DeveelDB  20151217
complete SQL database system, primarly developed for .NET/Mono frameworks
AggregateFunction.cs
Go to the documentation of this file.
1 //
2 // Copyright 2010-2015 Deveel
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 using System;
18 
19 using Deveel.Data;
20 using Deveel.Data.Sql;
22 using Deveel.Data.Types;
23 
24 namespace Deveel.Data.Routines {
25  public abstract class AggregateFunction : Function {
26  protected AggregateFunction(ObjectName name, RoutineParameter[] parameters, SqlType returnType)
27  : base(name, parameters, returnType, FunctionType.Aggregate) {
28  }
29 
30  protected abstract DataObject Evaluate(DataObject value1, DataObject value2, IRequest query, IGroupResolver group);
31 
32  protected virtual DataObject PostEvaluate(DataObject result, IRequest query, IGroupResolver group) {
33  // By default, do nothing....
34  return result;
35  }
36 
37  public override InvokeResult Execute(InvokeContext context) {
38  if (context == null)
39  throw new ArgumentNullException("context");
40 
41  var group = context.GroupResolver;
42 
43  if (group == null)
44  throw new Exception(String.Format("'{0}' can only be used as an aggregate function.", FunctionName));
45 
46  DataObject result = null;
47  // All aggregates functions return 'null' if group size is 0
48  int size = group.Count;
49  if (size == 0) {
50  // Return a NULL of the return type
51  return context.Result(DataObject.Null(ReturnType(context)));
52  }
53 
54  DataObject val;
55  ObjectName v = context.Arguments[0].AsReferenceName();
56  // If the aggregate parameter is a simple variable, then use optimal
57  // routine,
58  if (v != null) {
59  for (int i = 0; i < size; ++i) {
60  val = group.Resolve(v, i);
61  result = Evaluate(result, val, context.Request, group);
62  }
63  } else {
64  // Otherwise we must resolve the expression for each entry in group,
65  // This allows for expressions such as 'sum(quantity * price)' to
66  // work for a group.
67  var exp = context.Arguments[0];
68  for (int i = 0; i < size; ++i) {
69  val = exp.EvaluateToConstant(context.Request, group.GetVariableResolver(i));
70  result = Evaluate(result, val, context.Request, group);
71  }
72  }
73 
74  // Post method.
75  result = PostEvaluate(result, context.Request, group);
76 
77  return context.Result(result);
78  }
79  }
80 }
A type that represents an aggregate function.
A long string in the system.
A system routine that returns a value at the end of its execution.
Definition: Function.cs:31
static DataObject Null(SqlType type)
Definition: DataObject.cs:630
SqlExpression[] Arguments
Gets the array of expressions forming the arguments of the execution.
Describes the name of an object within a database.
Definition: ObjectName.cs:44
override InvokeResult Execute(InvokeContext context)
Executes the function and provides a result.
AggregateFunction(ObjectName name, RoutineParameter[] parameters, SqlType returnType)
virtual DataObject PostEvaluate(DataObject result, IRequest query, IGroupResolver group)
Defines a contract used by grouping functions to find information about the current group being evalu...
Represents the result of the execution of a routine.
Definition: InvokeResult.cs:25
Represents a dynamic object that encapsulates a defined SqlType and a compatible constant ISqlObject ...
Definition: DataObject.cs:35
FunctionType
The different type of a function.
Definition: FunctionType.cs:25
Defines the properties of a specific SQL Type and handles the values compatible.
Definition: SqlType.cs:33
InvokeResult Result(DataObject value)