Beispiel #1
0
        /**
         * Method declaration
         *
         *
         * @param f
         * @param ownfilter
         *
         * @throws Exception
         */
        public void resolve(TableFilter f, bool ownfilter)
        {
            if (eCondition != null)
            {
                // first set the table filter in the condition
                eCondition.resolve(f);

                if (f != null && ownfilter)
                {
                    // the table filter tries to get as many conditions as possible
                    // but only if the table filter belongs to this query
                    f.setCondition(eCondition);
                }
            }

            int len = eColumn.Length;

            for (int i = 0; i < len; i++)
            {
                eColumn[i].resolve(f);
            }
        }
Beispiel #2
0
        /**
         * Method declaration
         *
         *
         * @param f
         *
         * @throws Exception
         */
        public void resolve(TableFilter f)
        {
            if (f != null && iType == COLUMN)
            {
                if (sTable == null || f.getName().Equals(sTable))
                {
                    int i = f.getTable().searchColumn(sColumn);

                    if (i != -1)
                    {
                        // todo: other error message: multiple tables are possible
                        Trace.check(tFilter == null || tFilter == f,
                                    Trace.COLUMN_NOT_FOUND, sColumn);

                        tFilter   = f;
                        iColumn   = i;
                        sTable    = f.getName();
                        iDataType = f.getTable().getColumnType(i);
                    }
                }
            }

            // currently sets only data type
            // todo: calculate fixed expressions if possible
            if (eArg != null)
            {
                eArg.resolve(f);
            }

            if (eArg2 != null)
            {
                eArg2.resolve(f);
            }

            if (sSelect != null)
            {
                sSelect.resolve(f, false);
                sSelect.resolve();
            }

            /*			if (fFunction != null)
             *                      {
             *                              fFunction.resolve(f);
             *                      }
             */
            if (iDataType != 0)
            {
                return;
            }

            switch (iType)
            {
            /*				case FUNCTION:
             *                                      iDataType = fFunction.getReturnType();
             *
             *                                      break;
             */
            case QUERY:
                iDataType = sSelect.eColumn[0].iDataType;

                break;

            case NEGATE:
                iDataType = eArg.iDataType;

                break;

            case ADD:

            case SUBTRACT:

            case MULTIPLY:

            case DIVIDE:
                iDataType = eArg.iDataType;

                break;

            case CONCAT:
                iDataType = Column.VARCHAR;

                break;

            case NOT:

            case EQUAL:

            case BIGGER_EQUAL:

            case BIGGER:

            case SMALLER:

            case SMALLER_EQUAL:

            case NOT_EQUAL:

            case LIKE:

            case AND:

            case OR:

            case IN:

            case EXISTS:
                iDataType = Column.BIT;

                break;

            case COUNT:
                iDataType = Column.INTEGER;

                break;

            case MAX:

            case MIN:

            case SUM:

            case AVG:
                iDataType = eArg.iDataType;

                break;

            case CONVERT:

                // it is already set
                break;

            case IFNULL:

            case CASEWHEN:
                iDataType = eArg2.iDataType;

                break;
            }
        }
