Ejemplo n.º 1
0
        private static Row CursorFetch(FetchCursorStatement fetch, Cursor cursor, Scope scope)
        {
            var orientation = fetch.FetchType?.Orientation ?? FetchOrientation.None;

            switch (orientation)
            {
            case FetchOrientation.None:
            case FetchOrientation.Next:
                return(cursor.MoveNext());

            case FetchOrientation.Prior:
                return(cursor.MovePrior());

            case FetchOrientation.First:
                return(cursor.MoveFirst());

            case FetchOrientation.Last:
                return(cursor.MoveLast());

            case FetchOrientation.Absolute:
                return(cursor.MoveAbsolute(Evaluate <int>(fetch.FetchType?.RowOffset, NullArgument.It, scope)));

            case FetchOrientation.Relative:
                return(cursor.MoveRelative(Evaluate <int>(fetch.FetchType?.RowOffset, NullArgument.It, scope)));

            default:
                throw FeatureNotSupportedException.Value(orientation);
            }
        }
Ejemplo n.º 2
0
        public static void Evaluate(ProcedureStatementBodyBase exec, Scope scope)
        {
            switch (exec)
            {
            case AlterFunctionStatement alterFunc:
                scope.Env.GetSchema(alterFunc.Name).Functions.Set(
                    alterFunc.Name.BaseIdentifier.Value,
                    BuildFunc(alterFunc));
                return;

            case AlterProcedureStatement alterProc:
                scope.Env.GetSchema(alterProc.ProcedureReference.Name).Procedures.Set(
                    alterProc.ProcedureReference.Name.BaseIdentifier.Value,
                    BuildProc(alterProc));
                return;

            case CreateFunctionStatement createFunc:
                scope.Env.GetSchema(createFunc.Name).Functions.Declare(
                    createFunc.Name.BaseIdentifier.Value,
                    BuildFunc(createFunc));
                return;

            case CreateProcedureStatement createProc:
                scope.Env.GetSchema(createProc.ProcedureReference.Name).Procedures.Declare(
                    createProc.ProcedureReference.Name.BaseIdentifier.Value,
                    BuildProc(createProc));
                return;

            default:
                throw FeatureNotSupportedException.Subtype(exec);
            }
        }
        // TODO: use switch expression, expression bodied member
        public static bool Evaluate(BooleanComparisonType op, object left, object right)
        {
            switch (op)
            {
            case BooleanComparisonType.Equals:
                return(left != null && left.Equals(right));

            case BooleanComparisonType.NotEqualToBrackets:
            case BooleanComparisonType.NotEqualToExclamation:
                return(left == null || !left.Equals(right));

            case BooleanComparisonType.GreaterThan:
                // TODO: handle numeric conversions properly
                if (left is int i && right is int j)
                {
                    return(i > j);
                }
                if (left is decimal m && right is decimal n)
                {
                    return(m > n);
                }
                return(string.Compare(left.ToString(), right.ToString()) > 0);

            case BooleanComparisonType.GreaterThanOrEqualTo:
                if (left is int i2 && right is int j2)
                {
                    return(i2 >= j2);
                }
                if (left is decimal m2 && right is decimal n2)
                {
                    return(m2 >= n2);
                }
                return(string.Compare(left.ToString(), right.ToString()) >= 0);

            case BooleanComparisonType.LessThan:
                if (left is int i3 && right is int j3)
                {
                    return(i3 < j3);
                }
                if (left is decimal m3 && right is decimal n3)
                {
                    return(m3 < n3);
                }
                return(string.Compare(left.ToString(), right.ToString()) < 0);

            case BooleanComparisonType.LessThanOrEqualTo:
                if (left is int i4 && right is int j4)
                {
                    return(i4 <= j4);
                }
                if (left is decimal m4 && right is decimal n4)
                {
                    return(m4 <= n4);
                }
                return(string.Compare(left.ToString(), right.ToString()) <= 0);

            default:
                throw FeatureNotSupportedException.Value(op);
            }
        }
Ejemplo n.º 4
0
        public static void Handle(FeatureNotSupportedException e)
        {
            RavenService.Raven.Capture(new SentryEvent(e));
            DialogService.ShowAlert(CodeNull, AlertType.Error);

            #if DEBUG
            DialogService.ShowAlert(e.ToString(), AlertType.Error);
            #endif
        }
Ejemplo n.º 5
0
        public static EngineResult Evaluate(InsertSpecification insert, IOutputSink sink, Scope scope)
        {
            var table = scope.Env.GetTable((NamedTableReference)insert.Target);

            return(insert.InsertSource switch
            {
                ValuesInsertSource values => Evaluate(table, insert.Columns, values, NullArgument.It, sink, scope),
                SelectInsertSource select => Evaluate(table, insert.Columns, Evaluate(@select.Select, scope).ResultSet,
                                                      sink, scope),
                _ => throw FeatureNotSupportedException.Subtype(insert.InsertSource)
            });
Ejemplo n.º 6
0
        public static object Evaluate(FunctionCall funCall, IArgument arg, Scope scope)
        {
            switch (arg)
            {
            case GroupArgument group:
                return(GroupedFunctionCall(funCall, group, scope));

            case NullArgument _:
            case RowArgument _:
                return(UngroupedFunctionCall(funCall, arg, scope));

            default:
                throw FeatureNotSupportedException.Subtype(arg);
            }
        }
Ejemplo n.º 7
0
        public static EngineResult Evaluate(DataModificationSpecification dml, Scope scope)
        {
            IOutputSink sink;

            // TODO: support scalar expressions in TableOutputSink, not just column names
            //       how to handle INSERTED. and DELETED. aliases?

            if (dml.OutputClause != null || dml.OutputIntoClause != null)
            {
                sink = new TableOutputSink(
                    (dml.OutputClause?.SelectColumns ?? dml.OutputIntoClause?.SelectColumns)?
                    .Select(s => new Column
                {
                    Name = ((ColumnReferenceExpression)((SelectScalarExpression)s).Expression)
                           .MultiPartIdentifier.Identifiers.Select(x => x.Value).ToArray(),
                    Type = DbType.AnsiString
                }).ToList());
            }
            else
            {
                sink = new NullOutputSink();
            }

            var result = dml switch
            {
                InsertSpecification insert => Evaluate(insert, sink, scope),
                MergeSpecification merge => Evaluate(merge, sink, scope),
                DeleteSpecification delete => Evaluate(delete, sink, scope),
                UpdateSpecification update => Evaluate(update, sink, scope),
                _ => throw FeatureNotSupportedException.Subtype(dml)
            };

            if (dml.OutputIntoClause != null)
            {
                var(table, scope2) = Evaluate(dml.OutputIntoClause.IntoTable, null, scope);
                Evaluate(
                    table,
                    dml.OutputIntoClause.IntoTableColumns,
                    ((TableOutputSink)sink).Output,
                    new NullOutputSink(),
                    scope2);
            }

            return(dml.OutputClause != null
                ? new EngineResult(((TableOutputSink)sink).Output)
                : result);
        }
    }
