From 0a188f7944cbba5aa0437640af353f370311982c Mon Sep 17 00:00:00 2001 From: scottmk Date: Tue, 8 Jun 2010 21:01:27 +0000 Subject: [PATCH] 1. Support function calls in the FROM clause. 2. Support wildcards in the SELECT clause. WARNING: the presence of a wildcard in the SELECT clause is likely to disrupt a GROUP BY by renumbering the columns. Also: the "columns" method currently cannot return the names of the columns into which a wild card is expanded. 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 git-svn-id: svn://svn.open-ils.org/ILS/trunk@16628 dcc99617-32d9-48b4-a31d-7c20da2025e4 --- Open-ILS/include/openils/oils_buildq.h | 1 + Open-ILS/src/c-apps/buildSQL.c | 20 ++++++++-- Open-ILS/src/c-apps/oils_storedq.c | 51 +++++++++++++++++++------- 3 files changed, 54 insertions(+), 18 deletions(-) diff --git a/Open-ILS/include/openils/oils_buildq.h b/Open-ILS/include/openils/oils_buildq.h index 78ead41e28..f9cfe79d42 100644 --- a/Open-ILS/include/openils/oils_buildq.h +++ b/Open-ILS/include/openils/oils_buildq.h @@ -108,6 +108,7 @@ struct FromRelation_ { int subquery_id; StoredQ* subquery; int function_call_id; + Expression* function_call; char* table_alias; int parent_relation_id; int seq_no; diff --git a/Open-ILS/src/c-apps/buildSQL.c b/Open-ILS/src/c-apps/buildSQL.c index 596e0ab8f0..15cc46c552 100644 --- a/Open-ILS/src/c-apps/buildSQL.c +++ b/Open-ILS/src/c-apps/buildSQL.c @@ -372,7 +372,18 @@ static void buildFrom( BuildSQLState* state, const FromRelation* core_from ) { buffer_add_char( state->sql, ')' ); break; case FRT_FUNCTION : - sqlAddMsg( state, "Functions in FROM clause not yet supported" ); + buildFunction( state, core_from->function_call ); + if ( state->error ) { + sqlAddMsg( state, + "Unable to include function call # %d in FROM relation # %d", + core_from->function_call->id, core_from->id ); + return; + } + break; + default : + osrfLogError( OSRF_LOG_MARK, sqlAddMsg( state, + "Internal error: Invalid type # %d in FROM relation # %d", + core_from->type, core_from->id )); state->error = 1; return; } @@ -683,9 +694,10 @@ static void buildExpression( BuildSQLState* state, const Expression* expr ) { if( expr->column_name ) { buffer_add( state->sql, expr->column_name ); } else { - osrfLogWarning( OSRF_LOG_MARK, sqlAddMsg( state, - "Column name not present in expression # %d", expr->id )); - state->error = 1; + //osrfLogWarning( OSRF_LOG_MARK, sqlAddMsg( state, + // "Column name not present in expression # %d", expr->id )); + //state->error = 1; + buffer_add_char( state->sql, '*' ); } break; case EXP_EXIST : diff --git a/Open-ILS/src/c-apps/oils_storedq.c b/Open-ILS/src/c-apps/oils_storedq.c index a4bcc98a5e..50e6ab8ae8 100644 --- a/Open-ILS/src/c-apps/oils_storedq.c +++ b/Open-ILS/src/c-apps/oils_storedq.c @@ -547,30 +547,31 @@ static FromRelation* constructFromRelation( BuildSQLState* state, dbi_result res else type = FRT_RELATION; // shouldn't happen due to database constraint - const char* table_name = dbi_result_get_string_idx( result, 3 ); - const char* class_name = dbi_result_get_string_idx( result, 4 ); + const char* table_name = dbi_result_get_string_idx( result, 3 ); + const char* class_name = dbi_result_get_string_idx( result, 4 ); int subquery_id; if( dbi_result_field_is_null_idx( result, 5 ) ) - subquery_id = -1; + subquery_id = -1; else - subquery_id = dbi_result_get_int_idx( result, 5 ); + subquery_id = dbi_result_get_int_idx( result, 5 ); int function_call_id; if( dbi_result_field_is_null_idx( result, 6 ) ) - function_call_id = -1; + function_call_id = -1; else - function_call_id = dbi_result_get_int_idx( result, 6 ); + function_call_id = dbi_result_get_int_idx( result, 6 ); - const char* table_alias = dbi_result_get_string_idx( result, 7 ); + Expression* function_call = NULL; + const char* table_alias = dbi_result_get_string_idx( result, 7 ); int parent_relation_id; if( dbi_result_field_is_null_idx( result, 8 ) ) - parent_relation_id = -1; + parent_relation_id = -1; else - parent_relation_id = dbi_result_get_int_idx( result, 8 ); + parent_relation_id = dbi_result_get_int_idx( result, 8 ); - int seq_no = dbi_result_get_int_idx( result, 9 ); + int seq_no = dbi_result_get_int_idx( result, 9 ); JoinType join_type; const char* join_type_str = dbi_result_get_string_idx( result, 10 ); @@ -620,10 +621,27 @@ static FromRelation* constructFromRelation( BuildSQLState* state, dbi_result res } break; case FRT_FUNCTION : - osrfLogWarning( OSRF_LOG_MARK, sqlAddMsg( state, - "Functions in FROM clause not yet supported" )); - state->error = 1; - return NULL; + if( -1 == function_call_id ) { + osrfLogWarning( OSRF_LOG_MARK, sqlAddMsg( state, + "FROM clause # %d purports to reference a function; not identified", id )); + state->error = 1; + return NULL; + } + + function_call = getExpression( state, function_call_id ); + if( !function_call ) { + osrfLogWarning( OSRF_LOG_MARK, sqlAddMsg( state, + "Unable to build function call # %d in FROM relation # %d", + function_call_id, id )); + state->error = 1; + return NULL; + } else if( function_call->type != EXP_FUNCTION ) { + osrfLogWarning( OSRF_LOG_MARK, sqlAddMsg( state, + "In FROM relation # %d: supposed function call expression # %d " + "is not a function call", id, function_call_id )); + state->error = 1; + return NULL; + } } FromRelation* join_list = getJoinList( state, id ); @@ -666,6 +684,7 @@ static FromRelation* constructFromRelation( BuildSQLState* state, dbi_result res fr->subquery_id = subquery_id; fr->subquery = subquery; fr->function_call_id = function_call_id; + fr->function_call = function_call; fr->table_alias = table_alias ? strdup( table_alias ) : NULL; fr->parent_relation_id = parent_relation_id; fr->seq_no = seq_no; @@ -757,6 +776,10 @@ static void fromRelationFree( FromRelation* fr ) { storedQFree( fr->subquery ); fr->subquery = NULL; } + if( fr->function_call ) { + expressionFree( fr->function_call ); + fr->function_call = NULL; + } free( fr->table_alias ); fr->table_alias = NULL; if( fr->on_clause ) { -- 2.43.2