Beispiel #1
0
 public void Resolve(TableFilter filter)
 {
     foreach (Expression ex in eArg)
     {
         if (!ex.IsResolved)
         {
             ex.Resolve(filter);
         }
     }
 }
Beispiel #2
0
        public void Resolve(TableFilter filter, bool ownfilter)
        {
            if (eCondition != null)
            {
                // first set the table filter in the condition
                eCondition.Resolve(filter);

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

            int len = eColumn.Length;

            for (int i = 0; i < len; i++)
            {
                eColumn[i].Resolve(filter);
            }
        }
Beispiel #3
0
        /// <summary>
        /// Resolve the current expression.
        /// </summary>
        /// <param name="filter"></param>
        public void Resolve(TableFilter filter)
        {
            if (filter != null && _type == ExpressionType.DatabaseColumn)
            {
                if (sTable == null || filter.Name.Equals(sTable))
                {
                    int i = filter.Table.SearchColumn(sColumn);

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

                        tFilter     = filter;
                        iColumn     = i;
                        sTable      = filter.Name;
                        _columnType = filter.Table.GetColumnType(i);
                    }
                }
            }

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

            if (eArg2 != null)
            {
                eArg2.Resolve(filter);
            }

            if (sSelect != null)
            {
                sSelect.Resolve(filter, false);
                sSelect.Resolve();
            }

            if (fFunction != null)
            {
                fFunction.Resolve(filter);
            }

            if (_columnType != ColumnType.Null)
            {
                return;
            }

            switch (_type)
            {
            case ExpressionType.Function:
                _columnType = fFunction.GetReturnType();
                break;

            case ExpressionType.Query:
                _columnType = sSelect.eColumn[0].ColumnType;
                break;

            case ExpressionType.Negate:
                _columnType = eArg.ColumnType;
                break;

            case ExpressionType.Add:
            case ExpressionType.Subtract:
            case ExpressionType.Multiply:
            case ExpressionType.Divide:
                _columnType = eArg._columnType;
                break;

            case ExpressionType.Concat:
                _columnType = ColumnType.VarChar;
                break;

            case ExpressionType.Not:
            case ExpressionType.BiggerEqual:
            case ExpressionType.Bigger:
            case ExpressionType.Smaller:
            case ExpressionType.SmallerEqual:
            case ExpressionType.NotEqual:
            case ExpressionType.Like:
            case ExpressionType.And:
            case ExpressionType.Or:
            case ExpressionType.In:
            case ExpressionType.Exists:
                _columnType = ColumnType.Bit;
                break;

            case ExpressionType.Equal:
                if (this.IsVarAssign)
                {
                    _columnType = eArg2.ColumnType;
                }
                else
                {
                    _columnType = ColumnType.Bit;
                }
                break;

            case ExpressionType.Count:
                _columnType = ColumnType.Integer;
                break;

            case ExpressionType.Maximum:
            case ExpressionType.Minimum:
            case ExpressionType.Sum:
            case ExpressionType.Average:
                _columnType = eArg.ColumnType;
                break;

            case ExpressionType.Convert:
                // it is already set
                break;

            case ExpressionType.IfNull:
            case ExpressionType.CaseWhen:
                _columnType = eArg2.ColumnType;
                break;

            case ExpressionType.Variable:
                _columnType = eArg.ColumnType;
                break;
            }
        }
Beispiel #4
0
 public void Resolve( TableFilter filter )
 {
     foreach( Expression ex in eArg )
     {
         if( !ex.IsResolved )
             ex.Resolve(filter);
     }
 }
