public override InvokeResult Execute(InvokeContext context) { using (var execContext = new ExecutionContext(context.Request, Body)) { Body.Execute(execContext); if (!execContext.HasResult) { throw new InvalidOperationException("The execution of the function has no returns"); } var result = execContext.Result; var returnType = ReturnType(context); if (returnType is TabularType) { return(context.Result(result)); } if (result.RowCount == 0) { throw new InvalidOperationException("The execution of the function has no returns"); } var retunValue = result.GetValue(0, 0); return(context.Result(retunValue)); } }
public override InvokeResult Execute(InvokeContext context) { if (context == null) { throw new ArgumentNullException("context"); } var group = context.GroupResolver; if (group == null) { throw new Exception(String.Format("'{0}' can only be used as an aggregate function.", FunctionName)); } DataObject result = null; // All aggregates functions return 'null' if group size is 0 int size = group.Count; if (size == 0) { // Return a NULL of the return type return(context.Result(DataObject.Null(ReturnType(context)))); } DataObject val; ObjectName v = context.Arguments[0].AsReferenceName(); // If the aggregate parameter is a simple variable, then use optimal // routine, if (v != null) { for (int i = 0; i < size; ++i) { val = group.Resolve(v, i); result = Evaluate(result, val, context.Request, group); } } else { // Otherwise we must resolve the expression for each entry in group, // This allows for expressions such as 'sum(quantity * price)' to // work for a group. var exp = context.Arguments[0]; for (int i = 0; i < size; ++i) { val = exp.EvaluateToConstant(context.Request, group.GetVariableResolver(i)); result = Evaluate(result, val, context.Request, group); } } // Post method. result = PostEvaluate(result, context.Request, group); return(context.Result(result)); }
private InvokeResult Simple(InvokeContext context, Func <DataObject[], DataObject> func) { var evaluated = context.EvaluatedArguments; var value = func(evaluated); return(context.Result(value)); }
private InvokeResult Simple(InvokeContext context, Func <Field[], Field> func) { var evaluated = context.EvaluatedArguments; var value = func(evaluated); return(context.Result(value)); }
private InvokeResult Binary(InvokeContext context, Func <DataObject, DataObject, DataObject> func) { var evaluated = context.EvaluatedArguments; var value = func(evaluated[0], evaluated[1]); return(context.Result(value)); }
public static InvokeResult Execute(InvokeContext context) { var value = context.EvaluatedArguments[0]; var typeArg = context.EvaluatedArguments[1]; var typeString = typeArg.AsVarChar().Value.ToString(); var type = SqlType.Parse(context.Request.Context, typeString); return(context.Result(SystemFunctions.Cast(value, type))); }
public override InvokeResult Execute(InvokeContext context) { if (context == null) throw new ArgumentNullException("context"); var group = context.GroupResolver; if (group == null) throw new Exception(String.Format("'{0}' can only be used as an aggregate function.", FunctionName)); DataObject result = null; // All aggregates functions return 'null' if group size is 0 int size = group.Count; if (size == 0) { // Return a NULL of the return type return context.Result(DataObject.Null(ReturnType(context))); } DataObject val; ObjectName v = context.Arguments[0].AsReferenceName(); // If the aggregate parameter is a simple variable, then use optimal // routine, if (v != null) { for (int i = 0; i < size; ++i) { val = group.Resolve(v, i); result = Evaluate(result, val, context.Request, group); } } else { // Otherwise we must resolve the expression for each entry in group, // This allows for expressions such as 'sum(quantity * price)' to // work for a group. var exp = context.Arguments[0]; for (int i = 0; i < size; ++i) { val = exp.EvaluateToConstant(context.Request, group.GetVariableResolver(i)); result = Evaluate(result, val, context.Request, group); } } // Post method. result = PostEvaluate(result, context.Request, group); return context.Result(result); }
public override InvokeResult Execute(InvokeContext context) { var args = context.EvaluatedArguments; var method = ExternalRef.GetMethod(); var methodArgs = ConvertArguments(method, context.Request, args); var result = method.Invoke(null, methodArgs); return(context.Result(ConvertValue(result, ReturnType()))); }
public override InvokeResult Execute(InvokeContext context) { var args = context.EvaluatedArguments; var method = ExternalRef.GetMethod(); var methodArgs = ConvertArguments(method, context.Request, args); var result = method.Invoke(null, methodArgs); return context.Result(ConvertValue(result, ReturnType())); }
public override InvokeResult Execute(InvokeContext context) { using (var execContext = new ExecutionContext(context.Request, Body)) { Body.Execute(execContext); if (!execContext.HasResult) throw new InvalidOperationException("The execution of the function has no returns"); var result = execContext.Result; var returnType = ReturnType(context); if (returnType is TabularType) return context.Result(result); if (result.RowCount == 0) throw new InvalidOperationException("The execution of the function has no returns"); var retunValue = result.GetValue(0, 0); return context.Result(retunValue); } }
public virtual InvokeResult Execute(InvokeContext context) { var args = context.Arguments; InvokeResult invokeResult = null; try { context.Request.Context.OnEvent(new RoutineEvent(Name, args, RoutineInfo.RoutineType)); var block = context.Request.CreateBlock(); PrepareBlock(context.Arguments, block); var result = ExecuteRoutine(block); if (RoutineInfo.RoutineType == RoutineType.Function) { invokeResult = context.Result(result); } else { invokeResult = context.Result(); } var output = CollectOutput(block); if (output.Count > 0) { foreach (var pair in output) { context.SetOutput(pair.Key, pair.Value); } } return(invokeResult); } catch (Exception) { throw; } finally { context.Request.Context.OnEvent(new RoutineEvent(Name, args, RoutineInfo.RoutineType, invokeResult)); } }
public override InvokeResult Execute(InvokeContext context) { if (method == null) method = DiscoverMethod(); if (method == null) throw new InvalidOperationException(); var args = context.EvaluatedArguments; try { var methodArgs = ConvertArguments(method, args); var result = method.Invoke(null, methodArgs); return context.Result(ConvertValue(result, ReturnType())); } catch (Exception) { throw; } }
public static InvokeResult Execute(InvokeContext context) { if (context.GroupResolver == null) { throw new Exception("'count' can only be used as an aggregate function."); } int size = context.GroupResolver.Count; Field result; // if, count(*) if (size == 0 || context.Invoke.IsGlobArgument) { result = Field.Integer(size); } else { // Otherwise we need to count the number of non-null entries in the // columns list(s) var arg1 = context.EvaluatedArguments[0]; var arg2 = context.EvaluatedArguments[1]; if (!Field.IsNullField(arg2)) { if (Field.IsNullField(arg1)) { result = Field.Integer(1); } else { result = arg1.Add(Field.Integer(1)); } } else { result = arg1; } } return(context.Result(result)); }
internal static InvokeResult Iif(InvokeContext context) { var result = DataObject.Null(); var evalContext = new EvaluateContext(context.Request, context.VariableResolver, context.GroupResolver); var condition = context.Arguments[0].EvaluateToConstant(evalContext); if (condition.Type is BooleanType) { if (condition.Equals(DataObject.BooleanTrue)) { result = context.Arguments[1].EvaluateToConstant(evalContext); } else if (condition.Equals(DataObject.BooleanFalse)) { result = context.Arguments[2].EvaluateToConstant(evalContext); } } return(context.Result(result)); }
public override InvokeResult Execute(InvokeContext context) { if (method == null) { method = DiscoverMethod(); } if (method == null) { throw new InvalidOperationException(); } var args = context.EvaluatedArguments; try { var methodArgs = ConvertArguments(method, args); var result = method.Invoke(null, methodArgs); return(context.Result(ConvertValue(result, ReturnType()))); } catch (Exception) { throw; } }
public static InvokeResult Execute(InvokeContext context) { if (context.GroupResolver == null) { throw new Exception("'count' can only be used as an aggregate function."); } int size = context.GroupResolver.Count; DataObject result; // if, count(*) if (size == 0 || context.Invoke.IsGlobArgument) { result = DataObject.Integer(size); } else { // Otherwise we need to count the number of non-null entries in the // columns list(s). int totalCount = size; var exp = context.Arguments[0]; for (int i = 0; i < size; ++i) { var val = exp.EvaluateToConstant(context.Request, context.GroupResolver.GetVariableResolver(i)); if (val.IsNull) { --totalCount; } } result = DataObject.Integer(totalCount); } return(context.Result(result)); }
private InvokeResult Simple(InvokeContext context, Func <Field> func) { var value = func(); return(context.Result(value)); }
internal static InvokeResult Iif(InvokeContext context) { var result = DataObject.Null(); var evalContext = new EvaluateContext(context.Request, context.VariableResolver, context.GroupResolver); var condition = context.Arguments[0].EvaluateToConstant(evalContext); if (condition.Type is BooleanType) { if (condition.Equals(DataObject.BooleanTrue)) { result = context.Arguments[1].EvaluateToConstant(evalContext); } else if (condition.Equals(DataObject.BooleanFalse)) { result = context.Arguments[2].EvaluateToConstant(evalContext); } } return context.Result(result); }
public virtual InvokeResult Execute(InvokeContext context) { var args = context.Arguments; InvokeResult invokeResult = null; try { context.Request.Context.OnEvent(new RoutineEvent(Name, args, RoutineInfo.RoutineType)); var block = context.Request.CreateBlock(); PrepareBlock(context.Arguments, block); var result = ExecuteRoutine(block); if (RoutineInfo.RoutineType == RoutineType.Function) { invokeResult = context.Result(result); } else { invokeResult = context.Result(); } var output = CollectOutput(block); if (output.Count > 0) { foreach (var pair in output) { context.SetOutput(pair.Key, pair.Value); } } return invokeResult; } catch (Exception) { throw; } finally { context.Request.Context.OnEvent(new RoutineEvent(Name, args, RoutineInfo.RoutineType, invokeResult)); } }
public override InvokeResult Execute(InvokeContext context) { if (FunctionInfo.FunctionType != FunctionType.Aggregate) { return(functionBody(context)); } if (context.GroupResolver == null) { throw new Exception(String.Format("Function '{0}' can only be used as an aggregate.", FunctionInfo.RoutineName)); } Field result = null; // All aggregates functions return 'null' if group size is 0 int size = context.GroupResolver.Count; if (size == 0) { // Return a NULL of the return type return(context.Result(Field.Null(ReturnType(context)))); } Field val; SqlReferenceExpression v = context.Arguments[0].Value as SqlReferenceExpression; // If the aggregate parameter is a simple variable, then use optimal // routine, if (v != null) { for (int i = 0; i < size; ++i) { var variable = context.GroupResolver.Resolve(v.ReferenceName, i); val = variable.Evaluate(context.Request); var invokeResult = functionBody(context.New(new SqlExpression[] { SqlExpression.Constant(result), SqlExpression.Constant(val) })); result = invokeResult.ReturnValue; } } else { // Otherwise we must resolve the expression for each entry in group, // This allows for expressions such as 'sum(quantity * price)' to // work for a group. var exp = context.Arguments[0]; for (int i = 0; i < size; ++i) { var evaluated = exp.Value.Evaluate(context.Request, context.GroupResolver.GetVariableResolver(i)); if (evaluated.ExpressionType != SqlExpressionType.Constant) { throw new InvalidOperationException( String.Format("The evaluation of the group {0} in aggregate function '{1}' is not constant", i, FunctionInfo.RoutineName)); } val = ((SqlConstantExpression)evaluated).Value; var invokeResult = functionBody(context.New(new SqlExpression[] { SqlExpression.Constant(result), SqlExpression.Constant(val) })); result = invokeResult.ReturnValue; } } // Post method. if (afterAggregate != null) { result = afterAggregate(context, result); } return(context.Result(result)); }
private static InvokeResult Simple(InvokeContext context, Func<DataObject[], DataObject> func) { var args = context.EvaluatedArguments; var funcResult = func(args); return context.Result(funcResult); }
public override InvokeResult Execute(InvokeContext context) { // There's some issues with implementing this function. // For this function to be efficient, we need to have access to the // underlying Table object(s) so we can use table indexing to sort the // columns. Otherwise, we will need to keep in memory the group // contents so it can be sorted. Or alternatively (and probably worst // of all) don't store in memory, but use an expensive iterative search // for non-distinct rows. // // An iterative search will be terrible for large groups with mostly // distinct rows. But would be okay for large groups with few distinct // rows. if (context.GroupResolver == null) { throw new Exception("'count' can only be used as an aggregate function."); } int rows = context.GroupResolver.Count; if (rows <= 1) { // If count of entries in group is 0 or 1 return(context.Result(Field.Integer(rows))); } // Make an array of all cells in the group that we are finding which // are distinct. int cols = context.ArgumentCount; var groupRow = new Field[rows * cols]; int n = 0; for (int i = 0; i < rows; ++i) { var vr = context.GroupResolver.GetVariableResolver(i); for (int p = 0; p < cols; ++p) { var exp = context.Arguments[p]; groupRow[n + p] = exp.Value.EvaluateToConstant(context.Request, vr); } n += cols; } var c = new DistinctComparer(cols, groupRow); // The list of indexes, var list = new int[rows]; for (int i = 0; i < rows; ++i) { list[i] = i; } // Sort the list, Array.Sort(list, c); // The count of distinct elements, (there will always be at least 1) int distinctCount = 1; for (int i = 1; i < rows; ++i) { int v = c.Compare(list[i], list[i - 1]); // If v == 0 then entry is not distinct with the previous element in // the sorted list therefore the distinct counter is not incremented. if (v > 0) { // If current entry is greater than previous then we've found a // distinct entry. ++distinctCount; } else if (v < 0) { // The current element should never be less if list is sorted in // ascending order. throw new Exception("Assertion failed - the distinct list does not " + "appear to be sorted."); } } // If the first entry in the list is NULL then subtract 1 from the // distinct count because we shouldn't be counting NULL entries. if (list.Length > 0) { int firstEntry = (int)list[0]; // Assume first is null bool firstIsNull = true; for (int m = 0; m < cols && firstIsNull; ++m) { var val = groupRow[(firstEntry * cols) + m]; if (!val.IsNull) { // First isn't null firstIsNull = false; } } // Is first NULL? if (firstIsNull) { // decrease distinct count so we don't count the null entry. distinctCount = distinctCount - 1; } } return(context.Result(Field.Integer(distinctCount))); }