diff --git a/pycsw/core/repository.py b/pycsw/core/repository.py
index 59093fb53..85fe53cbb 100644
--- a/pycsw/core/repository.py
+++ b/pycsw/core/repository.py
@@ -43,6 +43,7 @@
from sqlalchemy import create_engine, func, __version__, select
from sqlalchemy.exc import OperationalError
from sqlalchemy.sql import text
+from sqlalchemy.sql.elements import Grouping
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import create_session
@@ -418,7 +419,7 @@ def query(self, constraint, sortby=None, typenames=None,
if 'where' in constraint: # GetRecords with constraint
LOGGER.debug('constraint detected')
query = self.session.query(self.dataset).filter(
- text(constraint['where'])).params(self._create_values(constraint['values']))
+ _safe_text(constraint['where'])).params(self._create_values(constraint['values']))
else: # GetRecords sans constraint
LOGGER.debug('No constraint detected')
query = self.session.query(self.dataset)
@@ -512,14 +513,14 @@ def update(self, record=None, recprops=None, constraint=None):
self.session.rollback()
raise RuntimeError('property not found for XPath %s' % rpu['rp']['name'])
rows += self._get_repo_filter(self.session.query(self.dataset)).filter(
- text(constraint['where'])).params(self._create_values(constraint['values'])).update({
+ _safe_text(constraint['where'])).params(self._create_values(constraint['values'])).update({
getattr(self.dataset, rpu['rp']['dbcol']): rpu['value'],
'xml': func.update_xpath(str(self.context.namespaces),
getattr(self.dataset, self.context.md_core_model['mappings']['pycsw:XML']), str(rpu)),
}, synchronize_session='fetch')
# then update anytext tokens
rows2 += self._get_repo_filter(self.session.query(self.dataset)).filter(
- text(constraint['where'])).params(self._create_values(constraint['values'])).update({
+ _safe_text(constraint['where'])).params(self._create_values(constraint['values'])).update({
'anytext': func.get_anytext(getattr(
self.dataset, self.context.md_core_model['mappings']['pycsw:XML']))
}, synchronize_session='fetch')
@@ -539,7 +540,7 @@ def delete(self, constraint):
try:
self.session.begin()
rows = self._get_repo_filter(self.session.query(self.dataset)).filter(
- text(constraint['where'])).params(self._create_values(constraint['values']))
+ _safe_text(constraint['where'])).params(self._create_values(constraint['values']))
parentids = []
for row in rows: # get ids
@@ -579,9 +580,11 @@ def exists(self):
def _get_repo_filter(self, query):
''' Apply repository wide side filter / mask query '''
if self.filter is not None:
- return query.filter(text(self.filter))
+ return query.filter(_safe_text(self.filter))
return query
+def _safe_text(target):
+ return Grouping(text(target))
def create_custom_sql_functions(connection):
"""Register custom functions on the database connection."""
diff --git a/tests/functionaltests/suites/repofilter/expected/post_GetRecords-or1.xml b/tests/functionaltests/suites/repofilter/expected/post_GetRecords-or1.xml
new file mode 100644
index 000000000..2497d87f6
--- /dev/null
+++ b/tests/functionaltests/suites/repofilter/expected/post_GetRecords-or1.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/tests/functionaltests/suites/repofilter/expected/post_GetRecords-or2.xml b/tests/functionaltests/suites/repofilter/expected/post_GetRecords-or2.xml
new file mode 100644
index 000000000..3afb0eb08
--- /dev/null
+++ b/tests/functionaltests/suites/repofilter/expected/post_GetRecords-or2.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+ urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357
+ http://purl.org/dc/dcmitype/Dataset
+ Physiography-Landforms
+ FI-ES
+ Donec scelerisque pede ut nisl luctus accumsan. Quisque ultrices, lorem eget feugiat fringilla, lorem dui porttitor ante, cursus ultrices magna odio eu neque.
+
+
+ urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63
+ http://purl.org/dc/dcmitype/Dataset
+ Mauris sed neque
+ Vegetation-Cropland
+ Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit.
+ 2006-03-26
+
+ 47.595 -4.097
+ 51.217 0.889
+
+
+
+ urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc
+ http://purl.org/dc/dcmitype/Dataset
+ Ñunç elementum
+ Hydrography-Oceanographic
+ 2005-10-24
+
+ 44.792 -6.171
+ 51.126 -2.228
+
+
+
+
diff --git a/tests/functionaltests/suites/repofilter/post/GetRecords-or1.xml b/tests/functionaltests/suites/repofilter/post/GetRecords-or1.xml
new file mode 100644
index 000000000..6270c5e75
--- /dev/null
+++ b/tests/functionaltests/suites/repofilter/post/GetRecords-or1.xml
@@ -0,0 +1,24 @@
+
+
+
+ full
+
+
+
+
+ dc:type
+ http://purl.org/dc/dcmitype/Dataset
+
+
+ dc:type
+ http://purl.org/dc/dcmitype/Dataset
+
+
+ dc:type
+ http://purl.org/dc/dcmitype/Dataset
+
+
+
+
+
+
diff --git a/tests/functionaltests/suites/repofilter/post/GetRecords-or2.xml b/tests/functionaltests/suites/repofilter/post/GetRecords-or2.xml
new file mode 100644
index 000000000..5674af1de
--- /dev/null
+++ b/tests/functionaltests/suites/repofilter/post/GetRecords-or2.xml
@@ -0,0 +1,24 @@
+
+
+
+ full
+
+
+
+
+ dc:type
+ http://purl.org/dc/dcmitype/Dataset
+
+
+ dc:type
+ http://purl.org/dc/dcmitype/Dataset
+
+
+ dc:type
+ http://purl.org/dc/dcmitype/Dataset
+
+
+
+
+
+