Beispiel #5
0
        public void Resolve(TableFilter filter, bool ownfilter)
        {
            if (eCondition != null)
            {

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

                if (filter != null && ownfilter)
                {

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

            int len = eColumn.Length;

            for (int i = 0; i < len; i++)
            {
                eColumn[i].Resolve(filter);
            }
        }
Beispiel #6
0
        // [email protected] end changes from 1.50
        // [email protected] begin changes from 1.50
        public Result GetResult(int start, int cnt, Channel cChannel)
        {
            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.Type[i] = e.ColumnType;

                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;
            }

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

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

            while (level >= 0)
            {
                bool found = false;

                if (filter > 0)
                {
                    TableFilter t = tFilter[level];

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

                if (!found)
                {
                    level--;

                    if (!OnlyVars)
                    {
                        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();

                        if (cChannel != null && eColumn[i].IsVarAssign)
                        {
                            cChannel.SetDeclareValue(eColumn[i].Arg.ColumnName, row[i]);
                        }
                    }

                    count++;

                    if (aggregated && !grouped)
                    {
                        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.Root;
                Result x = new Result(len);

                for (int i = 0; i < len; i++)
                {
                    x.Type[i] = r.Type[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.Type[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 maybe is 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.Label[i] = e.Alias;
                r.Table[i] = e.TableName;
                r.Name[i]  = e.ColumnName;
            }

            if (sUnion != null)
            {
                Result x = sUnion.GetResult(0, cChannel);

                if (UnionType == SelectType.Union)
                {
                    r.Append(x);

                    r = RemoveDuplicates(r);
                }
                else if (UnionType == SelectType.UnionAll)
                {
                    r.Append(x);
                }
                else if (UnionType == SelectType.Intersect)
                {
                    r = RemoveDuplicates(r);
                    x = RemoveDuplicates(x);
                    r = RemoveDifferent(r, x);
                }
                else if (UnionType == SelectType.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 #7
0
        private Select ParseSelect()
        {
            Select select = new Select ();
            // [email protected] begin changes from 1.50
            select.limitStart = 0;
            select.limitCount = cChannel.MaxRows;
            // [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 = int.Parse (limStart);
                select.limitCount = int.Parse (limEnd);
                // [email protected] end changes from 1.50
            } else {
                tTokenizer.Back ();
            }

            // parse column list
            ArrayList vcolumn = new ArrayList ();
            select.OnlyVars = true;

            do {
                Expression e = ParseExpression ();

                token = tTokenizer.GetString ();

                if (token.Equals ("AS")) {
                    e.Alias = tTokenizer.GetName ();

                    token = tTokenizer.GetString ();
                } else if (tTokenizer.WasName) {
                    e.Alias = token;

                    token = tTokenizer.GetString ();
                }

                vcolumn.Add (e);

                select.OnlyVars = select.OnlyVars & (e.Type == ExpressionType.Variable);

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

            if (!select.OnlyVars) {
                if (token.Equals ("INTO")) {
                    select.sIntoTable = tTokenizer.GetString ();
                    token = tTokenizer.GetString ();
                }

                if (!token.Equals ("FROM")) {
                    throw TracingHelper.Error (TracingHelper.UnexpectedToken, 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 ();
                        }

                        TracingHelper.Check (token.Equals ("JOIN"), TracingHelper.UnexpectedToken,
                            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.Type == ExpressionType.Asterix) {
                        int current = i;
                        Table table = null;
                        string n = e.TableName;

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

                            e.Resolve (f);

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

                            table = f.Table;

                            int col = table.ColumnCount;

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

                                vcolumn.Insert (current++, ins);

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

                        TracingHelper.Check (table != null, TracingHelper.TABLE_NOT_FOUND, n);

                        // minus the asterix element
                        len--;

                        vcolumn.RemoveAt (current);
                    } else if (e.Type == ExpressionType.DatabaseColumn) {
                        if (e.TableName == 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.Type == ExpressionType.Value) {

                            // order by 1,2,3
                            if (e.ColumnType == ColumnType.Integer) {
                                int i = Convert.ToInt32 (e.GetValue ());

                                e = (Expression)vcolumn [i - 1];
                            }
                        } else if (e.Type == ExpressionType.DatabaseColumn
                                   && e.TableName == null) {

                            // this could be an alias column
                            string s = e.ColumnName;

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

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

                                    break;
                                }
                            }
                        }

                        token = tTokenizer.GetString ();

                        if (token.Equals ("DESC")) {
                            e.IsDescending = true;

                            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.UnionType = SelectType.UnionAll;
                    } else {
                        select.UnionType = SelectType.Union;

                        tTokenizer.Back ();
                    }

                    tTokenizer.GetThis ("SELECT");

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

                    select.UnionType = SelectType.Intersect;
                    select.sUnion = ParseSelect ();
                } else if (token.Equals ("EXCEPT") || token.Equals ("MINUS")) {
                    tTokenizer.GetThis ("SELECT");

                    select.UnionType = SelectType.Except;
                    select.sUnion = ParseSelect ();
                } else {
                    tTokenizer.Back ();
                }
            } else {
                select.tFilter = new TableFilter[]{ };

                int len = vcolumn.Count;
                select.iResultLen = len;
                select.eColumn = new Expression[len];
                vcolumn.CopyTo (select.eColumn);
            }

            return select;
        }
Beispiel #8
0
        public Result ProcessUpdate()
        {
            string token = tTokenizer.GetString ();

            cChannel.CheckReadWrite ();
            cChannel.Check (token, AccessType.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.GetColumnNumber (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];
            ColumnType[] type = new ColumnType[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.ColumnCount;

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

                        del.Add (nd);

                        object[] ni = table.NewRow;

                        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 ());

                lock (cChannel.SyncRoot) {

                    cChannel.BeginNestedTransaction ();

                    try {
                        Record nd = del.Root;

                        while (nd != null) {
                            table.DeleteNoCheck (nd.Data, cChannel);

                            nd = nd.Next;
                        }

                        Record ni = ins.Root;

                        while (ni != null) {
                            table.InsertNoCheck (ni.Data, cChannel);

                            ni = ni.Next;
                            count++;
                        }

                        table.CheckUpdate (col, del, ins);

                        ni = ins.Root;

                        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.SetUpdateCount (count);

            return r;
        }
Beispiel #9
0
        public Result ProcessDelete()
        {
            tTokenizer.GetThis ("FROM");

            string token = tTokenizer.GetString ();

            cChannel.CheckReadWrite ();
            cChannel.Check (token, AccessType.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.Root;

                while (n != null) {
                    table.Delete (n.Data, cChannel);

                    count++;
                    n = n.Next;
                }
            }

            Result r = new Result ();

            r.SetUpdateCount (count);

            return r;
        }
Beispiel #10
0
        /// <summary>
        /// Resolve the current expression.
        /// </summary>
        /// <param name="filter"></param>
        public void Resolve(TableFilter filter)
        {
            if (filter != null && _type == ExpressionType.DatabaseColumn)
            {
                if (sTable == null || filter.Name.Equals(sTable))
                {
                    int i = filter.Table.SearchColumn(sColumn);

                    if (i != -1)
                    {

                        // todo: other error message: multiple tables are possible
                        TracingHelper.Check(tFilter == null || tFilter == filter,
                            TracingHelper.COLUMN_NOT_FOUND, sColumn);

                        tFilter = filter;
                        iColumn = i;
                        sTable = filter.Name;
                        _columnType = filter.Table.GetColumnType(i);
                    }
                }
            }

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

            if (eArg2 != null)
            {
                eArg2.Resolve(filter);
            }

            if (sSelect != null)
            {
                sSelect.Resolve(filter, false);
                sSelect.Resolve();
            }

            if (fFunction != null)
            {
                fFunction.Resolve(filter);
            }

            if (_columnType != ColumnType.Null)
            {
                return;
            }

            switch (_type)
            {
                case ExpressionType.Function:
                    _columnType = fFunction.GetReturnType();
                    break;

                case ExpressionType.Query:
                    _columnType = sSelect.eColumn[0].ColumnType;
                    break;

                case ExpressionType.Negate:
                    _columnType = eArg.ColumnType;
                    break;

                case ExpressionType.Add:
                case ExpressionType.Subtract:
                case ExpressionType.Multiply:
                case ExpressionType.Divide:
                    _columnType = eArg._columnType;
                    break;

                case ExpressionType.Concat:
                    _columnType = ColumnType.VarChar;
                    break;

                case ExpressionType.Not:
                case ExpressionType.BiggerEqual:
                case ExpressionType.Bigger:
                case ExpressionType.Smaller:
                case ExpressionType.SmallerEqual:
                case ExpressionType.NotEqual:
                case ExpressionType.Like:
                case ExpressionType.And:
                case ExpressionType.Or:
                case ExpressionType.In:
                case ExpressionType.Exists:
                    _columnType = ColumnType.Bit;
                    break;

                case ExpressionType.Equal:
                    if( this.IsVarAssign )
                    {
                        _columnType = eArg2.ColumnType;
                    }
                    else
                    {
                        _columnType = ColumnType.Bit;
                    }
                    break;

                case ExpressionType.Count:
                    _columnType = ColumnType.Integer;
                    break;

                case ExpressionType.Maximum:
                case ExpressionType.Minimum:
                case ExpressionType.Sum:
                case ExpressionType.Average:
                    _columnType = eArg.ColumnType;
                    break;

                case ExpressionType.Convert:
                    // it is already set
                    break;

                case ExpressionType.IfNull:
                case ExpressionType.CaseWhen:
                    _columnType = eArg2.ColumnType;
                    break;
                case ExpressionType.Variable:
                    _columnType = eArg.ColumnType;
                    break;
            }
        }