Skip to content
Permalink
Browse files

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.
  • Loading branch information
rouault committed Nov 22, 2019
1 parent 2607cb1 commit e0559baf8ccaf2532e5d47fa8a740f55ae1d531e
Showing with 26 additions and 4 deletions.
  1. +26 −4 mappostgis.c
@@ -4025,6 +4025,8 @@ int msPostGISLayerTranslateFilter(layerObj *layer, expressionObj *filter, char *
msFree(snippet);
msFree(stresc);
} else if(filter->type == MS_EXPRESSION) {
int ieq_expected = MS_FALSE;

if(msPostGISParseData(layer) != MS_SUCCESS) return MS_FAILURE;

if(layer->debug >= 2) msDebug("msPostGISLayerTranslateFilter. String: %s.\n", filter->string);
@@ -4039,7 +4041,9 @@ int msPostGISLayerTranslateFilter(layerObj *layer, expressionObj *filter, char *
*/
if(node->token == MS_TOKEN_BINDING_TIME) {
bindingToken = node->token;
} else if(node->token == MS_TOKEN_COMPARISON_EQ || node->token == MS_TOKEN_COMPARISON_NE ||
} else if(node->token == MS_TOKEN_COMPARISON_EQ ||
node->token == MS_TOKEN_COMPARISON_IEQ ||
node->token == MS_TOKEN_COMPARISON_NE ||
node->token == MS_TOKEN_COMPARISON_GT || node->token == MS_TOKEN_COMPARISON_GE ||
node->token == MS_TOKEN_COMPARISON_LT || node->token == MS_TOKEN_COMPARISON_LE ||
node->token == MS_TOKEN_COMPARISON_IN) {
@@ -4090,7 +4094,10 @@ int msPostGISLayerTranslateFilter(layerObj *layer, expressionObj *filter, char *

msFreeCharArray(strings, nstrings);
} else {
strtmpl = "'%s'";
if(comparisonToken == MS_TOKEN_COMPARISON_IEQ)
strtmpl = "lower('%s')";
else
strtmpl = "'%s'";
stresc = msPostGISEscapeSQLParam(layer, node->tokenval.strval);
snippet = (char *) msSmallMalloc(strlen(strtmpl) + strlen(stresc));
sprintf(snippet, strtmpl, stresc);
@@ -4138,7 +4145,11 @@ int msPostGISLayerTranslateFilter(layerObj *layer, expressionObj *filter, char *
case MS_TOKEN_BINDING_DOUBLE:
case MS_TOKEN_BINDING_INTEGER:
case MS_TOKEN_BINDING_STRING:
if(node->token == MS_TOKEN_BINDING_STRING || node->next->token == MS_TOKEN_COMPARISON_RE || node->next->token == MS_TOKEN_COMPARISON_IRE)
if (node->token == MS_TOKEN_BINDING_STRING && node->next->token == MS_TOKEN_COMPARISON_IEQ ) {
strtmpl = "lower(%s::text)";
ieq_expected = MS_TRUE;
}
else if(node->token == MS_TOKEN_BINDING_STRING || node->next->token == MS_TOKEN_COMPARISON_RE || node->next->token == MS_TOKEN_COMPARISON_IRE)
strtmpl = "%s::text"; /* explicit cast necessary for certain operators */
else
strtmpl = "%s";
@@ -4184,8 +4195,19 @@ int msPostGISLayerTranslateFilter(layerObj *layer, expressionObj *filter, char *
native_string = msStringConcatenate(native_string, msExpressionTokenToString(node->token));
break;

/* unsupported tokens */
case MS_TOKEN_COMPARISON_IEQ:
if( ieq_expected )
{
native_string = msStringConcatenate(native_string, "=");
ieq_expected = MS_FALSE;
}
else
{
goto cleanup;
}
break;

/* unsupported tokens */
case MS_TOKEN_COMPARISON_BEYOND:
case MS_TOKEN_FUNCTION_TOSTRING:
case MS_TOKEN_FUNCTION_ROUND:

0 comments on commit e0559ba

Please sign in to comment.
You can’t perform that action at this time.