Ejemplo n.º 8
0
        public static EngineResult Evaluate(StatementWithCtesAndXmlNamespaces statement, Scope scope)
        {
            if (statement.WithCtesAndXmlNamespaces?.CommonTableExpressions != null)
            {
                scope = Evaluate(statement.WithCtesAndXmlNamespaces.CommonTableExpressions, scope);
            }

            return(statement switch
            {
                SelectStatement select => Evaluate(select, scope),
                InsertStatement insert => Evaluate(insert.InsertSpecification, scope),
                UpdateStatement update => Evaluate(update.UpdateSpecification, scope),
                DeleteStatement delete => Evaluate(delete.DeleteSpecification, scope),
                MergeStatement merge => Evaluate(merge.MergeSpecification, scope),
                _ => throw FeatureNotSupportedException.Subtype(statement)
            });
Ejemplo n.º 9
0
        public static (Table, Scope) Evaluate(TableReference tableRef, Table joinedTables, Scope scope)
        {
            switch (tableRef)
            {
            case NamedTableReference named:
                var baseName = named.SchemaObject.BaseIdentifier.Value;
                var schema   = scope.Env.GetSchema(named.SchemaObject);
                return(
                    schema.Views.GetMaybe(baseName)
                    .Select(v => Evaluate(v.Query, scope).ResultSet)
                    .Or(() => scope.Ctes.GetMaybe(baseName))
                    .OrElse(() => schema.Tables[baseName]),
                    named.Alias == null
                            ? scope
                            : scope.PushAlias(
                        named.Alias.Value,
                        scope.ExpandTableName(named.SchemaObject.Identifiers.Select(x => x.Value).ToArray())));

            case DataModificationTableReference dml:
                // TODO: how does this work?
                return(Evaluate(dml.DataModificationSpecification, scope).ResultSet, scope);

            case JoinParenthesisTableReference paren:
                return(Evaluate(paren.Join, joinedTables, scope));

            case OdbcQualifiedJoinTableReference odbc:
                return(Evaluate(odbc.TableReference, joinedTables, scope));

            case QueryDerivedTable query:
                var table = Evaluate(query.QueryExpression, scope).ResultSet;
                table.Name = Guid.NewGuid().ToString().Replace("-", "");
                return(table, scope.PushAlias(query.Alias.Value, new[] { table.Name }));

            case QualifiedJoin qjoin:
                var(leftTable, leftScope)   = Evaluate(qjoin.FirstTableReference, joinedTables, scope);
                var(rightTable, rightScope) = Evaluate(qjoin.SecondTableReference, leftTable, leftScope);
                return(Join(leftTable, rightTable, qjoin.SearchCondition, qjoin.QualifiedJoinType, rightScope));

            case UnqualifiedJoin ujoin:
                var(leftTable2, leftScope2)   = Evaluate(ujoin.FirstTableReference, joinedTables, scope);
                var(rightTable2, rightScope2) = Evaluate(ujoin.SecondTableReference, leftTable2, leftScope2);
                return(Join(leftTable2, rightTable2, ujoin.UnqualifiedJoinType, rightScope2));

            default:
                throw FeatureNotSupportedException.Subtype(tableRef);
            }
        }
Ejemplo n.º 10
0
        public static object Evaluate(AssignmentKind kind, object current, object value)
        {
            // TODO: use switch expression, expression bodied member
            switch (kind)
            {
            case AssignmentKind.Equals:
                return(value);

            case AssignmentKind.AddEquals:
                // TODO: handle numeric conversions properly
                // TODO: and how do nulls work?
                if (current == null || value == null)
                {
                    return(current ?? value);
                }
                if (current is int i && value is int j)
                {
                    return(i + j);
                }
                return((decimal)current + (decimal)value);

            case AssignmentKind.SubtractEquals:
                return((decimal)current - (decimal)value);

            case AssignmentKind.MultiplyEquals:
                return((decimal)current * (decimal)value);

            case AssignmentKind.DivideEquals:
                return((decimal)current / (decimal)value);

            case AssignmentKind.ModEquals:
                return((decimal)current % (decimal)value);

            case AssignmentKind.BitwiseAndEquals:
                return((int)current & (int)value);

            case AssignmentKind.BitwiseOrEquals:
                return((int)current | (int)value);

            case AssignmentKind.BitwiseXorEquals:
                return((int)current ^ (int)value);

            default:
                throw FeatureNotSupportedException.Value(kind);
            }
        }
Ejemplo n.º 11
0
        private static WhenClause MatchingClause(CaseExpression expr, IArgument arg, Scope scope)
        {
            switch (expr)
            {
            case SimpleCaseExpression simple:
                var input = Evaluate(simple.InputExpression, arg, scope);
                return(simple.WhenClauses
                       .FirstOrDefault(x => Equality.Equal(input, Evaluate(x.WhenExpression, arg, scope))));

            case SearchedCaseExpression searched:
                return(searched.WhenClauses
                       .FirstOrDefault(x => Evaluate(x.WhenExpression, arg, scope)));

            default:
                throw FeatureNotSupportedException.Subtype(expr);
            }
        }
Ejemplo n.º 12
0
        public static bool Evaluate(BooleanExpression expr, IArgument arg, Scope scope)
        {
            switch (expr)
            {
            case BooleanParenthesisExpression paren:
                return(Evaluate(paren.Expression, arg, scope));

            case BooleanBinaryExpression binaryExpr:
                return(Evaluate(
                           binaryExpr.BinaryExpressionType,
                           Evaluate(binaryExpr.FirstExpression, arg, scope),
                           Evaluate(binaryExpr.SecondExpression, arg, scope)));

            case BooleanTernaryExpression ternaryExpr:
                return(Evaluate(
                           ternaryExpr.TernaryExpressionType,
                           Evaluate(ternaryExpr.FirstExpression, arg, scope),
                           Evaluate(ternaryExpr.SecondExpression, arg, scope),
                           Evaluate(ternaryExpr.ThirdExpression, arg, scope)));

            case BooleanComparisonExpression compareExpr:
                return(Evaluate(
                           compareExpr.ComparisonType,
                           Evaluate(compareExpr.FirstExpression, arg, scope),
                           Evaluate(compareExpr.SecondExpression, arg, scope)));

            case BooleanNotExpression notExpr:
                return(!Evaluate(notExpr.Expression, arg, scope));

            case BooleanIsNullExpression isNullExpr:
                return(Evaluate(isNullExpr.Expression, arg, scope) == null);

            case InPredicate inExpr:
                var value = Evaluate(inExpr.Expression, arg, scope);
                return(value != null && inExpr.Values.Any(x => value.Equals(Evaluate(x, arg, scope))));

            case ExistsPredicate existsExpr:
                return(Evaluate(existsExpr.Subquery.QueryExpression, scope).ResultSet.Rows.Count > 0);

            default:
                throw FeatureNotSupportedException.Subtype(expr);
            }
        }
        public static object Evaluate(BinaryExpressionType op, object left, object right)
        {
            // TODO: use switch expression, expression bodied member
            switch (op)
            {
            case BinaryExpressionType.Add:
                // TODO: handle numeric conversions properly
                if (left is string s && right is string t)
                {
                    return(s + t);
                }
                if (left is int i && right is int j)
                {
                    return(i + j);
                }
                return((int)left + (int)right);

            case BinaryExpressionType.Subtract:
                return((int)left - (int)right);

            case BinaryExpressionType.Multiply:
                return((int)left * (int)right);

            case BinaryExpressionType.Divide:
                return((int)left / (int)right);

            case BinaryExpressionType.Modulo:
                return((int)left % (int)right);

            case BinaryExpressionType.BitwiseAnd:
                return((int)left & (int)right);

            case BinaryExpressionType.BitwiseOr:
                return((int)left & (int)right);

            case BinaryExpressionType.BitwiseXor:
                return((int)left ^ (int)right);

            default:
                throw FeatureNotSupportedException.Value(op);
            }
        }
Ejemplo n.º 14
0
        public static void Evaluate(CursorStatement statement, Scope scope)
        {
            // TODO: global cursors? statement.Cursor.IsGlobal
            var name   = statement.Cursor.Name.Value;
            var cursor = (Cursor)scope.Env.Vars[name];

            switch (statement)
            {
            case OpenCursorStatement _:
                cursor.Open(scope);
                return;

            case CloseCursorStatement _:
                cursor.Close();
                return;

            case DeallocateCursorStatement _:
                cursor.Deallocate();
                return;

            case FetchCursorStatement fetch:
                var result = CursorFetch(fetch, cursor, scope);
                scope.Env.FetchStatus = result == null ? 1 : 0;
                if (result == null)
                {
                    return;
                }

                foreach (var(v, x) in fetch.IntoVariables.Zip(result.Values, (v, x) => (v, x)))
                {
                    scope.Env.Vars.DeclareOrSet(v.Name, x);
                }

                return;

            default:
                throw FeatureNotSupportedException.Subtype(statement);
            }
        }
Ejemplo n.º 15
0
        public static void Evaluate(IList <SetClause> clauses, Row targetRow, Row sourceRow, IOutputSink sink, Scope scope)
        {
            var originalTargetRow = targetRow.Copy();

            foreach (var clause in clauses)
            {
                switch (clause)
                {
                case AssignmentSetClause set:
                    var columnName = set.Column.MultiPartIdentifier.Identifiers.Last().Value;
                    targetRow.Values[targetRow.GetColumnOrdinal(columnName)] = Evaluate(
                        set.AssignmentKind,
                        sourceRow.Values[sourceRow.GetColumnOrdinal(columnName)],
                        Evaluate(set.NewValue, new RowArgument(sourceRow), scope));
                    break;

                default:
                    throw FeatureNotSupportedException.Subtype(clause);
                }
            }

            sink.Updated(originalTargetRow, targetRow, scope.Env);
        }
        public static void Evaluate(DropObjectsStatement drop, Scope scope)
        {
            switch (drop)
            {
            case DropFunctionStatement _:
                DropAll(drop, scope.Env.Functions);
                return;

            case DropProcedureStatement _:
                DropAll(drop, scope.Env.Procedures);
                return;

            case DropTableStatement _:
                DropAll(drop, scope.Env.Tables);
                return;

            case DropViewStatement _:
                DropAll(drop, scope.Env.Views);
                return;

            default:
                throw FeatureNotSupportedException.Subtype(drop);
            }
        }
Ejemplo n.º 17
0
        private static object GroupedFunctionCall(FunctionCall funCall, GroupArgument group, Scope scope)
        {
            var name       = funCall.FunctionName.Value;
            var paramCount = funCall.Parameters.Count;
            var rows       = group.Rows.Select(x => new RowArgument(x));

            switch (name.ToLower())
            {
            case "sum" when paramCount == 1:
                var expr0 = funCall.Parameters[0];
                return(rows.Sum(x => Evaluate <int>(expr0, x, scope)));

            case "avg" when paramCount == 1:
                var expr1 = funCall.Parameters[0];
                return(rows.Average(x => Evaluate <int>(expr1, x, scope)));

            case "min" when paramCount == 1:
                var expr2 = funCall.Parameters[0];
                return(rows.Min(x => Evaluate <int>(expr2, x, scope)));

            case "max" when paramCount == 1:
                var expr3 = funCall.Parameters[0];
                return(rows.Max(x => Evaluate <int>(expr3, x, scope)));

            case "count" when paramCount == 1:
                var expr4 = funCall.Parameters[0];
                return(rows.Count(x => Evaluate(expr4, x, scope) != null));

            case "count_big" when paramCount == 1:
                var expr5 = funCall.Parameters[0];
                return(rows.LongCount(x => Evaluate(expr5, x, scope) != null));

            default:
                throw FeatureNotSupportedException.Value(funCall);
            }
        }
Ejemplo n.º 18
0
        public static void Evaluate(MergeAction action, Table targetTable, Row row, IOutputSink sink, Scope scope)
        {
            Row GetTargetRow() => row.Sources[EquatableArray.Of(scope.ExpandTableName(new[] { targetTable.Name }))];

            switch (action)
            {
            case InsertMergeAction insert:
                Evaluate(targetTable, insert.Columns, insert.Source, new RowArgument(row), sink, scope);
                return;

            case UpdateMergeAction update:
                Evaluate(update.SetClauses, GetTargetRow(), row, sink, scope);
                return;

            case DeleteMergeAction _:
                var r = GetTargetRow();
                sink.Deleted(r, scope.Env);
                targetTable.Rows.Remove(r);
                return;

            default:
                throw FeatureNotSupportedException.Subtype(action);
            }
        }
Ejemplo n.º 19
0
        private void parseMessage(IceInternal.BasicStream stream, ref MessageInfo info)
        {
            Debug.Assert(_state > StateNotValidated && _state < StateClosed);

            info.stream = stream;
            _readStream.swap(info.stream);
            _readStream.resize(IceInternal.Protocol.headerSize, true);
            _readStream.pos(0);
            _readHeader = true;

            try
            {
                //
                // The magic and version fields have already been checked.
                //
                Debug.Assert(info.stream.pos() == info.stream.size());
                info.stream.pos(8);
                byte messageType = info.stream.readByte();
                info.compress = info.stream.readByte();
                if(info.compress == (byte)2)
                {
                    if(_compressionSupported)
                    {
                        info.stream = info.stream.uncompress(IceInternal.Protocol.headerSize);
                    }
                    else
                    {
                        FeatureNotSupportedException ex = new FeatureNotSupportedException();
                        ex.unsupportedFeature = "Cannot uncompress compressed message: bzip2 DLL not found";
                        throw ex;
                    }
                }
                info.stream.pos(IceInternal.Protocol.headerSize);

                switch(messageType)
                {
                    case IceInternal.Protocol.closeConnectionMsg:
                    {
                        IceInternal.TraceUtil.traceRecv(info.stream, _logger, _traceLevels);
                        if(_endpoint.datagram())
                        {
                            if(_warn)
                            {
                                _logger.warning("ignoring close connection message for datagram connection:\n" + _desc);
                            }
                        }
                        else
                        {
                            setState(StateClosed, new CloseConnectionException());
                        }
                        break;
                    }

                    case IceInternal.Protocol.requestMsg:
                    {
                        if(_state == StateClosing)
                        {
                            IceInternal.TraceUtil.trace("received request during closing\n" +
                                                        "(ignored by server, client will retry)", info.stream, _logger,
                                                        _traceLevels);
                        }
                        else
                        {
                            IceInternal.TraceUtil.traceRecv(info.stream, _logger, _traceLevels);
                            info.requestId = info.stream.readInt();
                            info.invokeNum = 1;
                            info.servantManager = _servantManager;
                            info.adapter = _adapter;
                            ++_dispatchCount;
                        }
                        break;
                    }

                    case IceInternal.Protocol.requestBatchMsg:
                    {
                        if(_state == StateClosing)
                        {
                            IceInternal.TraceUtil.trace("received batch request during closing\n" +
                                                        "(ignored by server, client will retry)", info.stream, _logger,
                                                        _traceLevels);
                        }
                        else
                        {
                            IceInternal.TraceUtil.traceRecv(info.stream, _logger, _traceLevels);
                            info.invokeNum = info.stream.readInt();
                            if(info.invokeNum < 0)
                            {
                                info.invokeNum = 0;
                                throw new UnmarshalOutOfBoundsException();
                            }
                            info.servantManager = _servantManager;
                            info.adapter = _adapter;
                            _dispatchCount += info.invokeNum;
                        }
                        break;
                    }

                    case IceInternal.Protocol.replyMsg:
                    {
                        IceInternal.TraceUtil.traceRecv(info.stream, _logger, _traceLevels);
                        info.requestId = info.stream.readInt();
                        IceInternal.Outgoing og = null;
                        if(_requests.TryGetValue(info.requestId, out og))
                        {
                            _requests.Remove(info.requestId);
                            og.finished(info.stream);
                        }
                        else
                        {
                            if(!_asyncRequests.TryGetValue(info.requestId, out info.outAsync))
                            {
                                throw new UnknownRequestIdException();
                            }
                            _asyncRequests.Remove(info.requestId);
                        }
                        _m.NotifyAll(); // Notify threads blocked in close(false)
                        break;
                    }

                    case IceInternal.Protocol.validateConnectionMsg:
                    {
                        IceInternal.TraceUtil.traceRecv(info.stream, _logger, _traceLevels);
                        if(_warn)
                        {
                            _logger.warning("ignoring unexpected validate connection message:\n" + _desc);
                        }
                        break;
                    }

                    default:
                    {
                        IceInternal.TraceUtil.trace("received unknown message\n(invalid, closing connection)",
                                                    info.stream, _logger, _traceLevels);
                        throw new UnknownMessageException();
                    }
                }
            }
            catch(LocalException ex)
            {
                if(_endpoint.datagram())
                {
                    if(_warn)
                    {
                        _logger.warning("datagram connection exception:\n" + ex.ToString() + "\n" + _desc);
                    }
                }
                else
                {
                    setState(StateClosed, ex);
                }
            }
        }
        public static EngineResult Evaluate(BinaryQueryExpressionType type, bool all, Table left, Table right, Env env)
        {
            // TODO: does offset/fetch/top happen before or after?

            if (left.Columns.Count != right.Columns.Count)
            {
                throw new Exception("tables must have the same number of columns");
            }

            foreach (var i in Enumerable.Range(0, left.Columns.Count))
            {
                var a = left.Columns[i];
                var b = right.Columns[i];

                if (a.Name.Length > 0 && b.Name.Length > 0 && !a.Name.Last().Similar(b.Name.Last()))
                {
                    throw new Exception("columns must have the same names");
                }

                // TODO: identify lowest common type
                if (a.Type != b.Type)
                {
                    throw new Exception("types must match");
                }
            }

            var result = new Table {
                Columns = left.Columns
            };

            bool Contains(Table t, Row r) =>
            t.Rows.Any(s =>
                       Enumerable.Range(0, r.Columns.Count).All(i =>
                                                                Equality.Equal(r.Values[i], s.Values[i])));

            switch (type)
            {
            case BinaryQueryExpressionType.Except:
                foreach (var x in left.Rows)
                {
                    if (!Contains(right, x) && (all || !Contains(result, x)))
                    {
                        result.AddCopy(x, env);
                    }
                }

                break;

            case BinaryQueryExpressionType.Intersect:
                foreach (var x in left.Rows)
                {
                    if (Contains(right, x) && (all || !Contains(result, x)))
                    {
                        result.AddCopy(x, env);
                    }
                }

                if (all)
                {
                    foreach (var x in right.Rows)
                    {
                        if (Contains(left, x))
                        {
                            result.AddCopy(x, env);
                        }
                    }
                }

                break;

            case BinaryQueryExpressionType.Union:
                foreach (var x in left.Rows)
                {
                    if (all || !Contains(result, x))
                    {
                        result.AddCopy(x, env);
                    }
                }

                foreach (var x in right.Rows)
                {
                    if (all || !Contains(result, x))
                    {
                        result.AddCopy(x, env);
                    }
                }

                break;

            default:
                throw FeatureNotSupportedException.Value(type);
            }

            return(new EngineResult(result));
        }
Ejemplo n.º 21
0
        private int parseMessage(ref MessageInfo info)
        {
            Debug.Assert(_state > StateNotValidated && _state < StateClosed);

            info.stream = new IceInternal.BasicStream(_instance, Util.currentProtocolEncoding);
            _readStream.swap(info.stream);
            _readStream.resize(IceInternal.Protocol.headerSize, true);
            _readStream.pos(0);
            _readHeader = true;

            Debug.Assert(info.stream.pos() == info.stream.size());

            //
            // Connection is validated on first message. This is only used by
            // setState() to check wether or not we can print a connection
            // warning (a client might close the connection forcefully if the
            // connection isn't validated).
            //
            _validated = true;

            try
            {
                //
                // The magic and version fields have already been checked.
                //
                info.stream.pos(8);
                byte messageType = info.stream.readByte();
                info.compress = info.stream.readByte();
                if(info.compress == (byte)2)
                {
                    if(_compressionSupported)
                    {
                        info.stream = info.stream.uncompress(IceInternal.Protocol.headerSize, _messageSizeMax);
                    }
                    else
                    {
                        FeatureNotSupportedException ex = new FeatureNotSupportedException();
                        ex.unsupportedFeature = "Cannot uncompress compressed message: bzip2 DLL not found";
                        throw ex;
                    }
                }
                info.stream.pos(IceInternal.Protocol.headerSize);

                switch(messageType)
                {
                    case IceInternal.Protocol.closeConnectionMsg:
                    {
                        IceInternal.TraceUtil.traceRecv(info.stream, _logger, _traceLevels);
                        if(_endpoint.datagram())
                        {
                            if(_warn)
                            {
                                _logger.warning("ignoring close connection message for datagram connection:\n" + _desc);
                            }
                        }
                        else
                        {
                            setState(StateClosingPending, new CloseConnectionException());

                            //
                            // Notify the the transceiver of the graceful connection closure.
                            //
                            int op = _transceiver.closing(false, _exception);
                            if(op != 0)
                            {
                                return op;
                            }
                            setState(StateClosed);
                        }
                        break;
                    }

                    case IceInternal.Protocol.requestMsg:
                    {
                        if(_state >= StateClosing)
                        {
                            IceInternal.TraceUtil.trace("received request during closing\n" +
                                                        "(ignored by server, client will retry)", info.stream, _logger,
                                                        _traceLevels);
                        }
                        else
                        {
                            IceInternal.TraceUtil.traceRecv(info.stream, _logger, _traceLevels);
                            info.requestId = info.stream.readInt();
                            info.invokeNum = 1;
                            info.servantManager = _servantManager;
                            info.adapter = _adapter;
                            ++info.messageDispatchCount;
                        }
                        break;
                    }

                    case IceInternal.Protocol.requestBatchMsg:
                    {
                        if(_state >= StateClosing)
                        {
                            IceInternal.TraceUtil.trace("received batch request during closing\n" +
                                                        "(ignored by server, client will retry)", info.stream, _logger,
                                                        _traceLevels);
                        }
                        else
                        {
                            IceInternal.TraceUtil.traceRecv(info.stream, _logger, _traceLevels);
                            info.invokeNum = info.stream.readInt();
                            if(info.invokeNum < 0)
                            {
                                info.invokeNum = 0;
                                throw new UnmarshalOutOfBoundsException();
                            }
                            info.servantManager = _servantManager;
                            info.adapter = _adapter;
                            info.messageDispatchCount += info.invokeNum;
                        }
                        break;
                    }

                    case IceInternal.Protocol.replyMsg:
                    {
                        IceInternal.TraceUtil.traceRecv(info.stream, _logger, _traceLevels);
                        info.requestId = info.stream.readInt();
                        IceInternal.OutgoingAsyncBase outAsync = null;
                        if(_asyncRequests.TryGetValue(info.requestId, out outAsync))
                        {
                            _asyncRequests.Remove(info.requestId);

                            outAsync.getIs().swap(info.stream);

                            //
                            // If we just received the reply for a request which isn't acknowledge as
                            // sent yet, we queue the reply instead of processing it right away. It
                            // will be processed once the write callback is invoked for the message.
                            //
                            OutgoingMessage message = _sendStreams.Count > 0 ? _sendStreams.First.Value : null;
                            if(message != null && message.outAsync == outAsync)
                            {
                                message.receivedReply = true;
                            }
                            else
                            {
                                info.completedCallback = outAsync.completed();
                                if(info.completedCallback != null)
                                {
                                    info.outAsync = outAsync;
                                    ++info.messageDispatchCount;
                                }
                            }
                            System.Threading.Monitor.PulseAll(this); // Notify threads blocked in close(false)
                        }
                        break;
                    }

                    case IceInternal.Protocol.validateConnectionMsg:
                    {
                        IceInternal.TraceUtil.traceRecv(info.stream, _logger, _traceLevels);
                        if(_callback != null)
                        {
                            info.heartbeatCallback = _callback;
                            ++info.messageDispatchCount;
                        }
                        break;
                    }

                    default:
                    {
                        IceInternal.TraceUtil.trace("received unknown message\n(invalid, closing connection)",
                                                    info.stream, _logger, _traceLevels);
                        throw new UnknownMessageException();
                    }
                }
            }
            catch(LocalException ex)
            {
                if(_endpoint.datagram())
                {
                    if(_warn)
                    {
                        _logger.warning("datagram connection exception:\n" + ex.ToString() + "\n" + _desc);
                    }
                }
                else
                {
                    setState(StateClosed, ex);
                }
            }

            return _state == StateHolding ? IceInternal.SocketOperation.None : IceInternal.SocketOperation.Read;
        }
Ejemplo n.º 22
0
        public static EngineResult Evaluate(QueryExpression queryExpr, Scope scope)
        {
            var result = queryExpr switch
            {
                QuerySpecification querySpec => Evaluate(querySpec, scope),
                QueryParenthesisExpression paren => Evaluate(paren.QueryExpression, scope),
                BinaryQueryExpression binaryExpr => Evaluate(
                    binaryExpr.BinaryQueryExpressionType,
                    binaryExpr.All,
                    Evaluate(binaryExpr.FirstQueryExpression, scope).ResultSet,
                    Evaluate(binaryExpr.SecondQueryExpression, scope).ResultSet,
                    scope.Env),
                _ => throw FeatureNotSupportedException.Subtype(queryExpr)
            };

            if (result.ResultSet == null)
            {
                return(result);
            }

            var projection = result.ResultSet;

            // ORDER BY

            if (queryExpr.OrderByClause != null)
            {
                var elements     = queryExpr.OrderByClause.OrderByElements;
                var firstElement = elements.First();
                var restElements = elements.Skip(1);
                var temp         = projection.CopyLayout();

                foreach (var row in restElements.Aggregate(
                             Order(projection.Rows, firstElement, scope),
                             (orderedRows, element) => Order(orderedRows, element, scope)))
                {
                    CopyOnto(row, temp, scope.Env);
                }

                projection.Rows.Clear();
                CopyOnto(temp, projection, scope.Env);
            }

            // OFFSET

            if (queryExpr.OffsetClause != null)
            {
                var offset = Evaluate <int>(queryExpr.OffsetClause.OffsetExpression, NullArgument.It, scope);

                for (var i = 0; i < offset; ++i)
                {
                    projection.Rows.RemoveAt(0);
                }

                if (queryExpr.OffsetClause.FetchExpression != null)
                {
                    var fetch = Evaluate <int>(queryExpr.OffsetClause.FetchExpression, NullArgument.It, scope);

                    while (projection.Rows.Count > fetch)
                    {
                        projection.Rows.RemoveAt(projection.Rows.Count - 1);
                    }
                }
            }

            return(new EngineResult(projection));
        }
    }
