[open-ils-commits] r16541 - in trunk/Open-ILS: include/openils src/c-apps (scottmk)
svn at svn.open-ils.org
svn at svn.open-ils.org
Tue Jun 1 11:06:23 EDT 2010
Author: scottmk
Date: 2010-06-01 11:06:20 -0400 (Tue, 01 Jun 2010)
New Revision: 16541
Modified:
trunk/Open-ILS/include/openils/oils_buildq.h
trunk/Open-ILS/src/c-apps/buildSQL.c
trunk/Open-ILS/src/c-apps/oils_storedq.c
Log:
Add support for GROUP BY.
M Open-ILS/include/openils/oils_buildq.h
M Open-ILS/src/c-apps/oils_storedq.c
M Open-ILS/src/c-apps/buildSQL.c
Modified: trunk/Open-ILS/include/openils/oils_buildq.h
===================================================================
--- trunk/Open-ILS/include/openils/oils_buildq.h 2010-06-01 14:48:11 UTC (rev 16540)
+++ trunk/Open-ILS/include/openils/oils_buildq.h 2010-06-01 15:06:20 UTC (rev 16541)
@@ -182,10 +182,9 @@
int negate; // Boolean
BindVar* bind;
Expression* subexp_list; // Linked list of subexpressions
- // The next two columns come, not from query.expression,
+ // The next column comes, not from query.expression,
// but from query.function_sig:
char* function_name;
- int is_aggregate; // Boolean
};
struct QSeq_ {
Modified: trunk/Open-ILS/src/c-apps/buildSQL.c
===================================================================
--- trunk/Open-ILS/src/c-apps/buildSQL.c 2010-06-01 14:48:11 UTC (rev 16540)
+++ trunk/Open-ILS/src/c-apps/buildSQL.c 2010-06-01 15:06:20 UTC (rev 16541)
@@ -21,6 +21,7 @@
static void buildFrom( BuildSQLState* state, const FromRelation* core_from );
static void buildJoin( BuildSQLState* state, const FromRelation* join );
static void buildSelectList( BuildSQLState* state, const SelectItem* item );
+static void buildGroupBy( BuildSQLState* state, const SelectItem* sel_list );
static void buildOrderBy( BuildSQLState* state, const OrderItem* ord_list );
static void buildExpression( BuildSQLState* state, const Expression* expr );
static void buildFunction( BuildSQLState* state, const Expression* exp );
@@ -293,7 +294,8 @@
decr_indent( state );
}
- // To do: build GROUP BY clause, if there is one
+ // Build GROUP BY clause, if there is one
+ buildGroupBy( state, query->select_list );
// Build HAVING clause, if there is one
if( query->having_clause ) {
@@ -403,6 +405,11 @@
decr_indent( state );
}
+/**
+ @brief Add a JOIN clause.
+ @param state Pointer to the query-building context.
+ @param join Pointer to the FromRelation representing the JOIN to be added.
+*/
static void buildJoin( BuildSQLState* state, const FromRelation* join ) {
add_newline( state );
switch( join->join_type ) {
@@ -527,6 +534,35 @@
}
/**
+ @brief Add a GROUP BY clause, if there is one, to the current query.
+ @param state Pointer to the query-building context.
+ @param sel_list Pointer to the first node in a linked list of SelectItems
+
+ We reference the GROUP BY items by number, not by repeating the expressions.
+*/
+static void buildGroupBy( BuildSQLState* state, const SelectItem* sel_list ) {
+ int seq = 0; // Sequence number of current SelectItem
+ int first = 1; // Boolean: true for the first GROUPed BY item
+ while( sel_list ) {
+ ++seq;
+
+ if( sel_list->grouped_by ) {
+ if( first ) {
+ add_newline( state );
+ buffer_add( state->sql, "GROUP BY " );
+ first = 0;
+ }
+ else
+ buffer_add( state->sql, ", " );
+
+ buffer_fadd( state->sql, "%d", seq );
+ }
+
+ sel_list = sel_list->next;
+ }
+}
+
+/**
@brief Add an ORDER BY clause to the current query.
@param state Pointer to the query-building context.
@param ord_list Pointer to the first node in a linked list of OrderItems.
Modified: trunk/Open-ILS/src/c-apps/oils_storedq.c
===================================================================
--- trunk/Open-ILS/src/c-apps/oils_storedq.c 2010-06-01 14:48:11 UTC (rev 16540)
+++ trunk/Open-ILS/src/c-apps/oils_storedq.c 2010-06-01 15:06:20 UTC (rev 16541)
@@ -118,7 +118,7 @@
} else {
const char* msg;
int errnum = dbi_conn_error( state->dbhandle, &msg );
- osrfLogError( OSRF_LOG_MARK, sqlAddMsg( state,
+ osrfLogError( OSRF_LOG_MARK, sqlAddMsg( state,
"Unable to query query.stored_query table: #%d %s",
errnum, msg ? msg : "No description available" ));
state->error = 1;
@@ -302,7 +302,7 @@
*/
static QSeq* loadChildQueries( BuildSQLState* state, int parent_id, const char* type_str ) {
QSeq* child_list = NULL;
-
+
// The ORDER BY is in descending order so that we can build the list by adding to
// the head, and it will wind up in the right order.
dbi_result result = dbi_conn_queryf( state->dbhandle,
@@ -687,7 +687,7 @@
*/
static FromRelation* getJoinList( BuildSQLState* state, int id ) {
FromRelation* join_list = NULL;
-
+
// The ORDER BY is in descending order so that we can build the list by adding to
// the head, and it will wind up in the right order.
dbi_result result = dbi_conn_queryf( state->dbhandle,
@@ -771,6 +771,11 @@
}
}
+/**
+ @brief Build a SELECT list for a given query ID.
+ @param state Pointer to the query-building context.
+ @param query_id ID of the query to which the SELECT list belongs.
+*/
static SelectItem* getSelectList( BuildSQLState* state, int query_id ) {
SelectItem* select_list = NULL;
@@ -834,7 +839,7 @@
int expression_id = dbi_result_get_int_idx( result, 4 );
const char* column_alias = dbi_result_get_string_idx( result, 5 );
int grouped_by = oils_result_get_bool_idx( result, 6 );
-
+
// Construct an Expression
Expression* expression = getExpression( state, expression_id );
if( !expression ) {
@@ -919,7 +924,7 @@
bind = constructBindVar( state, result );
if( bind ) {
PRINT( "Got a bind variable for %s\n", name );
- } else
+ } else
osrfLogError( OSRF_LOG_MARK, sqlAddMsg( state,
"Unable to load bind variable \"%s\"", name ));
} else {
@@ -1047,7 +1052,7 @@
@return Pointer to a newly-created Expression if successful, or NULL if not.
*/
static Expression* getExpression( BuildSQLState* state, int id ) {
-
+
// Check the stack to see if the current expression is nested inside itself. If it is,
// then abort in order to avoid infinite recursion. If it isn't, then add it to the
// stack. (Make sure to pop it off the stack before returning.)
@@ -1064,7 +1069,7 @@
"SELECT exp.id, exp.type, exp.parenthesize, exp.parent_expr, exp.seq_no, "
"exp.literal, exp.table_alias, exp.column_name, exp.left_operand, exp.operator, "
"exp.right_operand, exp.subquery, exp.cast_type, exp.negate, exp.bind_variable, "
- "func.function_name, COALESCE(func.is_aggregate, false) "
+ "func.function_name "
"FROM query.expression AS exp LEFT JOIN query.function_sig AS func "
"ON (exp.function_id = func.id) "
"WHERE exp.id = %d;", id );
@@ -1077,7 +1082,7 @@
PRINT( "\ttype = %d\n", exp->type );
PRINT( "\tparenthesize = %d\n", exp->parenthesize );
PRINT( "\tcolumn_name = %s\n", exp->column_name ? exp->column_name : "(none)" );
- } else
+ } else
osrfLogError( OSRF_LOG_MARK, sqlAddMsg( state,
"Unable to construct an Expression for id = %d", id ));
}
@@ -1106,7 +1111,7 @@
int id = dbi_result_get_int_idx( result, 1 );
const char* type_str = dbi_result_get_string_idx( result, 2 );
-
+
ExprType type;
if( !strcmp( type_str, "xbet" ))
type = EXP_BETWEEN;
@@ -1152,7 +1157,7 @@
parent_expr_id = -1;
else
parent_expr_id = dbi_result_get_int_idx( result, 4 );
-
+
int seq_no = dbi_result_get_int_idx( result, 5 );
const char* literal = dbi_result_get_string_idx( result, 6 );
const char* table_alias = dbi_result_get_string_idx( result, 7 );
@@ -1187,7 +1192,6 @@
int negate = oils_result_get_bool_idx( result, 14 );
const char* bind_variable = dbi_result_get_string_idx( result, 15 );
const char* function_name = dbi_result_get_string_idx( result, 16 );
- int is_aggregate = oils_result_get_bool_idx( result, 17 );
Expression* left_operand = NULL;
Expression* right_operand = NULL;
@@ -1472,7 +1476,6 @@
exp->bind = bind;
exp->subexp_list = subexp_list;
exp->function_name = function_name ? strdup( function_name ) : NULL;
- exp->is_aggregate = is_aggregate;
return exp;
}
@@ -1548,14 +1551,14 @@
*/
static Expression* getExpressionList( BuildSQLState* state, int id ) {
Expression* exp_list = NULL;
-
+
// The ORDER BY is in descending order so that we can build the list by adding to
// the head, and it will wind up in the right order.
dbi_result result = dbi_conn_queryf( state->dbhandle,
"SELECT exp.id, exp.type, exp.parenthesize, exp.parent_expr, exp.seq_no, "
"exp.literal, exp.table_alias, exp.column_name, exp.left_operand, exp.operator, "
"exp.right_operand, exp.subquery, exp.cast_type, exp.negate, exp.bind_variable, "
- "func.function_name, COALESCE(func.is_aggregate, false) "
+ "func.function_name "
"FROM query.expression AS exp LEFT JOIN query.function_sig AS func "
"ON (exp.function_id = func.id) "
"WHERE exp.parent_expr = %d "
@@ -1796,7 +1799,7 @@
node->alias = strdup( alias );
else
node->alias = NULL;
-
+
// Reseat the stack
*stack = node;
}
More information about the open-ils-commits
mailing list