From 6a1899e92d4d7e8b5e9b5061867dc5e394d7b5da Mon Sep 17 00:00:00 2001
From: Vincent Pelletier <vincent@nexedi.com>
Date: Tue, 20 Apr 2010 12:58:10 +0000
Subject: [PATCH] Provide backward compatilibity with older ZSQLCatalog.

In older ZSQLCatalog versions (pre-r25706), values fetched via
  select_expression='catalog.simulation_state'
were accessible on brain as "brain.simulation_state". In current catalog,
this became "getattr(brain, 'catalog.simulation_state')" and hence broke
compatibility somewhat. This patch fixes this problem by stripping table
name from the generated alias.
Note: the table name is only stripped from implicit aliases, never from
explicit ones.


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@34685 20353a03-c40f-0410-a6d1-a30d3c3de9de
---
 product/ZSQLCatalog/Query/EntireQuery.py    |  3 +++
 product/ZSQLCatalog/tests/testSQLCatalog.py | 23 +++++++++++++++++++--
 2 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/product/ZSQLCatalog/Query/EntireQuery.py b/product/ZSQLCatalog/Query/EntireQuery.py
index 1174af8ab6..41ab108d72 100644
--- a/product/ZSQLCatalog/Query/EntireQuery.py
+++ b/product/ZSQLCatalog/Query/EntireQuery.py
@@ -115,6 +115,9 @@ class EntireQuery(object):
       for alias, raw_column in self.select_dict.iteritems():
         if raw_column is None:
           column = alias
+          if '.' in alias:
+            # If given column is pre-mapped, strip table name from its alias.
+            _, alias = alias.replace('`', '').split('.')
         else:
           column = raw_column
         try:
diff --git a/product/ZSQLCatalog/tests/testSQLCatalog.py b/product/ZSQLCatalog/tests/testSQLCatalog.py
index 1bb8c35fe0..8419dd4caa 100644
--- a/product/ZSQLCatalog/tests/testSQLCatalog.py
+++ b/product/ZSQLCatalog/tests/testSQLCatalog.py
@@ -217,8 +217,8 @@ class TestSQLCatalog(unittest.TestCase):
           'Query: %r\nSearchText: %r\nReference: %r\nSecond rendering: %r' % \
                        (query, search_text, reference_param_dict, search_text_param_dict))
 
-  def asSQLExpression(self, kw):
-    entire_query = self._catalog.buildEntireQuery(kw)
+  def asSQLExpression(self, kw, **build_entire_query_kw):
+    entire_query = self._catalog.buildEntireQuery(kw, **build_entire_query_kw)
     return entire_query.asSQLExpression(self._catalog, False)
 
   def _testDefaultKey(self, column):
@@ -549,6 +549,25 @@ class TestSQLCatalog(unittest.TestCase):
     select_dict = sql_expression.getSelectDict()
     self.assertTrue('ambiguous_mapping' in select_dict, select_dict)
     self.assertTrue('bar' in select_dict['ambiguous_mapping'], select_dict['ambiguous_mapping'])
+    # Doted alias: table name must get stripped. This is required to have an
+    # upgrade path from old ZSQLCatalog versions where pre-mapped columns were
+    # used in their select_expression. This must only happen in the
+    # "{column: None}" form, as otherwise it's the user explicitely asking for
+    # such alias (which is not strictly invalid).
+    sql_expression = self.asSQLExpression({'select_dict': {
+      'foo.default': None,
+      'foo.keyword': 'foo.keyword',
+    }}, query_table='foo')
+    select_dict = sql_expression.getSelectDict()
+    self.assertTrue('default' in select_dict, select_dict)
+    self.assertFalse('foo.default' in select_dict, select_dict)
+    self.assertTrue('foo.keyword' in select_dict, select_dict)
+    # Variant: same operation, but this time stripping generates an ambiguity.
+    # That must be detected and cause a mapping exception.
+    self.assertRaises(ValueError, self.asSQLExpression, {'select_dict': {
+        'foo.ambiguous_mapping': None,
+        'bar.ambiguous_mapping': None,
+      }}, query_table='foo')
 
   def test_hasColumn(self):
     self.assertTrue(self._catalog.hasColumn('uid'))
-- 
2.30.9