[tracker] rasqal: Add SUM, AVG, MIN, and MAX aggregate function support
- From: Jürg Billeter <juergbi src gnome org>
- To: svn-commits-list gnome org
- Subject: [tracker] rasqal: Add SUM, AVG, MIN, and MAX aggregate function support
- Date: Thu, 16 Apr 2009 10:17:51 -0400 (EDT)
commit 3ef25197a2a77e01bac8a3f96e59807aea1ebb9d
Author: Jürg Billeter <j bitron ch>
Date: Wed Dec 10 17:15:14 2008 +0100
rasqal: Add SUM, AVG, MIN, and MAX aggregate function support
---
src/rasqal/rasqal.h | 8 ++++
src/rasqal/rasqal_expr.c | 27 +++++++++++++-
src/rasqal/sparql_lexer.l | 4 ++
src/rasqal/sparql_parser.y | 88 ++++++++++++++++++++++++++++++++++++++++++-
4 files changed, 123 insertions(+), 4 deletions(-)
diff --git a/src/rasqal/rasqal.h b/src/rasqal/rasqal.h
index 225e34e..5dfbae3 100644
--- a/src/rasqal/rasqal.h
+++ b/src/rasqal/rasqal.h
@@ -441,6 +441,10 @@ struct rasqal_literal_s {
* @RASQAL_EXPR_COUNT: Expression for LAQRS select COUNT()
* @RASQAL_EXPR_VARSTAR: Expression for LAQRS select Variable *
* @RASQAL_EXPR_SAMETERM: Expression for SPARQL sameTerm
+ * @RASQAL_EXPR_SUM: Expression for LAQRS select SUM()
+ * @RASQAL_EXPR_AVG: Expression for LAQRS select AVG()
+ * @RASQAL_EXPR_MIN: Expression for LAQRS select MIN()
+ * @RASQAL_EXPR_MAX: Expression for LAQRS select MAX()
* @RASQAL_EXPR_UNKNOWN: Internal
* @RASQAL_EXPR_LAST: Internal
*
@@ -490,6 +494,10 @@ typedef enum {
RASQAL_EXPR_COUNT,
RASQAL_EXPR_VARSTAR,
RASQAL_EXPR_SAMETERM,
+ RASQAL_EXPR_SUM,
+ RASQAL_EXPR_AVG,
+ RASQAL_EXPR_MIN,
+ RASQAL_EXPR_MAX,
/* internal */
RASQAL_EXPR_LAST= RASQAL_EXPR_SAMETERM
} rasqal_op;
diff --git a/src/rasqal/rasqal_expr.c b/src/rasqal/rasqal_expr.c
index 07d99fd..1e3b76f 100644
--- a/src/rasqal/rasqal_expr.c
+++ b/src/rasqal/rasqal_expr.c
@@ -438,7 +438,8 @@ rasqal_new_0op_expression(rasqal_world* world, rasqal_op op)
* @RASQAL_EXPR_DATATYPE @RASQAL_EXPR_ISURI @RASQAL_EXPR_ISBLANK
* @RASQAL_EXPR_ISLITERAL @RASQAL_EXPR_ORDER_COND_ASC
* @RASQAL_EXPR_ORDER_COND_DESC @RASQAL_EXPR_GROUP_COND_ASC
- * @RASQAL_EXPR_GROUP_COND_DESC @RASQAL_EXPR_COUNT
+ * @RASQAL_EXPR_GROUP_COND_DESC @RASQAL_EXPR_COUNT @RASQAL_EXPR_SUM
+ * @RASQAL_EXPR_AVG @RASQAL_EXPR_MIN @RASQAL_EXPR_MAX
*
* @RASQAL_EXPR_BANG and @RASQAL_EXPR_UMINUS are used by RDQL and
* SPARQL. @RASQAL_EXPR_TILDE by RDQL only. The rest by SPARQL
@@ -796,6 +797,10 @@ rasqal_expression_clear(rasqal_expression* e)
case RASQAL_EXPR_GROUP_COND_ASC:
case RASQAL_EXPR_GROUP_COND_DESC:
case RASQAL_EXPR_COUNT:
+ case RASQAL_EXPR_SUM:
+ case RASQAL_EXPR_AVG:
+ case RASQAL_EXPR_MIN:
+ case RASQAL_EXPR_MAX:
rasqal_free_expression(e->arg1);
break;
case RASQAL_EXPR_STR_MATCH:
@@ -939,6 +944,10 @@ rasqal_expression_visit(rasqal_expression* e,
case RASQAL_EXPR_GROUP_COND_ASC:
case RASQAL_EXPR_GROUP_COND_DESC:
case RASQAL_EXPR_COUNT:
+ case RASQAL_EXPR_SUM:
+ case RASQAL_EXPR_AVG:
+ case RASQAL_EXPR_MIN:
+ case RASQAL_EXPR_MAX:
return rasqal_expression_visit(e->arg1, fn, user_data);
break;
case RASQAL_EXPR_STR_MATCH:
@@ -1899,6 +1908,10 @@ rasqal_expression_evaluate_v2(rasqal_world *world, raptor_locator *locator,
case RASQAL_EXPR_GROUP_COND_ASC:
case RASQAL_EXPR_GROUP_COND_DESC:
case RASQAL_EXPR_COUNT:
+ case RASQAL_EXPR_SUM:
+ case RASQAL_EXPR_AVG:
+ case RASQAL_EXPR_MIN:
+ case RASQAL_EXPR_MAX:
result=rasqal_expression_evaluate_v2(world, locator, e->arg1, flags);
break;
@@ -2129,6 +2142,10 @@ rasqal_expression_write(rasqal_expression* e, raptor_iostream* iostr)
case RASQAL_EXPR_GROUP_COND_ASC:
case RASQAL_EXPR_GROUP_COND_DESC:
case RASQAL_EXPR_COUNT:
+ case RASQAL_EXPR_SUM:
+ case RASQAL_EXPR_AVG:
+ case RASQAL_EXPR_MIN:
+ case RASQAL_EXPR_MAX:
raptor_iostream_write_counted_string(iostr, "op ", 3);
rasqal_expression_write_op(e, iostr);
raptor_iostream_write_byte(iostr, '(');
@@ -2252,6 +2269,10 @@ rasqal_expression_print(rasqal_expression* e, FILE* fh)
case RASQAL_EXPR_GROUP_COND_ASC:
case RASQAL_EXPR_GROUP_COND_DESC:
case RASQAL_EXPR_COUNT:
+ case RASQAL_EXPR_SUM:
+ case RASQAL_EXPR_AVG:
+ case RASQAL_EXPR_MIN:
+ case RASQAL_EXPR_MAX:
fputs("op ", fh);
rasqal_expression_print_op(e, fh);
fputc('(', fh);
@@ -2373,6 +2394,10 @@ rasqal_expression_is_constant(rasqal_expression* e)
case RASQAL_EXPR_GROUP_COND_ASC:
case RASQAL_EXPR_GROUP_COND_DESC:
case RASQAL_EXPR_COUNT:
+ case RASQAL_EXPR_SUM:
+ case RASQAL_EXPR_AVG:
+ case RASQAL_EXPR_MIN:
+ case RASQAL_EXPR_MAX:
result=rasqal_expression_is_constant(e->arg1);
break;
diff --git a/src/rasqal/sparql_lexer.l b/src/rasqal/sparql_lexer.l
index cf8db7b..68dee58 100644
--- a/src/rasqal/sparql_lexer.l
+++ b/src/rasqal/sparql_lexer.l
@@ -353,6 +353,10 @@ EXPONENT [eE][+-]?[0-9]+
[Ee][Xx][Pp][Ll][Aa][Ii][Nn] { return EXPLAIN; }
[Gg][Rr][Oo][Uu][Pp] { return GROUP; }
[Cc][Oo][Uu][Nn][Tt] { return COUNT; }
+[Ss][Uu][Mm] { return SUM; }
+[Aa][Vv][Gg] { return AVERAGE; }
+[Mm][Ii][Nn] { return MINIMUM; }
+[Mm][Aa][Xx] { return MAXIMUM; }
[Aa][Ss] { BEGIN(SPID); return AS; }
[Dd][Ee][Ll][Ee][Tt][Ee] { return DELETE; }
[Ii][Nn][Ss][Ee][Rr][Tt] { return INSERT; }
diff --git a/src/rasqal/sparql_parser.y b/src/rasqal/sparql_parser.y
index 7723dd0..2782cf8 100644
--- a/src/rasqal/sparql_parser.y
+++ b/src/rasqal/sparql_parser.y
@@ -145,7 +145,7 @@ static void sparql_query_error_full(rasqal_query *rq, const char *message, ...)
%token ISLITERAL "isLiteral"
%token SAMETERM "sameTerm"
/* LAQRS */
-%token EXPLAIN GROUP COUNT AS
+%token EXPLAIN GROUP COUNT SUM AVERAGE MINIMUM MAXIMUM AS
%token DELETE INSERT
@@ -218,7 +218,8 @@ static void sparql_query_error_full(rasqal_query *rq, const char *message, ...)
%type <expr> BuiltInCall RegexExpression FunctionCall
%type <expr> BrackettedExpression PrimaryExpression
%type <expr> OrderCondition Filter Constraint SelectExpression
-%type <expr> AggregateExpression CountAggregateExpression
+%type <expr> AggregateExpression CountAggregateExpression SumAggregateExpression
+%type <expr> AvgAggregateExpression MinAggregateExpression MaxAggregateExpression
%type <literal> GraphTerm IRIref BlankNode
%type <literal> VarOrIRIref
@@ -296,7 +297,8 @@ MultiplicativeExpression UnaryExpression
BuiltInCall RegexExpression FunctionCall
BrackettedExpression PrimaryExpression
OrderCondition Filter Constraint SelectExpression
-AggregateExpression CountAggregateExpression
+AggregateExpression CountAggregateExpression SumAggregateExpression
+AvgAggregateExpression MinAggregateExpression MaxAggregateExpression
%destructor {
if($$)
@@ -554,6 +556,22 @@ AggregateExpression: CountAggregateExpression
{
$$=$1;
}
+| SumAggregateExpression
+{
+ $$=$1;
+}
+| AvgAggregateExpression
+{
+ $$=$1;
+}
+| MinAggregateExpression
+{
+ $$=$1;
+}
+| MaxAggregateExpression
+{
+ $$=$1;
+}
;
@@ -589,6 +607,70 @@ CountAggregateExpression: COUNT '(' Expression ')'
;
+SumAggregateExpression: SUM '(' Expression ')'
+{
+ rasqal_sparql_query_language* sparql=(rasqal_sparql_query_language*)(((rasqal_query*)rq)->context);
+
+ if(!sparql->extended) {
+ sparql_syntax_error((rasqal_query*)rq, "SUM cannot be used with SPARQL");
+ $$=NULL;
+ } else {
+ $$=rasqal_new_1op_expression(((rasqal_query*)rq)->world, RASQAL_EXPR_SUM, $3);
+ if(!$$)
+ YYERROR_MSG("SumAggregateExpression 1: cannot create expr");
+ }
+}
+;
+
+
+AvgAggregateExpression: AVERAGE '(' Expression ')'
+{
+ rasqal_sparql_query_language* sparql=(rasqal_sparql_query_language*)(((rasqal_query*)rq)->context);
+
+ if(!sparql->extended) {
+ sparql_syntax_error((rasqal_query*)rq, "AVG cannot be used with SPARQL");
+ $$=NULL;
+ } else {
+ $$=rasqal_new_1op_expression(((rasqal_query*)rq)->world, RASQAL_EXPR_AVG, $3);
+ if(!$$)
+ YYERROR_MSG("AvgAggregateExpression 1: cannot create expr");
+ }
+}
+;
+
+
+MinAggregateExpression: MINIMUM '(' Expression ')'
+{
+ rasqal_sparql_query_language* sparql=(rasqal_sparql_query_language*)(((rasqal_query*)rq)->context);
+
+ if(!sparql->extended) {
+ sparql_syntax_error((rasqal_query*)rq, "MIN cannot be used with SPARQL");
+ $$=NULL;
+ } else {
+ $$=rasqal_new_1op_expression(((rasqal_query*)rq)->world, RASQAL_EXPR_MIN, $3);
+ if(!$$)
+ YYERROR_MSG("MinAggregateExpression 1: cannot create expr");
+ }
+}
+;
+
+
+MaxAggregateExpression: MAXIMUM '(' Expression ')'
+{
+ rasqal_sparql_query_language* sparql=(rasqal_sparql_query_language*)(((rasqal_query*)rq)->context);
+
+ if(!sparql->extended) {
+ sparql_syntax_error((rasqal_query*)rq, "MAX cannot be used with SPARQL");
+ $$=NULL;
+ } else {
+ $$=rasqal_new_1op_expression(((rasqal_query*)rq)->world, RASQAL_EXPR_MAX, $3);
+ if(!$$)
+ YYERROR_MSG("MaxAggregateExpression 1: cannot create expr");
+ }
+}
+;
+
+
/* SPARQL Grammar: [6] ConstructQuery */
ConstructQuery: CONSTRUCT ConstructTemplate
DatasetClauseListOpt WhereClauseOpt SolutionModifier
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]