Skip to content

Commit 7f3cebc

Browse files
committed
PostGIS backend: translate insensitive equality comparison as Postgre SQL lower(foo::text) = lower('bar').
Fixes a performance issue dating from 7.0 The wfs_filter_postgis.map wfs_filter_postgis_property_is_equal_case_insensitive test case exercices this code path.
1 parent 0af5737 commit 7f3cebc

File tree

1 file changed

+26
-4
lines changed

1 file changed

+26
-4
lines changed

mappostgis.c

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4036,6 +4036,8 @@ int msPostGISLayerTranslateFilter(layerObj *layer, expressionObj *filter, char *
40364036
msFree(snippet);
40374037
msFree(stresc);
40384038
} else if(filter->type == MS_EXPRESSION) {
4039+
int ieq_expected = MS_FALSE;
4040+
40394041
if(msPostGISParseData(layer) != MS_SUCCESS) return MS_FAILURE;
40404042

40414043
if(layer->debug >= 2) msDebug("msPostGISLayerTranslateFilter. String: %s.\n", filter->string);
@@ -4050,7 +4052,9 @@ int msPostGISLayerTranslateFilter(layerObj *layer, expressionObj *filter, char *
40504052
*/
40514053
if(node->token == MS_TOKEN_BINDING_TIME) {
40524054
bindingToken = node->token;
4053-
} else if(node->token == MS_TOKEN_COMPARISON_EQ || node->token == MS_TOKEN_COMPARISON_NE ||
4055+
} else if(node->token == MS_TOKEN_COMPARISON_EQ ||
4056+
node->token == MS_TOKEN_COMPARISON_IEQ ||
4057+
node->token == MS_TOKEN_COMPARISON_NE ||
40544058
node->token == MS_TOKEN_COMPARISON_GT || node->token == MS_TOKEN_COMPARISON_GE ||
40554059
node->token == MS_TOKEN_COMPARISON_LT || node->token == MS_TOKEN_COMPARISON_LE ||
40564060
node->token == MS_TOKEN_COMPARISON_IN) {
@@ -4101,7 +4105,10 @@ int msPostGISLayerTranslateFilter(layerObj *layer, expressionObj *filter, char *
41014105

41024106
msFreeCharArray(strings, nstrings);
41034107
} else {
4104-
strtmpl = "'%s'";
4108+
if(comparisonToken == MS_TOKEN_COMPARISON_IEQ)
4109+
strtmpl = "lower('%s')";
4110+
else
4111+
strtmpl = "'%s'";
41054112
stresc = msPostGISEscapeSQLParam(layer, node->tokenval.strval);
41064113
snippet = (char *) msSmallMalloc(strlen(strtmpl) + strlen(stresc));
41074114
sprintf(snippet, strtmpl, stresc);
@@ -4149,7 +4156,11 @@ int msPostGISLayerTranslateFilter(layerObj *layer, expressionObj *filter, char *
41494156
case MS_TOKEN_BINDING_DOUBLE:
41504157
case MS_TOKEN_BINDING_INTEGER:
41514158
case MS_TOKEN_BINDING_STRING:
4152-
if(node->token == MS_TOKEN_BINDING_STRING || node->next->token == MS_TOKEN_COMPARISON_RE || node->next->token == MS_TOKEN_COMPARISON_IRE)
4159+
if (node->token == MS_TOKEN_BINDING_STRING && node->next->token == MS_TOKEN_COMPARISON_IEQ ) {
4160+
strtmpl = "lower(%s::text)";
4161+
ieq_expected = MS_TRUE;
4162+
}
4163+
else if(node->token == MS_TOKEN_BINDING_STRING || node->next->token == MS_TOKEN_COMPARISON_RE || node->next->token == MS_TOKEN_COMPARISON_IRE)
41534164
strtmpl = "%s::text"; /* explicit cast necessary for certain operators */
41544165
else
41554166
strtmpl = "%s";
@@ -4195,8 +4206,19 @@ int msPostGISLayerTranslateFilter(layerObj *layer, expressionObj *filter, char *
41954206
native_string = msStringConcatenate(native_string, msExpressionTokenToString(node->token));
41964207
break;
41974208

4198-
/* unsupported tokens */
41994209
case MS_TOKEN_COMPARISON_IEQ:
4210+
if( ieq_expected )
4211+
{
4212+
native_string = msStringConcatenate(native_string, "=");
4213+
ieq_expected = MS_FALSE;
4214+
}
4215+
else
4216+
{
4217+
goto cleanup;
4218+
}
4219+
break;
4220+
4221+
/* unsupported tokens */
42004222
case MS_TOKEN_COMPARISON_BEYOND:
42014223
case MS_TOKEN_FUNCTION_TOSTRING:
42024224
case MS_TOKEN_FUNCTION_ROUND:

0 commit comments

Comments
 (0)