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