diff -r b11f1068a0d3 -r 9b4bac626977 server/sources/rql2sql.py --- a/server/sources/rql2sql.py Thu Jul 09 16:14:22 2009 +0200 +++ b/server/sources/rql2sql.py Thu Jul 09 16:15:22 2009 +0200 @@ -303,7 +303,7 @@ protected by a lock """ - def __init__(self, schema, dbms_helper, dbencoding='UTF-8'): + def __init__(self, schema, dbms_helper, dbencoding='UTF-8', attrmap=None): self.schema = schema self.dbms_helper = dbms_helper self.dbencoding = dbencoding @@ -313,6 +313,9 @@ if not self.dbms_helper.union_parentheses_support: self.union_sql = self.noparen_union_sql self._lock = threading.Lock() + if attrmap is None: + attrmap = {} + self.attr_map = attrmap def generate(self, union, args=None, varmap=None): """return SQL queries and a variable dictionnary from a RQL syntax tree @@ -853,27 +856,30 @@ relation.r_type) return '%s%s' % (lhssql, relation.children[1].accept(self, contextrels)) - def _visit_attribute_relation(self, relation): + def _visit_attribute_relation(self, rel): """generate SQL for an attribute relation""" - lhs, rhs = relation.get_parts() + lhs, rhs = rel.get_parts() rhssql = rhs.accept(self) table = self._var_table(lhs.variable) if table is None: - assert relation.r_type == 'eid' + assert rel.r_type == 'eid' lhssql = lhs.accept(self) else: try: - lhssql = self._varmap['%s.%s' % (lhs.name, relation.r_type)] + lhssql = self._varmap['%s.%s' % (lhs.name, rel.r_type)] except KeyError: - if relation.r_type == 'eid': + mapkey = '%s.%s' % (self._state.solution[lhs.name], rel.r_type) + if mapkey in self.attr_map: + lhssql = self.attr_map[mapkey](self, lhs.variable, rel) + elif rel.r_type == 'eid': lhssql = lhs.variable._q_sql else: - lhssql = '%s.%s%s' % (table, SQL_PREFIX, relation.r_type) + lhssql = '%s.%s%s' % (table, SQL_PREFIX, rel.r_type) try: - if relation._q_needcast == 'TODAY': + if rel._q_needcast == 'TODAY': sql = 'DATE(%s)%s' % (lhssql, rhssql) # XXX which cast function should be used - #elif relation._q_needcast == 'NOW': + #elif rel._q_needcast == 'NOW': # sql = 'TIMESTAMP(%s)%s' % (lhssql, rhssql) else: sql = '%s%s' % (lhssql, rhssql) @@ -884,15 +890,15 @@ else: return sql - def _visit_has_text_relation(self, relation): + def _visit_has_text_relation(self, rel): """generate SQL for a has_text relation""" - lhs, rhs = relation.get_parts() + lhs, rhs = rel.get_parts() const = rhs.children[0] - alias = self._fti_table(relation) + alias = self._fti_table(rel) jointo = lhs.accept(self) restriction = '' lhsvar = lhs.variable - me_is_principal = lhsvar.stinfo.get('principal') is relation + me_is_principal = lhsvar.stinfo.get('principal') is rel if me_is_principal: if not lhsvar.stinfo['typerels']: # the variable is using the fti table, no join needed @@ -908,8 +914,8 @@ else: etypes = ','.join("'%s'" % etype for etype in lhsvar.stinfo['possibletypes']) restriction = " AND %s.type IN (%s)" % (ealias, etypes) - if isinstance(relation.parent, Not): - self._state.done.add(relation.parent) + if isinstance(rel.parent, Not): + self._state.done.add(rel.parent) not_ = True else: not_ = False @@ -1117,6 +1123,9 @@ if isinstance(linkedvar, ColumnAlias): raise BadRQLQuery('variable %s should be selected by the subquery' % variable.name) + mapkey = '%s.%s' % (self._state.solution[linkedvar.name], rel.r_type) + if mapkey in self.attr_map: + return self.attr_map[mapkey](self, linkedvar, rel) try: sql = self._varmap['%s.%s' % (linkedvar.name, rel.r_type)] except KeyError: