From cbc9e328a88eb86366f21ac77ce196d569766d3a Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Mon, 26 Jul 2021 16:14:40 +0000 Subject: [PATCH 1/2] Allow SQL functions to not cause errors from Python ICAT - An example query for this use case is: `SELECT o FROM Investigation o WHERE UPPER(o.title) like '%toMAto%'` --- icat/query.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/icat/query.py b/icat/query.py index 9286de0d..0eacc9ec 100644 --- a/icat/query.py +++ b/icat/query.py @@ -373,7 +373,8 @@ def addConditions(self, conditions): """ if conditions: for a in conditions.keys(): - for (pattr, attrInfo, rclass) in self._attrpath(a): + a_name = (a.split("("))[1].split(")")[0] + for (pattr, attrInfo, rclass) in self._attrpath(a_name): pass if a in self.conditions: conds = [] @@ -468,7 +469,10 @@ def __str__(self): if self.conditions: conds = [] for a in sorted(self.conditions.keys()): - attr = self._dosubst(a, subst, False) + sql_function_name = a.split("(")[0] + a_name = (a.split("("))[1].split(")")[0] + attr = self._dosubst(a_name, subst, False) + attr = f"{sql_function_name}({attr})" cond = self.conditions[a] if isinstance(cond, str): conds.append("%s %s" % (attr, cond)) From 4699ee253eb2b42e553a2cf9d977611bf67c9a1a Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Fri, 30 Jul 2021 12:42:59 +0000 Subject: [PATCH 2/2] Fix queries without SQL functions on fields - This is done by checking if a function is present before removing it --- icat/query.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/icat/query.py b/icat/query.py index 0eacc9ec..83fa2d7b 100644 --- a/icat/query.py +++ b/icat/query.py @@ -142,6 +142,8 @@ def _attrpath(self, attrname): """ rclass = self.entity pattr = "" + if attrname.endswith(')'): + attrname = (attrname.split("("))[1].split(")")[0] for attr in attrname.split('.'): if pattr: pattr += ".%s" % attr @@ -169,6 +171,8 @@ def _makesubst(self, objs): i = obj.rfind('.') if i < 0: continue + if obj.endswith(')'): + obj = (obj.split("("))[1].split(")")[0] obj = obj[:i] for (o, attrInfo, oclass) in self._attrpath(obj): if o not in subst: @@ -373,7 +377,9 @@ def addConditions(self, conditions): """ if conditions: for a in conditions.keys(): - a_name = (a.split("("))[1].split(")")[0] + a_name = a + if a.endswith(')'): + a_name = (a.split("("))[1].split(")")[0] for (pattr, attrInfo, rclass) in self._attrpath(a_name): pass if a in self.conditions: @@ -469,10 +475,13 @@ def __str__(self): if self.conditions: conds = [] for a in sorted(self.conditions.keys()): - sql_function_name = a.split("(")[0] - a_name = (a.split("("))[1].split(")")[0] + a_name = a + if a.endswith(')'): + sql_function_name = a.split("(")[0] + a_name = (a.split("("))[1].split(")")[0] attr = self._dosubst(a_name, subst, False) - attr = f"{sql_function_name}({attr})" + if "sql_function_name" in locals(): + attr = f"{sql_function_name}({attr})" cond = self.conditions[a] if isinstance(cond, str): conds.append("%s %s" % (attr, cond))