Ejemplo n.º 23
0
        private void parseMessage(ref MessageInfo info)
        {
            Debug.Assert(_state > StateNotValidated && _state < StateClosed);

            info.stream = new IceInternal.BasicStream(_instance, Util.currentProtocolEncoding);
            _readStream.swap(info.stream);
            _readStream.resize(IceInternal.Protocol.headerSize, true);
            _readStream.pos(0);
            _readHeader = true;

            //
            // Connection is validated on first message. This is only used by
            // setState() to check wether or not we can print a connection
            // warning (a client might close the connection forcefully if the
            // connection isn't validated).
            //
            _validated = true;

            try
            {
                //
                // The magic and version fields have already been checked.
                //
                Debug.Assert(info.stream.pos() == info.stream.size());
                info.stream.pos(8);
                byte messageType = info.stream.readByte();
                info.compress = info.stream.readByte();
                if(info.compress == (byte)2)
                {
                    if(_compressionSupported)
                    {
                        info.stream = info.stream.uncompress(IceInternal.Protocol.headerSize);
                    }
                    else
                    {
                        FeatureNotSupportedException ex = new FeatureNotSupportedException();
                        ex.unsupportedFeature = "Cannot uncompress compressed message: bzip2 DLL not found";
                        throw ex;
                    }
                }
                info.stream.pos(IceInternal.Protocol.headerSize);

                switch(messageType)
                {
                    case IceInternal.Protocol.closeConnectionMsg:
                    {
                        IceInternal.TraceUtil.traceRecv(info.stream, _logger, _traceLevels);
                        if(_endpoint.datagram())
                        {
                            if(_warn)
                            {
                                _logger.warning("ignoring close connection message for datagram connection:\n" + _desc);
                            }
                        }
                        else
                        {
                            setState(StateClosed, new CloseConnectionException());
                        }
                        break;
                    }

                    case IceInternal.Protocol.requestMsg:
                    {
                        if(_state == StateClosing)
                        {
                            IceInternal.TraceUtil.trace("received request during closing\n" +
                                                        "(ignored by server, client will retry)", info.stream, _logger,
                                                        _traceLevels);
                        }
                        else
                        {
                            IceInternal.TraceUtil.traceRecv(info.stream, _logger, _traceLevels);
                            info.requestId = info.stream.readInt();
                            info.invokeNum = 1;
                            info.servantManager = _servantManager;
                            info.adapter = _adapter;
                            ++_dispatchCount;
                        }
                        break;
                    }

                    case IceInternal.Protocol.requestBatchMsg:
                    {
                        if(_state == StateClosing)
                        {
                            IceInternal.TraceUtil.trace("received batch request during closing\n" +
                                                        "(ignored by server, client will retry)", info.stream, _logger,
                                                        _traceLevels);
                        }
                        else
                        {
                            IceInternal.TraceUtil.traceRecv(info.stream, _logger, _traceLevels);
                            info.invokeNum = info.stream.readInt();
                            if(info.invokeNum < 0)
                            {
                                info.invokeNum = 0;
                                throw new UnmarshalOutOfBoundsException();
                            }
                            info.servantManager = _servantManager;
                            info.adapter = _adapter;
                            _dispatchCount += info.invokeNum;
                        }
                        break;
                    }

                    case IceInternal.Protocol.replyMsg:
                    {
                        IceInternal.TraceUtil.traceRecv(info.stream, _logger, _traceLevels);
                        info.requestId = info.stream.readInt();
                        IceInternal.Outgoing og = null;
                        if(_requests.TryGetValue(info.requestId, out og))
                        {
                            _requests.Remove(info.requestId);
                            og.finished(info.stream);
                        }
                        else
                        {
                            if(!_asyncRequests.TryGetValue(info.requestId, out info.outAsync))
                            {
                                throw new UnknownRequestIdException();
                            }
                            _asyncRequests.Remove(info.requestId);

                            info.outAsync.istr__.swap(info.stream);

                            //
                            // If we just received the reply for a request which isn't acknowledge as 
                            // sent yet, we queue the reply instead of processing it right away. It 
                            // will be processed once the write callback is invoked for the message.
                            //
                            OutgoingMessage message = _sendStreams.Count > 0 ? _sendStreams.Peek() : null;
                            if(message != null && message.outAsync == info.outAsync)
                            {
                                message.replyOutAsync = info.outAsync;
                                info.outAsync = null;
                            }
                        }
                        _m.NotifyAll(); // Notify threads blocked in close(false)
                        break;
                    }

                    case IceInternal.Protocol.validateConnectionMsg:
                    {
                        IceInternal.TraceUtil.traceRecv(info.stream, _logger, _traceLevels);
                        if(_warn)
                        {
                            _logger.warning("ignoring unexpected validate connection message:\n" + _desc);
                        }
                        break;
                    }

                    default:
                    {
                        IceInternal.TraceUtil.trace("received unknown message\n(invalid, closing connection)",
                                                    info.stream, _logger, _traceLevels);
                        throw new UnknownMessageException();
                    }
                }
            }
            catch(LocalException ex)
            {
                if(_endpoint.datagram())
                {
                    if(_warn)
                    {
                        _logger.warning("datagram connection exception:\n" + ex.ToString() + "\n" + _desc);
                    }
                }
                else
                {
                    setState(StateClosed, ex);
                }
            }
        }
