Skip to content

Commit

Permalink
Should fix MapServer#27. Few code cleaning in more
Browse files Browse the repository at this point in the history
  • Loading branch information
Olivier Courtin committed Nov 13, 2012
1 parent 0395be3 commit bd08bbe
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 109 deletions.
79 changes: 23 additions & 56 deletions src/fe/fe_comparison_ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,27 +41,23 @@ static buffer *fe_binary_comparison_op(ows * o, buffer * typename, filter_encodi
bool bool_type = false;
bool sensitive_case = true;

assert(o);
assert(typename);
assert(fe);
assert(n);
assert(o && typename && fe && n);

tmp = buffer_init();
name = buffer_init();

buffer_add_str(name, (char *) n->name);

/* by default, comparison is case sensitive */
/* By default, comparison is case sensitive */
matchcase = xmlGetProp(n, (xmlChar *) "matchCase");
if (matchcase && !strcmp((char *) matchcase, "false")) sensitive_case = false;
xmlFree(matchcase);

n = n->children;

/* jump to the next element if there are spaces */
while (n->type != XML_ELEMENT_NODE) n = n->next;
while (n->type != XML_ELEMENT_NODE) n = n->next; /* eat spaces */

/* if comparison isn't case sensitive, strings are passed in lower case */
/* If comparison are explicitly not case sensitive */
if (!sensitive_case) buffer_add_str(fe->sql, "lower(");

tmp = fe_expression(o, typename, fe, tmp, n);
Expand All @@ -73,8 +69,6 @@ static buffer *fe_binary_comparison_op(ows * o, buffer * typename, filter_encodi

buffer_copy(fe->sql, tmp);

/* if property is a boolean, xml content( 1 or 0) must be transformed
into FE->SQL syntax (true or false) */
if (buffer_cmp(name, "PropertyIsEqualTo") || buffer_cmp(name, "PropertyIsNotEqualTo")) {
/* remove brackets (if any) and quotation marks */
if (tmp->buf[0] == '(') {
Expand Down Expand Up @@ -137,8 +131,7 @@ static buffer *fe_binary_comparison_op(ows * o, buffer * typename, filter_encodi
return fe->sql;
}

/* if property is a boolean, xml content( 1 or 0) must be transformed
into fe->sql (true or false) */
/* If property is a boolean, XML content transformation */
if (bool_type) {
if (buffer_cmp(tmp, "'1'")) buffer_add_str(fe->sql, "'t'");
if (buffer_cmp(tmp, "'0'")) buffer_add_str(fe->sql, "'f'");
Expand All @@ -163,10 +156,7 @@ static buffer *fe_property_is_like(ows * o, buffer * typename, filter_encoding *
buffer *pg_string;
char *escaped;

assert(o);
assert(typename);
assert(fe);
assert(n);
assert(o && typename && fe && n);

wildcard = xmlGetProp(n, (xmlChar *) "wildCard");
singlechar = xmlGetProp(n, (xmlChar *) "singleChar");
Expand All @@ -179,29 +169,26 @@ static buffer *fe_property_is_like(ows * o, buffer * typename, filter_encoding *

n = n->children;

/* jump to the next element if there are spaces */
while (n->type != XML_ELEMENT_NODE) n = n->next;
while (n->type != XML_ELEMENT_NODE) n = n->next; /* eat spaces */

/* We need to cast as varchar at least for timestamp
PostgreSQL data type - cf (Ticket #10) */
/* We need to cast as varchar at least for timestamp PostgreSQL data type */
buffer_add_str(fe->sql, " CAST(\"");
fe->sql = fe_property_name(o, typename, fe, fe->sql, n, false, true);
buffer_add_str(fe->sql, "\" AS varchar) LIKE E");

n = n->next;

/* jump to the next element if there are spaces */
while (n->type != XML_ELEMENT_NODE) n = n->next;
while (n->type != XML_ELEMENT_NODE) n = n->next; /* eat spaces */

content = xmlNodeGetContent(n->children);

pg_string = buffer_init();
buffer_add_str(pg_string, (char *) content);

/* Replace the wildcard,singlechar and escapechar by Postgrefe->sql's */
/* Replace the wildcard,singlechar and escapechar */
if ((char *) wildcard && (char *) singlechar && (char *) escape) {
if (strlen((char *) escape)) pg_string = buffer_replace(pg_string, (char *) escape, "\\\\");
if (strlen((char *) wildcard)) pg_string = buffer_replace(pg_string, (char *) wildcard, "%");
if (strlen((char *) escape)) pg_string = buffer_replace(pg_string, (char *) escape, "\\\\");
if (strlen((char *) wildcard)) pg_string = buffer_replace(pg_string, (char *) wildcard, "%");
if (strlen((char *) singlechar)) pg_string = buffer_replace(pg_string, (char *) singlechar, "_");
} else fe->error_code = FE_ERROR_FILTER;

Expand All @@ -228,13 +215,10 @@ static buffer *fe_property_is_like(ows * o, buffer * typename, filter_encoding *
*/
static buffer *fe_property_is_null(ows * o, buffer * typename, filter_encoding * fe, xmlNodePtr n)
{
assert(o);
assert(typename);
assert(fe);
assert(n);
assert(o && typename && fe && n);

n = n->children;
while (n->type != XML_ELEMENT_NODE) n = n->next; /* Jump to next element if spaces */
while (n->type != XML_ELEMENT_NODE) n = n->next; /* eat spaces */
buffer_add(fe->sql, '"');
fe->sql = fe_property_name(o, typename, fe, fe->sql, n, false, true);
buffer_add_str(fe->sql, "\" isnull");
Expand All @@ -250,17 +234,13 @@ static buffer *fe_property_is_between(ows * o, buffer * typename, filter_encodin
{
buffer *tmp;

assert(o);
assert(typename);
assert(fe);
assert(n);
assert(o && typename && fe && n);

tmp = buffer_init();

n = n->children;

/* jump to the next element if there are spaces */
while (n->type != XML_ELEMENT_NODE) n = n->next;
while (n->type != XML_ELEMENT_NODE) n = n->next; /* eat spaces */

tmp = fe_expression(o, typename, fe, tmp, n);

Expand All @@ -271,8 +251,7 @@ static buffer *fe_property_is_between(ows * o, buffer * typename, filter_encodin

n = n->next;

/* jump to the next element if there are spaces */
while (n->type != XML_ELEMENT_NODE) n = n->next;
while (n->type != XML_ELEMENT_NODE) n = n->next; /* eat spaces */

tmp = fe_expression(o, typename, fe, tmp, n->children);

Expand All @@ -283,8 +262,7 @@ static buffer *fe_property_is_between(ows * o, buffer * typename, filter_encodin

n = n->next;

/* jump to the next element if there are spaces */
while (n->type != XML_ELEMENT_NODE) n = n->next;
while (n->type != XML_ELEMENT_NODE) n = n->next; /* eat spaces */

tmp = fe_expression(o, typename, fe, tmp, n->children);

Expand All @@ -302,8 +280,7 @@ bool fe_is_comparison_op(char *name)
{
assert(name);

/* case sensitive comparison because the gml standard specifies
strictly the name of the operator */
/* Case sensitive comparison as specified in GML standard */
if ( !strcmp(name, "PropertyIsEqualTo")
|| !strcmp(name, "PropertyIsNotEqualTo")
|| !strcmp(name, "PropertyIsLessThan")
Expand All @@ -320,19 +297,14 @@ bool fe_is_comparison_op(char *name)


/*
* Execute the matching function
* Warning : before calling this function,
* Check if n->name is a comparison operator with fe_is_comparison_op()
* Execute the matching comparison function
* CAUTION : call fe_is_comparison_op before calling this function,
*/
buffer *fe_comparison_op(ows * o, buffer * typename, filter_encoding * fe, xmlNodePtr n)
{
assert(o);
assert(typename);
assert(fe);
assert(n);
assert(o && typename && fe && n);

/* case sensitive comparison because the gml standard specifies
strictly the name of the operator */
/* Case sensitive comparison as specified in GML standard */
if ( !strcmp((char *) n->name, "PropertyIsEqualTo")
|| !strcmp((char *) n->name, "PropertyIsNotEqualTo")
|| !strcmp((char *) n->name, "PropertyIsLessThan")
Expand All @@ -351,8 +323,3 @@ buffer *fe_comparison_op(ows * o, buffer * typename, filter_encoding * fe, xmlNo

return fe->sql;
}


/*
* vim: expandtab sw=4 ts=4
*/
63 changes: 20 additions & 43 deletions src/fe/fe_filter.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ filter_encoding *filter_encoding_init()

fe->sql = buffer_init();
fe->error_code = FE_NO_ERROR;
fe->in_not = 0;
fe->in_not = false;
fe->is_numeric = false;

return fe;
}
Expand Down Expand Up @@ -120,10 +121,7 @@ buffer * fe_expression(ows * o, buffer * typename, filter_encoding * fe, buffer
char *escaped;
xmlChar *content;

assert(o);
assert(typename);
assert(fe);
assert(sql);
assert(o && typename && fe && sql);

if (!n) return sql;
if (!strcmp((char *) n->name, "Function")) return fe_function(o, typename, fe, sql, n);
Expand All @@ -139,7 +137,7 @@ buffer * fe_expression(ows * o, buffer * typename, filter_encoding * fe, buffer

content = xmlNodeGetContent(n);

/* Order is meaningfull (i.e Arithmetic, PropertyName, Literal) */
/* Order here is meaningfull (i.e Arithmetic then PropertyName then Literal) */
if (!strcmp((char *) n->name, "Add")) buffer_add_str(sql, " + ");
else if (!strcmp((char *) n->name, "Sub")) buffer_add_str(sql, " - ");
else if (!strcmp((char *) n->name, "Mul")) buffer_add_str(sql, " * ");
Expand All @@ -149,13 +147,13 @@ buffer * fe_expression(ows * o, buffer * typename, filter_encoding * fe, buffer
sql = fe_property_name(o, typename, fe, sql, n, false, true);
buffer_add(sql, '"');
} else if (!strcmp((char *) n->name, "Literal")) {
buffer_add_str(sql, "'");
if (!fe->is_numeric) buffer_add_str(sql, "'");
escaped = ows_psql_escape_string(o, (char *) content);
if (escaped) {
buffer_add_str(sql, escaped);
free(escaped);
}
buffer_add_str(sql, "'");
if (!fe->is_numeric) buffer_add_str(sql, "'");
} else if (n->type != XML_ELEMENT_NODE) {
sql = fe_expression(o, typename, fe, sql, n->next);
}
Expand All @@ -171,7 +169,7 @@ buffer * fe_expression(ows * o, buffer * typename, filter_encoding * fe, buffer
content = xmlNodeGetContent(n->children->next);

/* If children element is empty */
if (check_regexp((char *) content, "^$") == 1) buffer_add_str(sql, "''");
if (check_regexp((char *) content, "^$") == 1) buffer_add_str(sql, "''");
/* Close a bracket when there are not empty children elements */
else if (check_regexp((char *) content, " +") != 1) buffer_add_str(sql, ")");

Expand All @@ -189,9 +187,7 @@ buffer *fe_xpath_property_name(ows * o, buffer * typename, buffer * property)
{
buffer *prop_name;

assert(o);
assert(typename);
assert(property);
assert(o && typename && property);

if (check_regexp(property->buf, "\\*\\[position")) buffer_shift(property, 13); /* Remove '*[position()=' */
else buffer_shift(property, 2); /* Remove '*[' */
Expand All @@ -211,21 +207,16 @@ buffer *fe_xpath_property_name(ows * o, buffer * typename, buffer * property)
/*
* Check if propertyName is valid and return the appropriate string
*/
buffer *fe_property_name(ows * o, buffer * typename, filter_encoding * fe, buffer * sql, xmlNodePtr n,
bool check_geom_column, bool mandatory)
buffer *fe_property_name(ows * o, buffer * typename, filter_encoding * fe, buffer * sql, xmlNodePtr n, bool check_geom_column, bool mandatory)
{
xmlChar *content;
array *prop_table;
buffer *tmp, *layer_name;
list *l, *ll;

assert(o);
assert(typename);
assert(n);
assert(fe);
assert(sql);
assert(o && typename && n && fe && sql);

while (n->type != XML_ELEMENT_NODE) n = n->next; /* Jump to the next element if there are spaces */
while (n->type != XML_ELEMENT_NODE) n = n->next; /* eat spaces */

layer_name = ows_layer_prefix_to_uri(o->layers, typename);
prop_table = ows_psql_describe_table(o, layer_name);
Expand All @@ -251,8 +242,11 @@ buffer *fe_property_name(ows * o, buffer * typename, filter_encoding * fe, buffe
tmp = wfs_request_remove_prop_ns_prefix(o, tmp, ll);
list_free(ll);

if (array_is_key(prop_table, tmp->buf)) buffer_copy(sql, tmp);
else if (mandatory) fe->error_code = FE_ERROR_PROPERTYNAME;
if (array_is_key(prop_table, tmp->buf)) {
buffer_copy(sql, tmp);
fe->is_numeric = ows_psql_is_numeric(array_get(prop_table, tmp->buf));
if (buffer_cmp(tmp, "intProperty")) fe->is_numeric = true;
} else if (mandatory) fe->error_code = FE_ERROR_PROPERTYNAME;

if (mandatory && check_geom_column && !ows_psql_is_geometry_column(o, layer_name, tmp))
fe->error_code = FE_ERROR_GEOM_PROPERTYNAME;
Expand All @@ -275,10 +269,7 @@ buffer *fe_feature_id(ows * o, buffer * typename, filter_encoding * fe, xmlNodeP
xmlChar *fid = NULL;
buffer *buf_fid, *id_name = NULL;

assert(o);
assert(typename);
assert(n);
assert(fe);
assert(o && typename && n && fe);

for (feature_id = gid = false ; n ; n = n->next) {
if (n->type == XML_ELEMENT_NODE) {
Expand Down Expand Up @@ -366,10 +357,7 @@ filter_encoding *fe_filter(ows * o, filter_encoding * fe, buffer * typename, buf
xmlNodePtr n;
int ret = -1;

assert(o);
assert(fe);
assert(typename);
assert(xmlchar);
assert(o && fe && typename && xmlchar);

/* No validation if Filter came from KVP method
FIXME: really, but why ? */
Expand Down Expand Up @@ -437,10 +425,7 @@ buffer *fe_kvp_bbox(ows * o, wfs_request * wr, buffer * layer_name, ows_bbox * b
int srid = -1;
bool transform = false;

assert(o);
assert(wr);
assert(layer_name);
assert(bbox);
assert(o && wr && layer_name && bbox);

where = buffer_init();
geom = ows_psql_geometry_column(o, layer_name);
Expand Down Expand Up @@ -513,10 +498,7 @@ buffer *fe_kvp_featureid(ows * o, wfs_request * wr, buffer * layer_name, list *
list *fe;
list_node *ln;

assert(o);
assert(wr);
assert(layer_name);
assert(fid);
assert(o && wr && layer_name && fid);

where = buffer_init();

Expand All @@ -542,8 +524,3 @@ buffer *fe_kvp_featureid(ows * o, wfs_request * wr, buffer * layer_name, list *

return where;
}


/*
* vim: expandtab sw=4 ts=4
*/
5 changes: 0 additions & 5 deletions src/ows/ows.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,3 @@
#include "../ows_api.h"

#endif /* OWS_H */


/*
* vim: expandtab sw=4 ts=4
*/
18 changes: 18 additions & 0 deletions src/ows/ows_psql.c
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,24 @@ ows_version * ows_psql_postgis_version(ows *o)
}


/*
* TODO
*/
bool ows_psql_is_numeric(buffer * type)
{
assert(type);

if (buffer_cmp(type, "int2")) return true;
if (buffer_cmp(type, "int4")) return true;
if (buffer_cmp(type, "int8")) return true;
if (buffer_cmp(type, "float4")) return true;
if (buffer_cmp(type, "float8")) return true;
if (buffer_ncmp(type, "numeric", 7)) return true;

return false;
}


/*
* Convert a PostgreSql type to a valid
* OGC XMLSchema's type
Expand Down
Loading

0 comments on commit bd08bbe

Please sign in to comment.