Details
Description
Consider the following scenario:
Geoserver 1.6.x latest revision: WMS GetMap on a bbox with a CQL filter like (PROP1 = 'value2')
1. In GetMapResponse.java on line 161 the parsed CQL gets turned into a combined filter (cql + layer def filter)
2. In GetMapResponse.java around line 313, the combined filter gets added to the query for that layer, however the propertyNames for that query are left at null (= all properties?)
3. In StreamingRenderer on line 715, the definition query from the layer and the bbox query from the StreamingRenderer are mixed together using DataUtilities.mixQueries(). However DataUtilities.mixQueries interprets query.propertyNames = null as NO properties (as opposed to ALL properties as in point 2.) See line 1401 in DataUtilities.java.
4. This means that the query to the datastore only asks for the explicitly named properties (namely the geometry property from the bbox filter), but that the call to iterator.next() (StreamingRenderer.java line 1599) will probably fail as the datastore is returning a single attribute and the iterator is expecting at least two attributes.
I was able to fix this with the attached patch. It explicitly extracts all required attributes out of the combined filter and applies them to the query created in 2. I tried to run the tests but got other (extraneous?) failures in SVG and KML rendering that I'll look into.
Note that the comments around line 687 make me think that this new queryLayer() implementation might have exactly these sorts of issues. I think the discrepancy between how 4. treats the propertyNames = null and 2. treats propertyNames = null should be addressed at some level. This patch just makes things explicit while not solving that problem.
Query.getProperties() javadoc says:
The properties array is used to specify the attributes that should be selected for the return feature collection.
*ALL_NAMES: null
If no properties are specified (getProperties returns ALL_NAMES or null) then the full schema should be used (all attributes).
If getProperties returns an array of size 0, then the datasource should return features with no attributes, only their ids.
GetMapResponse line 161 is blank, which revision are you looking at? The code creating the query is at line 238 afaik
The evaluation at point 3 is not fully exact, the javadoc of mixQueries says that what you're seeing is to be expected.
In my opinion the renderer is working properly, but the datastore is broken. The renderer does not need any attribute specified in the filter, only the datastore does.
For example, if I attach a cql filter such as "STATE_FIPS = 56" against the topp:states shapefile using the population style, the renderer will end up
issuing a query that requires just the_geom, STATE_ABBR and PERSONS, with a filter that uses STATE_FIPS and the_geom.
The datastore will have to read the "STATE_FIPS" attribute to perform the query, but it won't return it because it has not been requested. Afaik the problem is
the opposite of what you diagnosed, that is, somewhere in the datastore more attributes than requested are returned... but it's hard to say since there
is no stack trace to look.