[open-ils-commits] r13752 - trunk/Open-ILS/src/c-apps (scottmk)
svn at svn.open-ils.org
svn at svn.open-ils.org
Tue Jul 28 08:37:42 EDT 2009
Author: scottmk
Date: 2009-07-28 08:37:41 -0400 (Tue, 28 Jul 2009)
New Revision: 13752
Modified:
trunk/Open-ILS/src/c-apps/oils_cstore.c
Log:
Support table aliases other than class names for joined tables
(not, so far, for tables outside of a JOIN clause).
Also: when constructing a BETWEEN clause, qualify the column
name with a table alias (correcting an apparent oversight).
Also: when using the "+class" trick to apply a table alias,
verify that the alias is in scope.
Modified: trunk/Open-ILS/src/c-apps/oils_cstore.c
===================================================================
--- trunk/Open-ILS/src/c-apps/oils_cstore.c 2009-07-28 06:26:25 UTC (rev 13751)
+++ trunk/Open-ILS/src/c-apps/oils_cstore.c 2009-07-28 12:37:41 UTC (rev 13752)
@@ -93,17 +93,17 @@
static jsonObject* oilsMakeFieldmapperFromResult( dbi_result, osrfHash* );
static jsonObject* oilsMakeJSONFromResult( dbi_result );
-static char* searchSimplePredicate ( const char* op, const char* class,
+static char* searchSimplePredicate ( const char* op, const char* class_alias,
osrfHash* field, const jsonObject* node );
static char* searchFunctionPredicate ( const char*, osrfHash*, const jsonObject*, const char* );
static char* searchFieldTransform ( const char*, osrfHash*, const jsonObject*);
-static char* searchFieldTransformPredicate ( const char*, osrfHash*, const jsonObject*, const char* );
+static char* searchFieldTransformPredicate ( const ClassInfo*, osrfHash*, const jsonObject*, const char* );
static char* searchBETWEENPredicate ( const char*, osrfHash*, const jsonObject* );
static char* searchINPredicate ( const char*, osrfHash*,
jsonObject*, const char*, osrfMethodContext* );
-static char* searchPredicate ( const char*, osrfHash*, jsonObject*, osrfMethodContext* );
-static char* searchJOIN ( const jsonObject*, osrfHash* );
-static char* searchWHERE ( const jsonObject*, osrfHash*, int, osrfMethodContext* );
+static char* searchPredicate ( const ClassInfo*, osrfHash*, jsonObject*, osrfMethodContext* );
+static char* searchJOIN ( const jsonObject*, const ClassInfo* left_info );
+static char* searchWHERE ( const jsonObject*, const ClassInfo*, int, osrfMethodContext* );
static char* buildSELECT ( jsonObject*, jsonObject*, osrfHash*, osrfMethodContext* );
char* SELECT ( osrfMethodContext*, jsonObject*, jsonObject*, jsonObject*, jsonObject*, jsonObject*, jsonObject*, jsonObject*, int );
@@ -1746,14 +1746,14 @@
return buffer_release(val_buf);
}
-static char* searchINPredicate (const char* class, osrfHash* field,
+static char* searchINPredicate (const char* class_alias, osrfHash* field,
jsonObject* node, const char* op, osrfMethodContext* ctx ) {
growing_buffer* sql_buf = buffer_init(32);
buffer_fadd(
sql_buf,
"\"%s\".%s ",
- class,
+ class_alias,
osrfHashGet(field, "name")
);
@@ -1902,7 +1902,7 @@
return buffer_release(sql_buf);
}
-static char* searchFunctionPredicate (const char* class, osrfHash* field,
+static char* searchFunctionPredicate (const char* class_alias, osrfHash* field,
const jsonObject* node, const char* op) {
if( ! is_good_operator( op ) ) {
@@ -1918,7 +1918,7 @@
buffer_fadd(
sql_buf,
"\"%s\".%s %s %s",
- class,
+ class_alias,
osrfHashGet(field, "name"),
op,
val
@@ -1929,10 +1929,10 @@
return buffer_release(sql_buf);
}
-// class is a class name
+// class_alias is a class name or other table alias
// field is a field definition as stored in the IDL
// node comes from the method parameter, and may represent an entry in the SELECT list
-static char* searchFieldTransform (const char* class, osrfHash* field, const jsonObject* node) {
+static char* searchFieldTransform (const char* class_alias, osrfHash* field, const jsonObject* node) {
growing_buffer* sql_buf = buffer_init(32);
const char* field_transform = jsonObjectGetString( jsonObjectGetKeyConst( node, "transform" ) );
@@ -1957,7 +1957,7 @@
return NULL;
}
- buffer_fadd( sql_buf, "%s(\"%s\".%s", field_transform, class, osrfHashGet(field, "name"));
+ buffer_fadd( sql_buf, "%s(\"%s\".%s", field_transform, class_alias, osrfHashGet(field, "name"));
const jsonObject* array = jsonObjectGetKeyConst( node, "params" );
if (array) {
@@ -1992,7 +1992,7 @@
buffer_add( sql_buf, " )" );
} else {
- buffer_fadd( sql_buf, "\"%s\".%s", class, osrfHashGet(field, "name"));
+ buffer_fadd( sql_buf, "\"%s\".%s", class_alias, osrfHashGet(field, "name"));
}
if (transform_subcolumn)
@@ -2001,7 +2001,7 @@
return buffer_release(sql_buf);
}
-static char* searchFieldTransformPredicate (const char* class, osrfHash* field,
+static char* searchFieldTransformPredicate( const ClassInfo* class_info, osrfHash* field,
const jsonObject* node, const char* op ) {
if( ! is_good_operator( op ) ) {
@@ -2009,7 +2009,7 @@
return NULL;
}
- char* field_transform = searchFieldTransform( class, field, node );
+ char* field_transform = searchFieldTransform( class_info->alias, field, node );
if( ! field_transform )
return NULL;
char* value = NULL;
@@ -2017,7 +2017,7 @@
const jsonObject* value_obj = jsonObjectGetKeyConst( node, "value" );
if ( ! value_obj ) {
- value = searchWHERE( node, osrfHashGet( oilsIDL(), class ), AND_OP_JOIN, NULL );
+ value = searchWHERE( node, class_info, AND_OP_JOIN, NULL );
if( !value ) {
osrfLogError(OSRF_LOG_MARK, "%s: Error building condition for field transform", MODULENAME);
free(field_transform);
@@ -2032,7 +2032,7 @@
return NULL;
}
} else if ( value_obj->type == JSON_HASH ) {
- value = searchWHERE( value_obj, osrfHashGet( oilsIDL(), class ), AND_OP_JOIN, NULL );
+ value = searchWHERE( value_obj, class_info, AND_OP_JOIN, NULL );
if( !value ) {
osrfLogError(OSRF_LOG_MARK, "%s: Error building predicate for field transform", MODULENAME);
free(field_transform);
@@ -2091,7 +2091,7 @@
return buffer_release(sql_buf);
}
-static char* searchSimplePredicate (const char* op, const char* class,
+static char* searchSimplePredicate (const char* op, const char* class_alias,
osrfHash* field, const jsonObject* node) {
if( ! is_good_operator( op ) ) {
@@ -2131,7 +2131,7 @@
}
growing_buffer* sql_buf = buffer_init(32);
- buffer_fadd( sql_buf, "\"%s\".%s %s %s", class, osrfHashGet(field, "name"), op, val );
+ buffer_fadd( sql_buf, "\"%s\".%s %s %s", class_alias, osrfHashGet(field, "name"), op, val );
char* pred = buffer_release( sql_buf );
free(val);
@@ -2139,7 +2139,8 @@
return pred;
}
-static char* searchBETWEENPredicate (const char* class, osrfHash* field, const jsonObject* node) {
+static char* searchBETWEENPredicate (const char* class_alias,
+ osrfHash* field, const jsonObject* node) {
const jsonObject* x_node = jsonObjectGetIndex( node, 0 );
const jsonObject* y_node = jsonObjectGetIndex( node, 1 );
@@ -2173,19 +2174,20 @@
}
growing_buffer* sql_buf = buffer_init(32);
- buffer_fadd( sql_buf, "%s BETWEEN %s AND %s", osrfHashGet(field, "name"), x_string, y_string );
+ buffer_fadd( sql_buf, "\"%s\".%s BETWEEN %s AND %s",
+ class_alias, osrfHashGet(field, "name"), x_string, y_string );
free(x_string);
free(y_string);
return buffer_release(sql_buf);
}
-static char* searchPredicate ( const char* class, osrfHash* field,
+static char* searchPredicate ( const ClassInfo* class_info, osrfHash* field,
jsonObject* node, osrfMethodContext* ctx ) {
char* pred = NULL;
if (node->type == JSON_ARRAY) { // equality IN search
- pred = searchINPredicate( class, field, node, NULL, ctx );
+ pred = searchINPredicate( class_info->alias, field, node, NULL, ctx );
} else if (node->type == JSON_HASH) { // other search
jsonIterator* pred_itr = jsonNewIterator( node );
if( !jsonIteratorHasNext( pred_itr ) ) {
@@ -2199,15 +2201,15 @@
osrfLogError( OSRF_LOG_MARK, "%s: Multiple predicates for field \"%s\"",
MODULENAME, osrfHashGet(field, "name") );
} else if ( !(strcasecmp( pred_itr->key,"between" )) )
- pred = searchBETWEENPredicate( class, field, pred_node );
+ pred = searchBETWEENPredicate( class_info->alias, field, pred_node );
else if ( !(strcasecmp( pred_itr->key,"in" )) || !(strcasecmp( pred_itr->key,"not in" )) )
- pred = searchINPredicate( class, field, pred_node, pred_itr->key, ctx );
+ pred = searchINPredicate( class_info->alias, field, pred_node, pred_itr->key, ctx );
else if ( pred_node->type == JSON_ARRAY )
- pred = searchFunctionPredicate( class, field, pred_node, pred_itr->key );
+ pred = searchFunctionPredicate( class_info->alias, field, pred_node, pred_itr->key );
else if ( pred_node->type == JSON_HASH )
- pred = searchFieldTransformPredicate( class, field, pred_node, pred_itr->key );
+ pred = searchFieldTransformPredicate( class_info, field, pred_node, pred_itr->key );
else
- pred = searchSimplePredicate( pred_itr->key, class, field, pred_node );
+ pred = searchSimplePredicate( pred_itr->key, class_info->alias, field, pred_node );
}
jsonIteratorFree(pred_itr);
@@ -2216,12 +2218,12 @@
buffer_fadd(
_p,
"\"%s\".%s IS NULL",
- class,
+ class_info->class_name,
osrfHashGet(field, "name")
);
pred = buffer_release(_p);
} else { // equality search
- pred = searchSimplePredicate( "=", class, field, node );
+ pred = searchSimplePredicate( "=", class_info->alias, field, node );
}
return pred;
@@ -2256,7 +2258,7 @@
*/
-static char* searchJOIN ( const jsonObject* join_hash, osrfHash* leftmeta ) {
+static char* searchJOIN ( const jsonObject* join_hash, const ClassInfo* left_info ) {
const jsonObject* working_hash;
jsonObject* freeable_hash = NULL;
@@ -2280,16 +2282,20 @@
}
growing_buffer* join_buf = buffer_init(128);
- const char* leftclass = osrfHashGet(leftmeta, "classname");
+ const char* leftclass = left_info->class_name;
jsonObject* snode = NULL;
jsonIterator* search_itr = jsonNewIterator( working_hash );
while ( (snode = jsonIteratorNext( search_itr )) ) {
- const char* class = search_itr->key;
- const char* table_alias = NULL; // stubbed out for now
- const ClassInfo* class_info = add_joined_class( table_alias, class );
- if( !class_info ) {
+ const char* right_alias = search_itr->key;
+ const char* class =
+ jsonObjectGetString( jsonObjectGetKeyConst( snode, "class" ) );
+ if( ! class )
+ class = right_alias;
+
+ const ClassInfo* right_info = add_joined_class( right_alias, class );
+ if( !right_info ) {
osrfLogError(
OSRF_LOG_MARK,
"%s: JOIN failed. Class \"%s\" not resolved in IDL",
@@ -2302,11 +2308,10 @@
jsonObjectFree( freeable_hash );
return NULL;
}
- osrfHash* idlClass = class_info->class_def;
- osrfHash* links = class_info->links;
- const char* table = class_info->source_def;
+ osrfHash* links = right_info->links;
+ const char* table = right_info->source_def;
- const char* fkey = jsonObjectGetString( jsonObjectGetKeyConst( snode, "fkey" ) );
+ const char* fkey = jsonObjectGetString( jsonObjectGetKeyConst( snode, "fkey" ) );
const char* field = jsonObjectGetString( jsonObjectGetKeyConst( snode, "field" ) );
if (field && !fkey) {
@@ -2341,7 +2346,7 @@
// Look up the corresponding join column in the IDL.
// The link must be defined in the child table,
// and point to the right parent table.
- osrfHash* left_links = (osrfHash*) osrfHashGet( leftmeta, "links" );
+ osrfHash* left_links = left_info->links;
osrfHash* idl_link = (osrfHash*) osrfHashGet( left_links, fkey );
const char* reltype = NULL;
const char* other_class = NULL;
@@ -2367,7 +2372,7 @@
}
} else if (!field && !fkey) {
- osrfHash* left_links = (osrfHash*) osrfHashGet( leftmeta, "links" );
+ osrfHash* left_links = left_info->links;
// For each link defined for the left class:
// see if the link references the joined class
@@ -2392,6 +2397,7 @@
if (!field || !fkey) {
// Do another such search, with the classes reversed
+ //_links = oilsIDL_links( class );
// For each link defined for the joined class:
// see if the link references the left class
@@ -2448,7 +2454,7 @@
}
buffer_fadd(join_buf, " %s AS \"%s\" ON ( \"%s\".%s = \"%s\".%s",
- table, class, class, field, leftclass, fkey);
+ table, right_alias, right_alias, field, left_info->alias, fkey);
// Add any other join conditions as specified by "filter"
const jsonObject* filter = jsonObjectGetKeyConst( snode, "filter" );
@@ -2460,7 +2466,7 @@
buffer_add( join_buf, " AND " );
}
- char* jpred = searchWHERE( filter, idlClass, AND_OP_JOIN, NULL );
+ char* jpred = searchWHERE( filter, right_info, AND_OP_JOIN, NULL );
if( jpred ) {
OSRF_BUFFER_ADD_CHAR( join_buf, ' ' );
OSRF_BUFFER_ADD( join_buf, jpred );
@@ -2484,7 +2490,7 @@
// Recursively add a nested join, if one is present
const jsonObject* join_filter = jsonObjectGetKeyConst( snode, "join" );
if (join_filter) {
- char* jpred = searchJOIN( join_filter, idlClass );
+ char* jpred = searchJOIN( join_filter, right_info );
if( jpred ) {
OSRF_BUFFER_ADD_CHAR( join_buf, ' ' );
OSRF_BUFFER_ADD( join_buf, jpred );
@@ -2525,17 +2531,18 @@
*/
-static char* searchWHERE ( const jsonObject* search_hash, osrfHash* meta, int opjoin_type, osrfMethodContext* ctx ) {
+static char* searchWHERE ( const jsonObject* search_hash, const ClassInfo* class_info,
+ int opjoin_type, osrfMethodContext* ctx ) {
osrfLogDebug(
- OSRF_LOG_MARK,
- "%s: Entering searchWHERE; search_hash addr = %p, meta addr = %p, opjoin_type = %d, ctx addr = %p",
- MODULENAME,
- search_hash,
- meta,
- opjoin_type,
- ctx
- );
+ OSRF_LOG_MARK,
+ "%s: Entering searchWHERE; search_hash addr = %p, meta addr = %p, opjoin_type = %d, ctx addr = %p",
+ MODULENAME,
+ search_hash,
+ class_info->class_def,
+ opjoin_type,
+ ctx
+ );
growing_buffer* sql_buf = buffer_init(128);
@@ -2557,25 +2564,27 @@
}
while ( (node = jsonIteratorNext( search_itr )) ) {
- if (first) {
- first = 0;
- } else {
- if (opjoin_type == OR_OP_JOIN) buffer_add(sql_buf, " OR ");
- else buffer_add(sql_buf, " AND ");
- }
+ if (first) {
+ first = 0;
+ } else {
+ if (opjoin_type == OR_OP_JOIN)
+ buffer_add(sql_buf, " OR ");
+ else
+ buffer_add(sql_buf, " AND ");
+ }
- char* subpred = searchWHERE( node, meta, opjoin_type, ctx );
- if( subpred ) {
- buffer_fadd(sql_buf, "( %s )", subpred);
- free(subpred);
- } else {
+ char* subpred = searchWHERE( node, class_info, opjoin_type, ctx );
+ if( ! subpred ) {
jsonIteratorFree( search_itr );
buffer_free( sql_buf );
return NULL;
}
- }
- jsonIteratorFree(search_itr);
+ buffer_fadd(sql_buf, "( %s )", subpred);
+ free(subpred);
+ }
+ jsonIteratorFree(search_itr);
+
} else if ( search_hash->type == JSON_HASH ) {
osrfLogDebug(OSRF_LOG_MARK, "%s: In WHERE clause, condition type is JSON_HASH", MODULENAME);
jsonIterator* search_itr = jsonNewIterator( search_hash );
@@ -2592,159 +2601,164 @@
while ( (node = jsonIteratorNext( search_itr )) ) {
- if (first) {
- first = 0;
- } else {
- if (opjoin_type == OR_OP_JOIN) buffer_add(sql_buf, " OR ");
- else buffer_add(sql_buf, " AND ");
- }
+ if (first) {
+ first = 0;
+ } else {
+ if (opjoin_type == OR_OP_JOIN)
+ buffer_add(sql_buf, " OR ");
+ else
+ buffer_add(sql_buf, " AND ");
+ }
if ( '+' == search_itr->key[ 0 ] ) {
+
+ // This plus sign prefixes a class name or other table alias;
+ // make sure the table alias is in scope
+ ClassInfo* alias_info = search_all_alias( search_itr->key + 1 );
+ if( ! alias_info ) {
+ osrfLogError(
+ OSRF_LOG_MARK,
+ "%s: Invalid table alias \"%s\" in WHERE clause",
+ MODULENAME,
+ search_itr->key + 1
+ );
+ jsonIteratorFree( search_itr );
+ buffer_free( sql_buf );
+ return NULL;
+ }
+
if ( node->type == JSON_STRING ) {
- // Intended purpose; to allow reference to a Boolean column
-
- // Verify that the class alias is not empty
- if( '\0' == search_itr->key[ 1 ] ) {
- osrfLogError(
- OSRF_LOG_MARK,
- "%s: Table alias is empty",
- MODULENAME
- );
+ // It's the name of a column
+ buffer_fadd(sql_buf, " \"%s\".%s ", alias_info->alias, jsonObjectGetString( node ) );
+ } else {
+ // It's something more complicated
+ char* subpred = searchWHERE( node, alias_info, AND_OP_JOIN, ctx );
+ if( ! subpred ) {
jsonIteratorFree( search_itr );
buffer_free( sql_buf );
return NULL;
}
- // Verify that the string looks like an identifier.
- const char* subpred = jsonObjectGetString( node );
- if( ! is_identifier( subpred ) ) {
- osrfLogError(
- OSRF_LOG_MARK,
- "%s: Invalid boolean identifier in WHERE clause: \"%s\"",
- MODULENAME,
- subpred
- );
+ buffer_fadd(sql_buf, "( %s )", subpred);
+ free(subpred);
+ }
+ } else if ( '-' == search_itr->key[ 0 ] ) {
+ if ( !strcasecmp("-or",search_itr->key) ) {
+ char* subpred = searchWHERE( node, class_info, OR_OP_JOIN, ctx );
+ if( ! subpred ) {
jsonIteratorFree( search_itr );
buffer_free( sql_buf );
return NULL;
}
- buffer_fadd(sql_buf, " \"%s\".%s ", search_itr->key + 1, subpred);
- } else {
- char* subpred = searchWHERE( node, osrfHashGet( oilsIDL(), search_itr->key + 1 ), AND_OP_JOIN, ctx );
- if( subpred ) {
- buffer_fadd(sql_buf, "( %s )", subpred);
- free(subpred);
- } else {
+ buffer_fadd(sql_buf, "( %s )", subpred);
+ free( subpred );
+ } else if ( !strcasecmp("-and",search_itr->key) ) {
+ char* subpred = searchWHERE( node, class_info, AND_OP_JOIN, ctx );
+ if( ! subpred ) {
jsonIteratorFree( search_itr );
buffer_free( sql_buf );
return NULL;
}
- }
- } else if ( !strcasecmp("-or",search_itr->key) ) {
- char* subpred = searchWHERE( node, meta, OR_OP_JOIN, ctx );
- if( subpred ) {
+
buffer_fadd(sql_buf, "( %s )", subpred);
free( subpred );
- } else {
- buffer_free( sql_buf );
- return NULL;
- }
- } else if ( !strcasecmp("-and",search_itr->key) ) {
- char* subpred = searchWHERE( node, meta, AND_OP_JOIN, ctx );
- if( subpred ) {
- buffer_fadd(sql_buf, "( %s )", subpred);
- free( subpred );
- } else {
- buffer_free( sql_buf );
- return NULL;
- }
- } else if ( !strcasecmp("-not",search_itr->key) ) {
- char* subpred = searchWHERE( node, meta, AND_OP_JOIN, ctx );
- if( subpred ) {
+ } else if ( !strcasecmp("-not",search_itr->key) ) {
+ char* subpred = searchWHERE( node, class_info, AND_OP_JOIN, ctx );
+ if( ! subpred ) {
+ jsonIteratorFree( search_itr );
+ buffer_free( sql_buf );
+ return NULL;
+ }
+
buffer_fadd(sql_buf, " NOT ( %s )", subpred);
free( subpred );
- } else {
- buffer_free( sql_buf );
- return NULL;
- }
- } else if ( !strcasecmp("-exists",search_itr->key) ) {
- char* subpred = SELECT(
- ctx,
- jsonObjectGetKey( node, "select" ),
- jsonObjectGetKey( node, "from" ),
- jsonObjectGetKey( node, "where" ),
- jsonObjectGetKey( node, "having" ),
- jsonObjectGetKey( node, "order_by" ),
- jsonObjectGetKey( node, "limit" ),
- jsonObjectGetKey( node, "offset" ),
- SUBSELECT
- );
- pop_query_frame();
+ } else if ( !strcasecmp("-exists",search_itr->key) ) {
+ char* subpred = SELECT(
+ ctx,
+ jsonObjectGetKey( node, "select" ),
+ jsonObjectGetKey( node, "from" ),
+ jsonObjectGetKey( node, "where" ),
+ jsonObjectGetKey( node, "having" ),
+ jsonObjectGetKey( node, "order_by" ),
+ jsonObjectGetKey( node, "limit" ),
+ jsonObjectGetKey( node, "offset" ),
+ SUBSELECT
+ );
+ pop_query_frame();
- if( subpred ) {
+ if( ! subpred ) {
+ jsonIteratorFree( search_itr );
+ buffer_free( sql_buf );
+ return NULL;
+ }
+
buffer_fadd(sql_buf, "EXISTS ( %s )", subpred);
free(subpred);
- } else {
- buffer_free( sql_buf );
- return NULL;
- }
- } else if ( !strcasecmp("-not-exists",search_itr->key) ) {
- char* subpred = SELECT(
- ctx,
- jsonObjectGetKey( node, "select" ),
- jsonObjectGetKey( node, "from" ),
- jsonObjectGetKey( node, "where" ),
- jsonObjectGetKey( node, "having" ),
- jsonObjectGetKey( node, "order_by" ),
- jsonObjectGetKey( node, "limit" ),
- jsonObjectGetKey( node, "offset" ),
- SUBSELECT
- );
- pop_query_frame();
+ } else if ( !strcasecmp("-not-exists",search_itr->key) ) {
+ char* subpred = SELECT(
+ ctx,
+ jsonObjectGetKey( node, "select" ),
+ jsonObjectGetKey( node, "from" ),
+ jsonObjectGetKey( node, "where" ),
+ jsonObjectGetKey( node, "having" ),
+ jsonObjectGetKey( node, "order_by" ),
+ jsonObjectGetKey( node, "limit" ),
+ jsonObjectGetKey( node, "offset" ),
+ SUBSELECT
+ );
+ pop_query_frame();
- if( subpred ) {
+ if( ! subpred ) {
+ jsonIteratorFree( search_itr );
+ buffer_free( sql_buf );
+ return NULL;
+ }
+
buffer_fadd(sql_buf, "NOT EXISTS ( %s )", subpred);
free(subpred);
- } else {
+ } else { // Invalid "minus" operator
+ osrfLogError(
+ OSRF_LOG_MARK,
+ "%s: Invalid operator \"%s\" in WHERE clause",
+ MODULENAME,
+ search_itr->key
+ );
+ jsonIteratorFree( search_itr );
buffer_free( sql_buf );
return NULL;
}
- } else {
+ } else {
- char* class = osrfHashGet(meta, "classname");
- osrfHash* fields = osrfHashGet(meta, "fields");
- osrfHash* field = osrfHashGet( fields, search_itr->key );
+ const char* class = class_info->class_name;
+ osrfHash* fields = class_info->fields;
+ osrfHash* field = osrfHashGet( fields, search_itr->key );
-
- if (!field) {
- char* table = getSourceDefinition(meta);
- if( !table )
- table = strdup( "(?)" );
- osrfLogError(
- OSRF_LOG_MARK,
- "%s: Attempt to reference non-existent column \"%s\" on %s (%s)",
- MODULENAME,
- search_itr->key,
- table,
- class ? class : "?"
- );
- buffer_free(sql_buf);
- free(table);
+ if (!field) {
+ const char* table = class_info->source_def;
+ osrfLogError(
+ OSRF_LOG_MARK,
+ "%s: Attempt to reference non-existent column \"%s\" on %s (%s)",
+ MODULENAME,
+ search_itr->key,
+ table ? table : "?",
+ class ? class : "?"
+ );
jsonIteratorFree(search_itr);
+ buffer_free(sql_buf);
return NULL;
}
- char* subpred = searchPredicate( class, field, node, ctx );
- if( subpred ) {
- buffer_add( sql_buf, subpred );
- free(subpred);
- } else {
+ char* subpred = searchPredicate( class_info, field, node, ctx );
+ if( ! subpred ) {
buffer_free(sql_buf);
jsonIteratorFree(search_itr);
return NULL;
}
+
+ buffer_add( sql_buf, subpred );
+ free(subpred);
}
}
jsonIteratorFree(search_itr);
@@ -2795,7 +2809,7 @@
osrfLogDebug(OSRF_LOG_MARK, "cstore SELECT locale: %s", locale);
- // punt if there's no core class
+ // punt if there's no FROM clause
if (!join_hash || ( join_hash->type == JSON_HASH && !join_hash->size )) {
osrfLogError(
OSRF_LOG_MARK,
@@ -2840,7 +2854,7 @@
}
core_class = curr_query->core.class_name;
join_hash = snode;
-
+
jsonObject* extra = jsonIteratorNext( tmp_itr );
jsonIteratorFree( tmp_itr );
@@ -2909,7 +2923,7 @@
char* join_clause = NULL;
if( join_hash && ! from_function ) {
- join_clause = searchJOIN( join_hash, curr_query->core.class_def );
+ join_clause = searchJOIN( join_hash, &curr_query->core );
if( ! join_clause ) {
if (ctx)
osrfAppSessionStatus(
@@ -2957,9 +2971,6 @@
}
}
- // the query buffer
- growing_buffer* sql_buf = buffer_init(128);
-
// temp buffers for the SELECT list and GROUP BY clause
growing_buffer* select_buf = buffer_init(128);
growing_buffer* group_buf = buffer_init(128);
@@ -3027,7 +3038,6 @@
"Selected class not in FROM clause in JSON query"
);
jsonIteratorFree( selclass_itr );
- buffer_free( sql_buf );
buffer_free( select_buf );
buffer_free( group_buf );
if( defaultselhash ) jsonObjectFree( defaultselhash );
@@ -3035,7 +3045,7 @@
return NULL;
}
- // Capture some attributes of the current class
+ // Look up some attributes of the current class
osrfHash* idlClass = class_info->class_def;
osrfHash* class_field_set = class_info->fields;
const char* class_pkey = osrfHashGet( idlClass, "primarykey" );
@@ -3077,7 +3087,6 @@
);
jsonIteratorFree( select_itr );
jsonIteratorFree( selclass_itr );
- buffer_free( sql_buf );
buffer_free( select_buf );
buffer_free( group_buf );
if( defaultselhash ) jsonObjectFree( defaultselhash );
@@ -3102,7 +3111,6 @@
);
jsonIteratorFree( select_itr );
jsonIteratorFree( selclass_itr );
- buffer_free( sql_buf );
buffer_free( select_buf );
buffer_free( group_buf );
if( defaultselhash ) jsonObjectFree( defaultselhash );
@@ -3154,7 +3162,6 @@
);
jsonIteratorFree( select_itr );
jsonIteratorFree( selclass_itr );
- buffer_free( sql_buf );
buffer_free( select_buf );
buffer_free( group_buf );
if( defaultselhash ) jsonObjectFree( defaultselhash );
@@ -3179,7 +3186,6 @@
);
jsonIteratorFree( select_itr );
jsonIteratorFree( selclass_itr );
- buffer_free( sql_buf );
buffer_free( select_buf );
buffer_free( group_buf );
if( defaultselhash ) jsonObjectFree( defaultselhash );
@@ -3196,7 +3202,7 @@
}
if (jsonObjectGetKeyConst( selfield, "transform" )) {
- char* transform_str = searchFieldTransform(cname, field_def, selfield);
+ char* transform_str = searchFieldTransform(class_info->alias, field_def, selfield);
if( transform_str ) {
buffer_fadd(select_buf, " %s AS \"%s\"", transform_str, _alias);
free(transform_str);
@@ -3211,7 +3217,6 @@
);
jsonIteratorFree( select_itr );
jsonIteratorFree( selclass_itr );
- buffer_free( sql_buf );
buffer_free( select_buf );
buffer_free( group_buf );
if( defaultselhash ) jsonObjectFree( defaultselhash );
@@ -3256,7 +3261,6 @@
);
jsonIteratorFree( select_itr );
jsonIteratorFree( selclass_itr );
- buffer_free( sql_buf );
buffer_free( select_buf );
buffer_free( group_buf );
if( defaultselhash ) jsonObjectFree( defaultselhash );
@@ -3299,10 +3303,10 @@
OSRF_BUFFER_ADD_CHAR( group_buf, ',' );
}
- _column = searchFieldTransform(cname, field, selfield);
+ _column = searchFieldTransform(class_info->alias, field, selfield);
OSRF_BUFFER_ADD_CHAR(group_buf, ' ');
OSRF_BUFFER_ADD(group_buf, _column);
- _column = searchFieldTransform(cname, field, selfield);
+ _column = searchFieldTransform(class_info->alias, field, selfield);
*/
}
}
@@ -3333,7 +3337,6 @@
"Unable to identify table for core class"
);
free( col_list );
- buffer_free( sql_buf );
buffer_free( group_buf );
if( defaultselhash ) jsonObjectFree( defaultselhash );
free( join_clause );
@@ -3341,6 +3344,7 @@
}
// Put it all together
+ growing_buffer* sql_buf = buffer_init(128);
buffer_fadd(sql_buf, "SELECT %s FROM %s AS \"%s\" ", col_list, table, core_class );
free(col_list);
free(table);
@@ -3357,37 +3361,36 @@
if (!from_function) {
// Build a WHERE clause, if there is one
- if ( search_hash ) {
- buffer_add(sql_buf, " WHERE ");
+ if ( search_hash ) {
+ buffer_add(sql_buf, " WHERE ");
- // and it's on the WHERE clause
- char* pred = searchWHERE( search_hash, curr_query->core.class_def, AND_OP_JOIN, ctx );
-
- if (pred) {
- buffer_add(sql_buf, pred);
- free(pred);
- } else {
+ // and it's on the WHERE clause
+ char* pred = searchWHERE( search_hash, &curr_query->core, AND_OP_JOIN, ctx );
+ if ( ! pred ) {
if (ctx) {
- osrfAppSessionStatus(
- ctx->session,
- OSRF_STATUS_INTERNALSERVERERROR,
- "osrfMethodException",
- ctx->request,
- "Severe query error in WHERE predicate -- see error log for more details"
- );
- }
- buffer_free(group_buf);
- buffer_free(sql_buf);
- if (defaultselhash) jsonObjectFree(defaultselhash);
- return NULL;
+ osrfAppSessionStatus(
+ ctx->session,
+ OSRF_STATUS_INTERNALSERVERERROR,
+ "osrfMethodException",
+ ctx->request,
+ "Severe query error in WHERE predicate -- see error log for more details"
+ );
+ }
+ buffer_free(group_buf);
+ buffer_free(sql_buf);
+ if (defaultselhash) jsonObjectFree(defaultselhash);
+ return NULL;
}
+
+ buffer_add(sql_buf, pred);
+ free(pred);
}
// Build a HAVING clause, if there is one
if ( having_hash ) {
// and it's on the the WHERE clause
- having_buf = searchWHERE( having_hash, curr_query->core.class_def, AND_OP_JOIN, ctx );
+ having_buf = searchWHERE( having_hash, &curr_query->core, AND_OP_JOIN, ctx );
if( ! having_buf ) {
if (ctx) {
@@ -3438,7 +3441,7 @@
return NULL;
}
- const char* class =
+ const char* class_alias =
jsonObjectGetString( jsonObjectGetKeyConst( order_spec, "class" ) );
const char* field =
jsonObjectGetString( jsonObjectGetKeyConst( order_spec, "field" ) );
@@ -3448,7 +3451,7 @@
else
order_buf = buffer_init(128);
- if( !field || !class ) {
+ if( !field || !class_alias ) {
osrfLogError(OSRF_LOG_MARK,
"%s: Missing class or field name in field specification of ORDER BY clause",
MODULENAME );
@@ -3468,10 +3471,10 @@
return NULL;
}
- ClassInfo* order_class_info = search_alias( class );
+ ClassInfo* order_class_info = search_alias( class_alias );
if( ! order_class_info ) {
osrfLogError(OSRF_LOG_MARK, "%s: ORDER BY clause references class \"%s\" "
- "not in FROM clause", MODULENAME, class );
+ "not in FROM clause", MODULENAME, class_alias );
if( ctx )
osrfAppSessionStatus(
ctx->session,
@@ -3490,7 +3493,7 @@
osrfHash* field_def = osrfHashGet( order_class_info->fields, field );
if( !field_def ) {
osrfLogError(OSRF_LOG_MARK, "%s: Invalid field \"%s\".%s referenced in ORDER BY clause",
- MODULENAME, class, field );
+ MODULENAME, class_alias, field );
if( ctx )
osrfAppSessionStatus(
ctx->session,
@@ -3524,7 +3527,7 @@
}
if( jsonObjectGetKeyConst( order_spec, "transform" ) ) {
- char* transform_str = searchFieldTransform( class, field_def, order_spec );
+ char* transform_str = searchFieldTransform( class_alias, field_def, order_spec );
if( ! transform_str ) {
if( ctx )
osrfAppSessionStatus(
@@ -3546,7 +3549,7 @@
free( transform_str );
}
else
- buffer_fadd( order_buf, "\"%s\".%s", class, field );
+ buffer_fadd( order_buf, "\"%s\".%s", class_alias, field );
const char* direction =
jsonObjectGetString( jsonObjectGetKeyConst( order_spec, "direction" ) );
@@ -3558,7 +3561,7 @@
}
}
} else if( JSON_HASH == order_hash->type ) {
- // This hash is keyed on class name. Each class has either
+ // This hash is keyed on class alias. Each class has either
// an array of field names or a hash keyed on field name.
jsonIterator* class_itr = jsonNewIterator( order_hash );
while ( (snode = jsonIteratorNext( class_itr )) ) {
@@ -3994,7 +3997,7 @@
}
if ( join_hash ) {
- char* join_clause = searchJOIN( join_hash, meta );
+ char* join_clause = searchJOIN( join_hash, &curr_query->core );
OSRF_BUFFER_ADD_CHAR(sql_buf, ' ');
OSRF_BUFFER_ADD(sql_buf, join_clause);
free(join_clause);
@@ -4005,7 +4008,7 @@
OSRF_BUFFER_ADD(sql_buf, " WHERE ");
- char* pred = searchWHERE( search_hash, meta, AND_OP_JOIN, ctx );
+ char* pred = searchWHERE( search_hash, &curr_query->core, AND_OP_JOIN, ctx );
if (!pred) {
osrfAppSessionStatus(
ctx->session,
@@ -5445,7 +5448,9 @@
a pointer to the corresponding ClassInfo. Otherwise return NULL.
---------------------------------------------------------------------------*/
static ClassInfo* search_alias_in_frame( QueryFrame* frame, const char* target ) {
- if( ! frame || ! target ) return NULL;
+ if( ! frame || ! target ) {
+ return NULL;
+ }
ClassInfo* found_class = NULL;
@@ -5539,6 +5544,7 @@
static ClassInfo* search_all_alias( const char* target ) {
ClassInfo* found_class = NULL;
QueryFrame* curr_frame = curr_query;
+
while( curr_frame ) {
if(( found_class = search_alias_in_frame( curr_frame, target ) ))
break;
More information about the open-ils-commits
mailing list