Ejemplo n.º 24
0
        // TODO: refactor how built-in functions are implemented
        private static object UngroupedFunctionCall(FunctionCall funCall, IArgument arg, Scope scope)
        {
            var name       = funCall.FunctionName.Value;
            var paramCount = funCall.Parameters.Count;

            // TODO: how to handle `select count(*)` ?
            switch (name.ToLower())
            {
            case "error_number" when paramCount == 0:
                return(scope.Env.ErrorNumber);

            case "error_state" when paramCount == 0:
                return(scope.Env.ErrorState);

            case "error_message" when paramCount == 0:
                return(scope.Env.ErrorMessage);

            case "error_severity" when paramCount == 0:
                return(null);    // not properly implemented

            case "error_line" when paramCount == 0:
                return(null);    // not properly implemented

            case "error_procedure" when paramCount == 0:
                return(null);    // not properly implemented

            case "isnumeric" when paramCount == 1:
                var value = Evaluate(funCall.Parameters[0], arg, scope);
                return(value != null && NumericTypes.Contains(value.GetType()) ? 1 : 0);

            // TODO: not supported in version 8? see unit test
            case "isnull" when paramCount == 2:
                return(Evaluate <object>(funCall.Parameters[0], arg, scope)
                       ?? Evaluate <object>(funCall.Parameters[1], arg, scope));

            case "lower" when paramCount == 1:
                return(Evaluate <string>(funCall.Parameters[0], arg, scope)?.ToLower());

            case "upper" when paramCount == 1:
                return(Evaluate <string>(funCall.Parameters[0], arg, scope)?.ToUpper());

            case "trim" when paramCount == 1:
                return(Evaluate <string>(funCall.Parameters[0], arg, scope)?.Trim());

            case "ltrim" when paramCount == 1:
                return(Evaluate <string>(funCall.Parameters[0], arg, scope)?.TrimStart());

            case "rtrim" when paramCount == 1:
                return(Evaluate <string>(funCall.Parameters[0], arg, scope)?.TrimEnd());

            case "reverse" when paramCount == 1:
                var s5 = Evaluate <string>(funCall.Parameters[0], arg, scope);
                return(s5 == null ? null : new string(s5.Reverse().ToArray()));

            case "substring" when paramCount == 3:
                var s6 = Evaluate <string>(funCall.Parameters[0], arg, scope);
                var i6 = Evaluate <int>(funCall.Parameters[1], arg, scope);
                var j6 = Evaluate <int>(funCall.Parameters[2], arg, scope);
                return(s6?.Substring(i6, j6));

            case "dateadd":
                Func <DateTime, int, DateTime> dateAdd = null;
                switch (funCall.Parameters[0])
                {
                case ColumnReferenceExpression colExpr:
                    var dateUnit = colExpr.MultiPartIdentifier.Identifiers.LastOrDefault()?.Value?.ToLower();
                    // TODO: break this out into another function
                    switch (dateUnit)
                    {
                    case "year":
                    case "yy":
                    case "yyyy":
                        dateAdd = (d, x) => d.AddYears(x);
                        break;

                    case "quarter":
                    case "qq":
                    case "q":
                        dateAdd = (d, x) => d.AddMonths(x * 3);
                        break;

                    case "month":
                    case "mm":
                    case "m":
                        dateAdd = (d, x) => d.AddMonths(x);
                        break;

                    case "week":
                    case "wk":
                    case "ww":
                        dateAdd = (d, x) => d.AddDays(x * 7);
                        break;

                    case "dayofyear":
                    case "dy":
                    case "y":
                    case "weekday":
                    case "dw":
                    case "w":
                    case "day":
                    case "dd":
                    case "d":
                        dateAdd = (d, x) => d.AddDays(x);
                        break;

                    case "hour":
                    case "hh":
                        dateAdd = (d, x) => d.AddHours(x);
                        break;

                    case "minute":
                    case "mi":
                    case "n":
                        dateAdd = (d, x) => d.AddMinutes(x);
                        break;

                    case "second":
                    case "ss":
                    case "s":
                        dateAdd = (d, x) => d.AddSeconds(x);
                        break;

                    case "millisecond":
                    case "ms":
                        dateAdd = (d, x) => d.AddMilliseconds(x);
                        break;

                    default:
                        throw FeatureNotSupportedException.Value(dateUnit, "datepart");
                    }
                    break;
                }

                if (dateAdd == null)
                {
                    throw new Exception("invalid DATEADD() time increment argument");
                }
                var x1 = Evaluate <int>(funCall.Parameters[1], arg, scope);
                var d1 = Evaluate <DateTime>(funCall.Parameters[2], arg, scope);
                return(dateAdd(d1, x1));

            case "newid":
                return(Guid.NewGuid());

            default:
                var env2 = scope.Env.Fork();
                var f    = scope.Env.Functions[name];

                foreach (var(param, argExpr) in
                         f.Parameters.Zip(funCall.Parameters, (param, argExpr) => (param, argExpr)))
                {
                    env2.Vars.Declare(param.Key, Evaluate(argExpr, arg, scope));
                }

                Evaluate(f.Statements, new Scope(env2));
                return(env2.ReturnValue);
            }
        }