Beispiel #3
0
        // [email protected] end changes from 1.50
        // [email protected] begin changes from 1.50
        public Result getResult(int start, int cnt)
        {
            int maxrows = start + cnt;          //<-new, cut definitly

            // [email protected] begin changes from 1.50
            resolve();
            checkResolved();

            if (sUnion != null && sUnion.iResultLen != iResultLen)
            {
                throw Trace.error(Trace.COLUMN_COUNT_DOES_NOT_MATCH);
            }

            int    len        = eColumn.Length;
            Result r          = new Result(len);
            bool   aggregated = false;
            bool   grouped    = false;

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

                r.iType[i] = e.getDataType();

                if (e.isAggregate())
                {
                    aggregated = true;
                }
            }

            object[] agg = null;

            if (aggregated)
            {
                agg = new object[len];
            }

            if (iGroupLen > 0)
            {                // has been set in Parser
                grouped = true;
            }

            bool simple_maxrows = false;

            if (maxrows != 0 && grouped == false && sUnion == null && iOrderLen == 0)
            {
                simple_maxrows = true;
            }
            else
            {
                simple_maxrows = false;
            }

            int count  = 0;
            int filter = tFilter.Length;

            bool[] first = new bool[filter];
            int    level = 0;

            while (level >= 0)
            {
                TableFilter t = tFilter[level];
                bool        found;

                if (!first[level])
                {
                    found        = t.findFirst();
                    first[level] = found;
                }
                else
                {
                    found        = t.next();
                    first[level] = found;
                }

                if (!found)
                {
                    level--;

                    continue;
                }

                if (level < filter - 1)
                {
                    level++;

                    continue;
                }

                if (eCondition == null || eCondition.test())
                {
                    object[] row = new object[len];

                    for (int i = 0; i < len; i++)
                    {
                        row[i] = eColumn[i].getValue();
                    }

                    count++;

                    if (aggregated)
                    {
                        updateAggregateRow(agg, row, len);
                    }
                    else
                    {
                        r.add(row);

                        if (simple_maxrows && count >= maxrows)
                        {
                            break;
                        }
                    }
                }
            }

            if (aggregated && !grouped)
            {
                addAggregateRow(r, agg, len, count);
            }
            else if (grouped)
            {
                int[] order = new int[iGroupLen];
                int[] way   = new int[iGroupLen];

                for (int i = iResultLen, j = 0; j < iGroupLen; i++, j++)
                {
                    order[j] = i;
                    way[j]   = 1;
                }

                r = sortResult(r, order, way);

                Record n = r.rRoot;
                Result x = new Result(len);

                for (int i = 0; i < len; i++)
                {
                    x.iType[i] = r.iType[i];
                }

                do
                {
                    object[] row = new object[len];

                    count = 0;

                    bool newgroup = false;

                    while (n != null && newgroup == false)
                    {
                        count++;

                        for (int i = 0; i < iGroupLen; i++)
                        {
                            if (n.next == null)
                            {
                                newgroup = true;
                            }
                            else if (Column.compare(n.data[i], n.next.data[i], r.iType[i])
                                     != 0)
                            {
                                // can't use .Equals because 'null' is also one group
                                newgroup = true;
                            }
                        }

                        updateAggregateRow(row, n.data, len);

                        n = n.next;
                    }

                    addAggregateRow(x, row, len, count);
                } while (n != null);

                r = x;
            }

            if (iOrderLen != 0)
            {
                int[] order = new int[iOrderLen];
                int[] way   = new int[iOrderLen];

                for (int i = iResultLen, j = 0; j < iOrderLen; i++, j++)
                {
                    order[j] = i;
                    way[j]   = eColumn[i].isDescending() ? -1 : 1;
                }

                r = sortResult(r, order, way);
            }

            // the result is maybe bigger (due to group and order by)
            // but don't tell this anybody else
            r.setColumnCount(iResultLen);

            if (bDistinct)
            {
                r = removeDuplicates(r);
            }

            for (int i = 0; i < iResultLen; i++)
            {
                Expression e = eColumn[i];

                r.sLabel[i] = e.getAlias();
                r.sTable[i] = e.getTableName();
                r.sName[i]  = e.getColumnName();
            }

            if (sUnion != null)
            {
                Result x = sUnion.getResult(0);

                if (iUnionType == UNION)
                {
                    r.append(x);

                    r = removeDuplicates(r);
                }
                else if (iUnionType == UNIONALL)
                {
                    r.append(x);
                }
                else if (iUnionType == INTERSECT)
                {
                    r = removeDuplicates(r);
                    x = removeDuplicates(x);
                    r = removeDifferent(r, x);
                }
                else if (iUnionType == EXCEPT)
                {
                    r = removeDuplicates(r);
                    x = removeDuplicates(x);
                    r = removeSecond(r, x);
                }
            }

            if (maxrows > 0 && !simple_maxrows)
            {
                trimResult(r, maxrows);
            }

            // [email protected] begin changes from 1.50
            if (start > 0)
            {                   //then cut the first 'start' elements
                trimResultFront(r, start);
            }
            // [email protected] end changes from 1.50

            return(r);
        }
