Trying to affect rs_size indirectly, but:
authorLebbeous Fogle-Weekley <lebbeous@esilibrary.com>
Wed, 26 Oct 2011 18:04:54 +0000 (14:04 -0400)
committerLebbeous Fogle-Weekley <lebbeous@esilibrary.com>
Tue, 28 Feb 2012 16:40:09 +0000 (11:40 -0500)
things put into an osrfHash with osrfHashSet aren't immediately
available with osrfHashGetFmt !?!?

Signed-off-by: Lebbeous Fogle-Weekley <lebbeous@esilibrary.com>
Open-ILS/src/c-apps/oils_sql.c

index b002e61..af3ba0a 100644 (file)
@@ -119,7 +119,7 @@ static ClassInfo* add_joined_class( const char* alias, const char* classname );
 static void clear_query_stack( void );
 
 static const jsonObject* verifyUserPCRUD( osrfMethodContext* );
-static int verifyObjectPCRUD( osrfMethodContext*, osrfHash*, const jsonObject*, const int );
+static int verifyObjectPCRUD( osrfMethodContext*, osrfHash*, const jsonObject*, int );
 static const char* org_tree_root( osrfMethodContext* ctx );
 static jsonObject* single_hash( const char* key, const char* value );
 
@@ -1422,7 +1422,7 @@ static const jsonObject* verifyUserPCRUD( osrfMethodContext* ctx ) {
 
        The @a obj parameter points to a JSON_HASH of column values, keyed on column name.
 */
-static int verifyObjectPCRUD ( osrfMethodContext* ctx, osrfHash *class, const jsonObject* obj, const int rs_size ) {
+static int verifyObjectPCRUD ( osrfMethodContext* ctx, osrfHash *class, const jsonObject* obj, int rs_size ) {
 
        dbhandle = writehandle;
 
@@ -1430,6 +1430,14 @@ static int verifyObjectPCRUD ( osrfMethodContext* ctx, osrfHash *class, const js
        osrfHash* method_metadata = (osrfHash*) ctx->method->userData;
        const char* method_type = osrfHashGet( method_metadata, "methodtype" );
 
+       if (!rs_size) {
+               int *rs_size_from_hash = osrfHashGetFmt( (osrfHash *) ctx->session->userData, "req_%d_rs_size", ctx->request );
+               if (rs_size_from_hash) {
+                       rs_size = *rs_size_from_hash;
+                       osrfLogDebug(OSRF_LOG_MARK, "used rs_size from request-scoped hash: %d", rs_size);
+               }
+       }
+
        // Set fetch to 1 in all cases except for inserts, meaning that for local or foreign
        // contexts we will do another lookup of the current row, even if we already have a
        // previously fetched row image, because the row image in hand may not include the
@@ -1558,11 +1566,11 @@ static int verifyObjectPCRUD ( osrfMethodContext* ctx, osrfHash *class, const js
 
                if( fetch ) {
                        // Fetch the row so that we can look at the foreign key(s)
-                       osrfHashSet((osrfHash*) ctx->method->userData, "1", "inside_verify");
+                       osrfHashSet((osrfHash*) ctx->session->userData, "1", "inside_verify");
                        jsonObject* _tmp_params = single_hash( pkey, pkey_value );
                        jsonObject* _list = doFieldmapperSearch( ctx, class, _tmp_params, NULL, &err );
                        jsonObjectFree( _tmp_params );
-                       osrfHashSet((osrfHash*) ctx->method->userData, "0", "inside_verify");
+                       osrfHashSet((osrfHash*) ctx->session->userData, "0", "inside_verify");
 
                        param = jsonObjectExtractIndex( _list, 0 );
                        jsonObjectFree( _list );
@@ -1653,10 +1661,10 @@ static int verifyObjectPCRUD ( osrfMethodContext* ctx, osrfHash *class, const js
                                        // Look up the row to which the foreign key points
                                        jsonObject* _tmp_params = single_hash( foreign_pkey, foreign_pkey_value );
 
-                                       osrfHashSet((osrfHash*) ctx->method->userData, "1", "inside_verify");
+                                       osrfHashSet((osrfHash*) ctx->session->userData, "1", "inside_verify");
                                        jsonObject* _list = doFieldmapperSearch(
                                                ctx, osrfHashGet( oilsIDL(), class_name ), _tmp_params, NULL, &err );
-                                       osrfHashSet((osrfHash*) ctx->method->userData, "0", "inside_verify");
+                                       osrfHashSet((osrfHash*) ctx->session->userData, "0", "inside_verify");
 
                                        jsonObject* _fparam = NULL;
                                        if( _list && JSON_ARRAY == _list->type && _list->size > 0 )
@@ -5541,13 +5549,14 @@ static jsonObject* doFieldmapperSearch( osrfMethodContext* ctx, osrfHash* class_
 
        char* pkey = osrfHashGet( class_meta, "primarykey" );
 
-       char *inside_verify = osrfHashGet( (osrfHash*) ctx->method->userData, "inside_verify" );
+       char *inside_verify = osrfHashGet( (osrfHash*) ctx->session->userData, "inside_verify" );
        int need_to_verify = 1;
 
        if (inside_verify)
                need_to_verify = !atoi(inside_verify);
 
-       const jsonObject* _tmp;
+       int want_flesh = 0;     // we don't know yet
+       int flesh_depth = 0;
 
        // XXX This can be redundant with another instance of the same test that happens
        // within the functions that call doFieldmapperSearch(), but we have it here to
@@ -5598,6 +5607,33 @@ static jsonObject* doFieldmapperSearch( osrfMethodContext* ctx, osrfHash* class_
        jsonObject* res_list = jsonNewObjectType( JSON_ARRAY );
        jsonObject* row_obj = NULL;
 
+       // The following two steps are for verifyObjectPCRUD()'s benefit.
+       // 1. get the flesh depth
+       const jsonObject* _tmp = jsonObjectGetKeyConst( query_hash, "flesh" );
+       if( _tmp ) {
+               want_flesh = 1;
+               flesh_depth = (int) jsonObjectGetNumber( _tmp );
+               if( flesh_depth == -1 || flesh_depth > max_flesh_depth )
+                       flesh_depth = max_flesh_depth;
+       }
+
+       // 2. figure out one consistent rs_size for verifyObjectPCRUD to use
+       // over the whole life of this request.  This means if we've already set
+       // up a req_%d_rs_size, do nothing.
+       int *rs_size = osrfHashGetFmt( (osrfHash *) ctx->session->userData, "req_%d_rs_size", ctx->request );
+       if (!rs_size) { // pointer null, so value not set in hash
+               rs_size = (int *) safe_malloc( sizeof(int) );
+               unsigned long long result_count = dbi_result_get_numrows( result );
+               *rs_size = (int) result_count * (flesh_depth + 1);      // yes, we could lose some bits, but come on
+               osrfLogDebug( OSRF_LOG_MARK, "about to set rs_size to %d", *rs_size );
+               osrfHashSet( (osrfHash *) ctx->session->userData, rs_size, "req_%d_rs_size", ctx->request );
+               int *rs_size_test = osrfHashGetFmt( (osrfHash *) ctx->session->userData, "req_%d_rs_size", ctx->request );
+               if (rs_size_test)
+                       osrfLogDebug( OSRF_LOG_MARK, "immediately after set, get says rs_size is %d", *rs_size_test );
+               else
+                       osrfLogDebug( OSRF_LOG_MARK, "immediately after set, get says rs_size is NULL!" );
+       }
+
        if( dbi_result_first_row( result )) {
 
                // Convert each row to a JSON_ARRAY of column values, and enclose those objects
@@ -5613,7 +5649,7 @@ static jsonObject* doFieldmapperSearch( osrfMethodContext* ctx, osrfHash* class_
                                free( pkey_val );
                        } else {
                                if( !enforce_pcrud || !need_to_verify ||
-                                               verifyObjectPCRUD( ctx, class_meta, row_obj, 1 /* not at all sure about this 1 */ )) {
+                                               verifyObjectPCRUD( ctx, class_meta, row_obj, 0 /* means check user data for rs_size */ )) {
                                        osrfHashSet( dedup, pkey_val, pkey_val );
                                        jsonObjectPush( res_list, row_obj );
                                }
@@ -5633,243 +5669,235 @@ static jsonObject* doFieldmapperSearch( osrfMethodContext* ctx, osrfHash* class_
        // If we're asked to flesh, and there's anything to flesh, then flesh it
        // (formerly we would skip fleshing if in pcrud mode, but now we support
        // fleshing even in PCRUD).
-       if( res_list->size && query_hash ) {
-               _tmp = jsonObjectGetKeyConst( query_hash, "flesh" );
-               if( _tmp ) {
-                       // Get the flesh depth
-                       int flesh_depth = (int) jsonObjectGetNumber( _tmp );
-                       if( flesh_depth == -1 || flesh_depth > max_flesh_depth )
-                               flesh_depth = max_flesh_depth;
-
-                       // We need a non-zero flesh depth, and a list of fields to flesh
-                       const jsonObject* temp_blob = jsonObjectGetKeyConst( query_hash, "flesh_fields" );
-                       if( temp_blob && flesh_depth > 0 ) {
-
-                               jsonObject* flesh_blob = jsonObjectClone( temp_blob );
-                               const jsonObject* flesh_fields = jsonObjectGetKeyConst( flesh_blob, core_class );
-
-                               osrfStringArray* link_fields = NULL;
-                               osrfHash* links = osrfHashGet( class_meta, "links" );
-
-                               // Make an osrfStringArray of the names of fields to be fleshed
-                               if( flesh_fields ) {
-                                       if( flesh_fields->size == 1 ) {
-                                               const char* _t = jsonObjectGetString(
-                                                       jsonObjectGetIndex( flesh_fields, 0 ) );
-                                               if( !strcmp( _t, "*" ))
-                                                       link_fields = osrfHashKeys( links );
-                                       }
+       if( res_list->size && query_hash && want_flesh ) {
+               // We need a non-zero flesh depth, and a list of fields to flesh
+               const jsonObject* temp_blob = jsonObjectGetKeyConst( query_hash, "flesh_fields" );
+               if( temp_blob && flesh_depth > 0 ) {
+
+                       jsonObject* flesh_blob = jsonObjectClone( temp_blob );
+                       const jsonObject* flesh_fields = jsonObjectGetKeyConst( flesh_blob, core_class );
+
+                       osrfStringArray* link_fields = NULL;
+                       osrfHash* links = osrfHashGet( class_meta, "links" );
+
+                       // Make an osrfStringArray of the names of fields to be fleshed
+                       if( flesh_fields ) {
+                               if( flesh_fields->size == 1 ) {
+                                       const char* _t = jsonObjectGetString(
+                                               jsonObjectGetIndex( flesh_fields, 0 ) );
+                                       if( !strcmp( _t, "*" ))
+                                               link_fields = osrfHashKeys( links );
+                               }
 
-                                       if( !link_fields ) {
-                                               jsonObject* _f;
-                                               link_fields = osrfNewStringArray( 1 );
-                                               jsonIterator* _i = jsonNewIterator( flesh_fields );
-                                               while ((_f = jsonIteratorNext( _i ))) {
-                                                       osrfStringArrayAdd( link_fields, jsonObjectGetString( _f ) );
-                                               }
-                                               jsonIteratorFree( _i );
+                               if( !link_fields ) {
+                                       jsonObject* _f;
+                                       link_fields = osrfNewStringArray( 1 );
+                                       jsonIterator* _i = jsonNewIterator( flesh_fields );
+                                       while ((_f = jsonIteratorNext( _i ))) {
+                                               osrfStringArrayAdd( link_fields, jsonObjectGetString( _f ) );
                                        }
+                                       jsonIteratorFree( _i );
                                }
+                       }
 
-                               osrfHash* fields = osrfHashGet( class_meta, "fields" );
-
-                               // Iterate over the JSON_ARRAY of rows
-                               jsonObject* cur;
-                               unsigned long res_idx = 0;
-                               while((cur = jsonObjectGetIndex( res_list, res_idx++ ) )) {
+                       osrfHash* fields = osrfHashGet( class_meta, "fields" );
 
-                                       int i = 0;
-                                       const char* link_field;
+                       // Iterate over the JSON_ARRAY of rows
+                       jsonObject* cur;
+                       unsigned long res_idx = 0;
+                       while((cur = jsonObjectGetIndex( res_list, res_idx++ ) )) {
 
-                                       // Iterate over the list of fleshable fields
-                                       while( (link_field = osrfStringArrayGetString(link_fields, i++)) ) {
+                               int i = 0;
+                               const char* link_field;
 
-                                               osrfLogDebug( OSRF_LOG_MARK, "Starting to flesh %s", link_field );
+                               // Iterate over the list of fleshable fields
+                               while( (link_field = osrfStringArrayGetString(link_fields, i++)) ) {
 
-                                               osrfHash* kid_link = osrfHashGet( links, link_field );
-                                               if( !kid_link )
-                                                       continue;     // Not a link field; skip it
+                                       osrfLogDebug( OSRF_LOG_MARK, "Starting to flesh %s", link_field );
 
-                                               osrfHash* field = osrfHashGet( fields, link_field );
-                                               if( !field )
-                                                       continue;     // Not a field at all; skip it (IDL is ill-formed)
+                                       osrfHash* kid_link = osrfHashGet( links, link_field );
+                                       if( !kid_link )
+                                               continue;     // Not a link field; skip it
 
-                                               osrfHash* kid_idl = osrfHashGet( oilsIDL(),
-                                                       osrfHashGet( kid_link, "class" ));
-                                               if( !kid_idl )
-                                                       continue;   // The class it links to doesn't exist; skip it
+                                       osrfHash* field = osrfHashGet( fields, link_field );
+                                       if( !field )
+                                               continue;     // Not a field at all; skip it (IDL is ill-formed)
 
-                                               const char* reltype = osrfHashGet( kid_link, "reltype" );
-                                               if( !reltype )
-                                                       continue;   // No reltype; skip it (IDL is ill-formed)
+                                       osrfHash* kid_idl = osrfHashGet( oilsIDL(),
+                                               osrfHashGet( kid_link, "class" ));
+                                       if( !kid_idl )
+                                               continue;   // The class it links to doesn't exist; skip it
 
-                                               osrfHash* value_field = field;
+                                       const char* reltype = osrfHashGet( kid_link, "reltype" );
+                                       if( !reltype )
+                                               continue;   // No reltype; skip it (IDL is ill-formed)
 
-                                               if(    !strcmp( reltype, "has_many" )
-                                                       || !strcmp( reltype, "might_have" ) ) { // has_many or might_have
-                                                       value_field = osrfHashGet(
-                                                               fields, osrfHashGet( class_meta, "primarykey" ) );
-                                               }
+                                       osrfHash* value_field = field;
 
-                                               osrfStringArray* link_map = osrfHashGet( kid_link, "map" );
+                                       if(    !strcmp( reltype, "has_many" )
+                                               || !strcmp( reltype, "might_have" ) ) { // has_many or might_have
+                                               value_field = osrfHashGet(
+                                                       fields, osrfHashGet( class_meta, "primarykey" ) );
+                                       }
 
-                                               if( link_map->size > 0 ) {
-                                                       jsonObject* _kid_key = jsonNewObjectType( JSON_ARRAY );
-                                                       jsonObjectPush(
-                                                               _kid_key,
-                                                               jsonNewObject( osrfStringArrayGetString( link_map, 0 ) )
-                                                       );
+                                       osrfStringArray* link_map = osrfHashGet( kid_link, "map" );
 
-                                                       jsonObjectSetKey(
-                                                               flesh_blob,
-                                                               osrfHashGet( kid_link, "class" ),
-                                                               _kid_key
-                                                       );
-                                               };
+                                       if( link_map->size > 0 ) {
+                                               jsonObject* _kid_key = jsonNewObjectType( JSON_ARRAY );
+                                               jsonObjectPush(
+                                                       _kid_key,
+                                                       jsonNewObject( osrfStringArrayGetString( link_map, 0 ) )
+                                               );
 
-                                               osrfLogDebug(
-                                                       OSRF_LOG_MARK,
-                                                       "Link field: %s, remote class: %s, fkey: %s, reltype: %s",
-                                                       osrfHashGet( kid_link, "field" ),
+                                               jsonObjectSetKey(
+                                                       flesh_blob,
                                                        osrfHashGet( kid_link, "class" ),
-                                                       osrfHashGet( kid_link, "key" ),
-                                                       osrfHashGet( kid_link, "reltype" )
+                                                       _kid_key
                                                );
+                                       };
 
-                                               const char* search_key = jsonObjectGetString(
-                                                       jsonObjectGetIndex( cur,
-                                                               atoi( osrfHashGet( value_field, "array_position" ) )
-                                                       )
-                                               );
+                                       osrfLogDebug(
+                                               OSRF_LOG_MARK,
+                                               "Link field: %s, remote class: %s, fkey: %s, reltype: %s",
+                                               osrfHashGet( kid_link, "field" ),
+                                               osrfHashGet( kid_link, "class" ),
+                                               osrfHashGet( kid_link, "key" ),
+                                               osrfHashGet( kid_link, "reltype" )
+                                       );
 
-                                               if( !search_key ) {
-                                                       osrfLogDebug( OSRF_LOG_MARK, "Nothing to search for!" );
-                                                       continue;
-                                               }
+                                       const char* search_key = jsonObjectGetString(
+                                               jsonObjectGetIndex( cur,
+                                                       atoi( osrfHashGet( value_field, "array_position" ) )
+                                               )
+                                       );
 
-                                               osrfLogDebug( OSRF_LOG_MARK, "Creating param objects..." );
+                                       if( !search_key ) {
+                                               osrfLogDebug( OSRF_LOG_MARK, "Nothing to search for!" );
+                                               continue;
+                                       }
 
-                                               // construct WHERE clause
-                                               jsonObject* where_clause  = jsonNewObjectType( JSON_HASH );
-                                               jsonObjectSetKey(
-                                                       where_clause,
-                                                       osrfHashGet( kid_link, "key" ),
-                                                       jsonNewObject( search_key )
-                                               );
+                                       osrfLogDebug( OSRF_LOG_MARK, "Creating param objects..." );
+
+                                       // construct WHERE clause
+                                       jsonObject* where_clause  = jsonNewObjectType( JSON_HASH );
+                                       jsonObjectSetKey(
+                                               where_clause,
+                                               osrfHashGet( kid_link, "key" ),
+                                               jsonNewObject( search_key )
+                                       );
 
-                                               // construct the rest of the query, mostly
-                                               // by copying pieces of the previous level of query
-                                               jsonObject* rest_of_query = jsonNewObjectType( JSON_HASH );
-                                               jsonObjectSetKey( rest_of_query, "flesh",
-                                                       jsonNewNumberObject( flesh_depth - 1 + link_map->size )
+                                       // construct the rest of the query, mostly
+                                       // by copying pieces of the previous level of query
+                                       jsonObject* rest_of_query = jsonNewObjectType( JSON_HASH );
+                                       jsonObjectSetKey( rest_of_query, "flesh",
+                                               jsonNewNumberObject( flesh_depth - 1 + link_map->size )
+                                       );
+
+                                       if( flesh_blob )
+                                               jsonObjectSetKey( rest_of_query, "flesh_fields",
+                                                       jsonObjectClone( flesh_blob ));
+
+                                       if( jsonObjectGetKeyConst( query_hash, "order_by" )) {
+                                               jsonObjectSetKey( rest_of_query, "order_by",
+                                                       jsonObjectClone( jsonObjectGetKeyConst( query_hash, "order_by" ))
                                                );
+                                       }
 
-                                               if( flesh_blob )
-                                                       jsonObjectSetKey( rest_of_query, "flesh_fields",
-                                                               jsonObjectClone( flesh_blob ));
+                                       if( jsonObjectGetKeyConst( query_hash, "select" )) {
+                                               jsonObjectSetKey( rest_of_query, "select",
+                                                       jsonObjectClone( jsonObjectGetKeyConst( query_hash, "select" ))
+                                               );
+                                       }
 
-                                               if( jsonObjectGetKeyConst( query_hash, "order_by" )) {
-                                                       jsonObjectSetKey( rest_of_query, "order_by",
-                                                               jsonObjectClone( jsonObjectGetKeyConst( query_hash, "order_by" ))
-                                                       );
-                                               }
+                                       // do the query, recursively, to expand the fleshable field
+                                       jsonObject* kids = doFieldmapperSearch( ctx, kid_idl,
+                                               where_clause, rest_of_query, err );
 
-                                               if( jsonObjectGetKeyConst( query_hash, "select" )) {
-                                                       jsonObjectSetKey( rest_of_query, "select",
-                                                               jsonObjectClone( jsonObjectGetKeyConst( query_hash, "select" ))
-                                                       );
-                                               }
+                                       jsonObjectFree( where_clause );
+                                       jsonObjectFree( rest_of_query );
 
-                                               // do the query, recursively, to expand the fleshable field
-                                               jsonObject* kids = doFieldmapperSearch( ctx, kid_idl,
-                                                       where_clause, rest_of_query, err );
+                                       if( *err ) {
+                                               osrfStringArrayFree( link_fields );
+                                               jsonObjectFree( res_list );
+                                               jsonObjectFree( flesh_blob );
+                                               return NULL;
+                                       }
 
-                                               jsonObjectFree( where_clause );
-                                               jsonObjectFree( rest_of_query );
+                                       osrfLogDebug( OSRF_LOG_MARK, "Search for %s return %d linked objects",
+                                               osrfHashGet( kid_link, "class" ), kids->size );
 
-                                               if( *err ) {
-                                                       osrfStringArrayFree( link_fields );
-                                                       jsonObjectFree( res_list );
-                                                       jsonObjectFree( flesh_blob );
-                                                       return NULL;
-                                               }
+                                       // Traverse the result set
+                                       jsonObject* X = NULL;
+                                       if( link_map->size > 0 && kids->size > 0 ) {
+                                               X = kids;
+                                               kids = jsonNewObjectType( JSON_ARRAY );
 
-                                               osrfLogDebug( OSRF_LOG_MARK, "Search for %s return %d linked objects",
-                                                       osrfHashGet( kid_link, "class" ), kids->size );
-
-                                               // Traverse the result set
-                                               jsonObject* X = NULL;
-                                               if( link_map->size > 0 && kids->size > 0 ) {
-                                                       X = kids;
-                                                       kids = jsonNewObjectType( JSON_ARRAY );
-
-                                                       jsonObject* _k_node;
-                                                       unsigned long res_idx = 0;
-                                                       while((_k_node = jsonObjectGetIndex( X, res_idx++ ) )) {
-                                                               jsonObjectPush(
-                                                                       kids,
-                                                                       jsonObjectClone(
-                                                                               jsonObjectGetIndex(
-                                                                                       _k_node,
-                                                                                       (unsigned long) atoi(
+                                               jsonObject* _k_node;
+                                               unsigned long res_idx = 0;
+                                               while((_k_node = jsonObjectGetIndex( X, res_idx++ ) )) {
+                                                       jsonObjectPush(
+                                                               kids,
+                                                               jsonObjectClone(
+                                                                       jsonObjectGetIndex(
+                                                                               _k_node,
+                                                                               (unsigned long) atoi(
+                                                                                       osrfHashGet(
                                                                                                osrfHashGet(
                                                                                                        osrfHashGet(
                                                                                                                osrfHashGet(
-                                                                                                                       osrfHashGet(
-                                                                                                                               oilsIDL(),
-                                                                                                                               osrfHashGet( kid_link, "class" )
-                                                                                                                       ),
-                                                                                                                       "fields"
+                                                                                                                       oilsIDL(),
+                                                                                                                       osrfHashGet( kid_link, "class" )
                                                                                                                ),
-                                                                                                               osrfStringArrayGetString( link_map, 0 )
+                                                                                                               "fields"
                                                                                                        ),
-                                                                                                       "array_position"
-                                                                                               )
+                                                                                                       osrfStringArrayGetString( link_map, 0 )
+                                                                                               ),
+                                                                                               "array_position"
                                                                                        )
                                                                                )
                                                                        )
-                                                               );
-                                                       } // end while loop traversing X
-                                               }
-
-                                               if(    !strcmp( osrfHashGet( kid_link, "reltype" ), "has_a" )
-                                                       || !strcmp( osrfHashGet( kid_link, "reltype" ), "might_have" )) {
-                                                       osrfLogDebug(OSRF_LOG_MARK, "Storing fleshed objects in %s",
-                                                               osrfHashGet( kid_link, "field" ));
-                                                       jsonObjectSetIndex(
-                                                               cur,
-                                                               (unsigned long) atoi( osrfHashGet( field, "array_position" ) ),
-                                                               jsonObjectClone( jsonObjectGetIndex( kids, 0 ))
+                                                               )
                                                        );
-                                               }
+                                               } // end while loop traversing X
+                                       }
 
-                                               if( !strcmp( osrfHashGet( kid_link, "reltype" ), "has_many" )) {
-                                                       // has_many
-                                                       osrfLogDebug( OSRF_LOG_MARK, "Storing fleshed objects in %s",
-                                                               osrfHashGet( kid_link, "field" ) );
-                                                       jsonObjectSetIndex(
-                                                               cur,
-                                                               (unsigned long) atoi( osrfHashGet( field, "array_position" ) ),
-                                                               jsonObjectClone( kids )
-                                                       );
-                                               }
+                                       if(    !strcmp( osrfHashGet( kid_link, "reltype" ), "has_a" )
+                                               || !strcmp( osrfHashGet( kid_link, "reltype" ), "might_have" )) {
+                                               osrfLogDebug(OSRF_LOG_MARK, "Storing fleshed objects in %s",
+                                                       osrfHashGet( kid_link, "field" ));
+                                               jsonObjectSetIndex(
+                                                       cur,
+                                                       (unsigned long) atoi( osrfHashGet( field, "array_position" ) ),
+                                                       jsonObjectClone( jsonObjectGetIndex( kids, 0 ))
+                                               );
+                                       }
 
-                                               if( X ) {
-                                                       jsonObjectFree( kids );
-                                                       kids = X;
-                                               }
+                                       if( !strcmp( osrfHashGet( kid_link, "reltype" ), "has_many" )) {
+                                               // has_many
+                                               osrfLogDebug( OSRF_LOG_MARK, "Storing fleshed objects in %s",
+                                                       osrfHashGet( kid_link, "field" ) );
+                                               jsonObjectSetIndex(
+                                                       cur,
+                                                       (unsigned long) atoi( osrfHashGet( field, "array_position" ) ),
+                                                       jsonObjectClone( kids )
+                                               );
+                                       }
 
+                                       if( X ) {
                                                jsonObjectFree( kids );
+                                               kids = X;
+                                       }
 
-                                               osrfLogDebug( OSRF_LOG_MARK, "Fleshing of %s complete",
-                                                       osrfHashGet( kid_link, "field" ) );
-                                               osrfLogDebug( OSRF_LOG_MARK, "%s", jsonObjectToJSON( cur ));
+                                       jsonObjectFree( kids );
 
-                                       } // end while loop traversing list of fleshable fields
-                               } // end while loop traversing res_list
-                               jsonObjectFree( flesh_blob );
-                               osrfStringArrayFree( link_fields );
-                       }
+                                       osrfLogDebug( OSRF_LOG_MARK, "Fleshing of %s complete",
+                                               osrfHashGet( kid_link, "field" ) );
+                                       osrfLogDebug( OSRF_LOG_MARK, "%s", jsonObjectToJSON( cur ));
+
+                               } // end while loop traversing list of fleshable fields
+                       } // end while loop traversing res_list
+                       jsonObjectFree( flesh_blob );
+                       osrfStringArrayFree( link_fields );
                }
        }