 		    }
 		    
 		    // pathMapping is a nested object mapping property chains to WeavePath objects
-		    var obj:Object = listChainsAndNodes(pathMapping);
+		    var obj:Object = listChainsAndColumns(pathMapping);
 		    
 		    /* Perform the actual retrieval of records */
-		    var results:Array = ColumnUtils.joinColumns(obj.paths, dataType, true, keySet);
+		    var results:Array = ColumnUtils.joinColumns(obj.columns, dataType, true, keySetPath ? keySetPath.getObject() : null);
 		    return results[0]
 		        .map(this.qkeyToString)
 		        .map(function(key:String, iRow:int, a:Array):Object {

		            if (column is IAttributeColumn)
		            {
		                output.chains.push(prefix.concat(key));
		                output.paths.push(column);
		            }
		        }
		        else
		        {
		            listChainsAndNodes(item, prefix.concat(key), output);
		        }
		    }
		    return output;

		 * Recursively builds a mapping of property chains to WeavePath objects from a path specification as used in retrieveRecords
		 * @param obj A path spec object
		 * @param prefix A property chain prefix (optional)
		 * @param output Output object with "chains" and "columns" properties (optional)
		 * @return An object like {"chains": [], "columns": []}, where "chains" contains property name chains and "columns" contains IAttributeColumn objects
		 */
		protected function listChainsAndColumns(obj:Object, prefix:Array = null, output:Object = null):Object
		{
		    if (!prefix)
		        prefix = [];
		    if (!output)
		        output = {chains: [], columns: []};
		    
		    for (var key:String in obj)
		    {