Beispiel #4
0
        /**
         * Method declaration
         *
         *
         * @param f
         * @param ownfilter
         *
         * @throws Exception
         */
        public void resolve(TableFilter f, bool ownfilter)
        {
            if (eCondition != null)
            {

                // first set the table filter in the condition
                eCondition.resolve(f);

                if (f != null && ownfilter)
                {

                    // the table filter tries to get as many conditions as possible
                    // but only if the table filter belongs to this query
                    f.setCondition(eCondition);
                }
            }

            int len = eColumn.Length;

            for (int i = 0; i < len; i++)
            {
                eColumn[i].resolve(f);
            }
        }
Beispiel #5
0
        /**
         * Method declaration
         *
         *
         * @param f
         *
         * @throws Exception
         */
        public void resolve(TableFilter f)
        {
            if (f != null && iType == COLUMN)
            {
                if (sTable == null || f.getName().Equals(sTable))
                {
                    int i = f.getTable().searchColumn(sColumn);

                    if (i != -1)
                    {

                        // todo: other error message: multiple tables are possible
                        Trace.check(tFilter == null || tFilter == f,
                            Trace.COLUMN_NOT_FOUND, sColumn);

                        tFilter = f;
                        iColumn = i;
                        sTable = f.getName();
                        iDataType = f.getTable().getColumnType(i);
                    }
                }
            }

            // currently sets only data type
            // todo: calculate fixed expressions if possible
            if (eArg != null)
            {
                eArg.resolve(f);
            }

            if (eArg2 != null)
            {
                eArg2.resolve(f);
            }

            if (sSelect != null)
            {
                sSelect.resolve(f, false);
                sSelect.resolve();
            }

            /*			if (fFunction != null)
                        {
                            fFunction.resolve(f);
                        }
            */
            if (iDataType != 0)
            {
                return;
            }

            switch (iType)
            {

                    /*				case FUNCTION:
                                        iDataType = fFunction.getReturnType();

                                        break;
                    */
                case QUERY:
                    iDataType = sSelect.eColumn[0].iDataType;

                    break;

                case NEGATE:
                    iDataType = eArg.iDataType;

                    break;

                case ADD:

                case SUBTRACT:

                case MULTIPLY:

                case DIVIDE:
                    iDataType = eArg.iDataType;

                    break;

                case CONCAT:
                    iDataType = Column.VARCHAR;

                    break;

                case NOT:

                case EQUAL:

                case BIGGER_EQUAL:

                case BIGGER:

                case SMALLER:

                case SMALLER_EQUAL:

                case NOT_EQUAL:

                case LIKE:

                case AND:

                case OR:

                case IN:

                case EXISTS:
                    iDataType = Column.BIT;

                    break;

                case COUNT:
                    iDataType = Column.INTEGER;

                    break;

                case MAX:

                case MIN:

                case SUM:

                case AVG:
                    iDataType = eArg.iDataType;

                    break;

                case CONVERT:

                    // it is already set
                    break;

                case IFNULL:

                case CASEWHEN:
                    iDataType = eArg2.iDataType;

                    break;
            }
        }
Beispiel #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;
        }
Beispiel #7
0
        /**
         * Method declaration
         *
         *
         * @return
         *
         * @throws Exception
         */
        public Result processDelete()
        {
            tTokenizer.getThis("FROM");

            string token = tTokenizer.getstring();

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

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

            token = tTokenizer.getstring();

            Expression eCondition = null;

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

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

            int count = 0;

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

                do
                {
                    if (eCondition == null || eCondition.test())
                    {
                        del.add(filter.oCurrentData);
                    }
                } while (filter.next());

                Record n = del.rRoot;

                while (n != null)
                {
                    table.delete(n.data, cChannel);

                    count++;
                    n = n.next;
                }
            }

            Result r = new Result();

            r.iUpdateCount = count;

            return r;
        }
Beispiel #8
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;
        }