1008ea311SIrynaMironavaimport uuid
2008ea311SIrynaMironavaimport copy
3008ea311SIrynaMironavafrom tuqquery.tuq import QueryTests
4dd5e1b13SParag Agarwalfrom couchbase_helper.documentgenerator import DocumentGenerator
5008ea311SIrynaMironava
6008ea311SIrynaMironava
7ebd4ee10SIrynaMironavaJOIN_INNER = "INNER"
8ebd4ee10SIrynaMironavaJOIN_LEFT = "LEFT"
9ebd4ee10SIrynaMironavaJOIN_RIGHT = "RIGHT"
10008ea311SIrynaMironava
11008ea311SIrynaMironavaclass JoinTests(QueryTests):
12008ea311SIrynaMironava    def setUp(self):
13dd48635fSIrynaMironava        try:
14dd48635fSIrynaMironava            super(JoinTests, self).setUp()
15dd48635fSIrynaMironava            self.gens_tasks = self.generate_docs_tasks()
16dd48635fSIrynaMironava            self.type_join = self.input.param("type_join", JOIN_INNER)
17dd48635fSIrynaMironava        except Exception, ex:
18dd48635fSIrynaMironava            self.log.error("ERROR SETUP FAILED: %s" % str(ex))
19dd48635fSIrynaMironava            raise ex
20008ea311SIrynaMironava
21008ea311SIrynaMironava    def suite_setUp(self):
22008ea311SIrynaMironava        super(JoinTests, self).suite_setUp()
23008ea311SIrynaMironava        self.load(self.gens_tasks, start_items=self.num_items)
24008ea311SIrynaMironava
25008ea311SIrynaMironava    def tearDown(self):
26008ea311SIrynaMironava        super(JoinTests, self).tearDown()
27008ea311SIrynaMironava
28008ea311SIrynaMironava    def suite_tearDown(self):
29008ea311SIrynaMironava        super(JoinTests, self).suite_tearDown()
30008ea311SIrynaMironava
31008ea311SIrynaMironava    def test_simple_join_keys(self):
32008ea311SIrynaMironava        for bucket in self.buckets:
33008ea311SIrynaMironava            self.query = "SELECT employee.name, employee.tasks_ids, new_project " +\
34ebd4ee10SIrynaMironava            "FROM %s as employee %s JOIN default.project as new_project " % (bucket.name, self.type_join) +\
3579fd7838SIrynaMironava            "ON KEYS employee.tasks_ids"
36008ea311SIrynaMironava            actual_result = self.run_cbq_query()
370e54f998SIrynaMironava            actual_result = sorted(actual_result['results'])
38ebd4ee10SIrynaMironava            full_list = self._generate_full_joined_docs_list(join_type=self.type_join)
39ebd4ee10SIrynaMironava            expected_result = [doc for doc in full_list if not doc]
40ebd4ee10SIrynaMironava            expected_result.extend([{"name" : doc['name'], "tasks_ids" : doc['tasks_ids'],
41ebd4ee10SIrynaMironava                                     "new_project" : doc['project']}
42ebd4ee10SIrynaMironava                                    for doc in full_list if doc and 'project' in doc])
43ebd4ee10SIrynaMironava            expected_result.extend([{"name" : doc['name'], "tasks_ids" : doc['tasks_ids']}
44ebd4ee10SIrynaMironava                                    for doc in full_list if doc and not 'project' in doc])
45ebd4ee10SIrynaMironava            expected_result = sorted(expected_result)
46008ea311SIrynaMironava            self._verify_results(actual_result, expected_result)
47008ea311SIrynaMironava
48008ea311SIrynaMironava    def test_join_several_keys(self):
49008ea311SIrynaMironava        for bucket in self.buckets:
50008ea311SIrynaMironava            self.query = "SELECT employee.name, employee.tasks_ids, new_task.project, new_task.task_name " +\
51ebd4ee10SIrynaMironava            "FROM %s as employee %s JOIN default as new_task " % (bucket.name, self.type_join) +\
5279fd7838SIrynaMironava            "ON KEYS employee.tasks_ids"
53008ea311SIrynaMironava            actual_result = self.run_cbq_query()
540e54f998SIrynaMironava            actual_result = sorted(actual_result['results'])
55ebd4ee10SIrynaMironava            full_list = self._generate_full_joined_docs_list(join_type=self.type_join)
56ebd4ee10SIrynaMironava            expected_result = [doc for doc in full_list if not doc]
57ebd4ee10SIrynaMironava            expected_result.extend([{"name" : doc['name'], "tasks_ids" : doc['tasks_ids'],
58ebd4ee10SIrynaMironava                                     "project" : doc['project'], "task_name" : doc['task_name']}
59ebd4ee10SIrynaMironava                                    for doc in full_list if doc and 'project' in doc])
60ebd4ee10SIrynaMironava            expected_result.extend([{"name" : doc['name'], "tasks_ids" : doc['tasks_ids']}
61ebd4ee10SIrynaMironava                                    for doc in full_list if doc and not 'project' in doc])
62ebd4ee10SIrynaMironava            expected_result = sorted(expected_result)
63008ea311SIrynaMironava            self._verify_results(actual_result, expected_result)
64008ea311SIrynaMironava
65008ea311SIrynaMironava    def test_where_join_keys(self):
66008ea311SIrynaMironava        for bucket in self.buckets:
6792ddd188SIrynaMironava            self.query = "SELECT employee.name, employee.tasks_ids, new_project_full.project new_project " +\
6892ddd188SIrynaMironava            "FROM %s as employee %s JOIN default as new_project_full " % (bucket.name, self.type_join) +\
6979fd7838SIrynaMironava            "ON KEYS employee.tasks_ids WHERE new_project_full.project == 'IT'"
70008ea311SIrynaMironava            actual_result = self.run_cbq_query()
710e54f998SIrynaMironava            actual_result = sorted(actual_result['results'])
72ebd4ee10SIrynaMironava            expected_result = self._generate_full_joined_docs_list(join_type=self.type_join)
73008ea311SIrynaMironava            expected_result = [{"name" : doc['name'], "tasks_ids" : doc['tasks_ids'],
74008ea311SIrynaMironava                                "new_project" : doc['project']}
75ebd4ee10SIrynaMironava                               for doc in expected_result if doc and 'project' in doc and\
76ebd4ee10SIrynaMironava                               doc['project'] == 'IT']
77ebd4ee10SIrynaMironava            expected_result = sorted(expected_result)
78008ea311SIrynaMironava            self._verify_results(actual_result, expected_result)
79008ea311SIrynaMironava
807705cebcSIrynaMironava    def test_join_unnest_alias(self):
817705cebcSIrynaMironava        for bucket in self.buckets:
827705cebcSIrynaMironava            self.query = "SELECT task2 FROM %s emp1 JOIN %s" % (bucket.name, bucket.name) +\
8379fd7838SIrynaMironava            " task ON KEYS emp1.tasks_ids UNNEST emp1.tasks_ids as task2"
847705cebcSIrynaMironava            actual_result = self.run_cbq_query()
850e54f998SIrynaMironava            actual_result = sorted(actual_result['results'], key=lambda doc:(
867705cebcSIrynaMironava                                                               doc['task2']))
877705cebcSIrynaMironava            expected_result = self._generate_full_joined_docs_list()
887705cebcSIrynaMironava            expected_result = [{"task2" : task} for doc in expected_result
897705cebcSIrynaMironava                               for task in doc['tasks_ids']]
907705cebcSIrynaMironava            expected_result = sorted(expected_result, key=lambda doc:(
917705cebcSIrynaMironava                                                          doc['task2']))
927705cebcSIrynaMironava            self._verify_results(actual_result, expected_result)
937705cebcSIrynaMironava
94356b1630SIrynaMironava    def test_unnest(self):
95356b1630SIrynaMironava        for bucket in self.buckets:
96e0199ab6SIrynaMironava            self.query = "SELECT emp.name, task FROM %s emp %s UNNEST emp.tasks_ids task" % (bucket.name,self.type_join)
97356b1630SIrynaMironava            actual_result = self.run_cbq_query()
980e54f998SIrynaMironava            actual_result = sorted(actual_result['results'])
99e0199ab6SIrynaMironava            expected_result = self._generate_full_docs_list(self.gens_load)
100e0199ab6SIrynaMironava            expected_result = [{"task" : task, "name" : doc["name"]}
101e0199ab6SIrynaMironava                               for doc in expected_result for task in doc['tasks_ids']]
102e0199ab6SIrynaMironava            if self.type_join.upper() == JOIN_LEFT:
103e0199ab6SIrynaMironava                expected_result.extend([{}] * self.gens_tasks[-1].end)
104e0199ab6SIrynaMironava            expected_result = sorted(expected_result)
105356b1630SIrynaMironava            self._verify_results(actual_result, expected_result)
1068705c4a3SIrynaMironava
1078705c4a3SIrynaMironava    def test_subquery_select(self):
1088705c4a3SIrynaMironava        for bucket in self.buckets:
109ebeb55cdSIrynaMironava            self.query = "select task_name, (select count(task_name) cn from %s d use keys %s) as names from %s" % (bucket.name, str(['test_task-%s' % i for i in xrange(0, 29)]),
110ebeb55cdSIrynaMironava                                                                                                                    bucket.name)
1111394025cSIrynaMironava            self.run_cbq_query()
1128705c4a3SIrynaMironava            actual_result = self.run_cbq_query()
1130e54f998SIrynaMironava            actual_result = sorted(actual_result['results'])
1141394025cSIrynaMironava            expected_result_subquery = {"cn" : 29}
1151394025cSIrynaMironava            expected_result = [{'names' : [expected_result_subquery]}] * len(self._generate_full_docs_list(self.gens_load))
1168705c4a3SIrynaMironava            expected_result.extend([{'task_name': doc['task_name'],
1171394025cSIrynaMironava                                     'names' : [expected_result_subquery]}
1181394025cSIrynaMironava                                    for doc in self._generate_full_docs_list(self.gens_tasks)])
1198705c4a3SIrynaMironava            expected_result = sorted(expected_result)
1208705c4a3SIrynaMironava            self._verify_results(actual_result, expected_result)
1218705c4a3SIrynaMironava
1228705c4a3SIrynaMironava    def test_subquery_where_aggr(self):
1238705c4a3SIrynaMironava        for bucket in self.buckets:
124ebeb55cdSIrynaMironava            self.query = "select name, join_day from %s where join_day =" % (bucket.name) +\
125ebeb55cdSIrynaMironava            " (select AVG(join_day) as average from %s d use keys %s)[0].average" % (bucket.name,
1268705c4a3SIrynaMironava                                                                               str(['query-test-Sales-%s' % i
1278705c4a3SIrynaMironava                                                                                    for i in xrange(0, self.docs_per_day)]))
1288705c4a3SIrynaMironava            all_docs_list = self._generate_full_docs_list(self.gens_load)
1298705c4a3SIrynaMironava            actual_result = self.run_cbq_query()
1300e54f998SIrynaMironava            actual_result = sorted(actual_result['results'])
1318705c4a3SIrynaMironava            expected_result = [{'name' : doc['name'],
1328705c4a3SIrynaMironava                                'join_day' : doc['join_day']}
1338705c4a3SIrynaMironava                               for doc in all_docs_list
1348705c4a3SIrynaMironava                               if doc['job_title'] == 'Sales' and doc['join_day'] == 1]
1358705c4a3SIrynaMironava            expected_result = sorted(expected_result)
1368705c4a3SIrynaMironava            self._verify_results(actual_result, expected_result)
1378705c4a3SIrynaMironava
1388705c4a3SIrynaMironava    def test_subquery_where_in(self):
1398705c4a3SIrynaMironava        for bucket in self.buckets:
140ebeb55cdSIrynaMironava            self.query = "select name, join_day from %s where join_day IN " % (bucket.name) +\
141ebeb55cdSIrynaMironava            " (select ARRAY_AGG(join_day) as average from %s d use keys %s)[0].average" % (bucket.name,
1428705c4a3SIrynaMironava                                                                               str(['query-test-Sales-%s' % i
1438705c4a3SIrynaMironava                                                                                    for i in xrange(0, self.docs_per_day)]))
1448705c4a3SIrynaMironava            all_docs_list = self._generate_full_docs_list(self.gens_load)
1458705c4a3SIrynaMironava            actual_result = self.run_cbq_query()
1460e54f998SIrynaMironava            actual_result = sorted(actual_result['results'])
1478705c4a3SIrynaMironava            expected_result = [{'name' : doc['name'],
1488705c4a3SIrynaMironava                                'join_day' : doc['join_day']}
1498705c4a3SIrynaMironava                               for doc in all_docs_list
1508705c4a3SIrynaMironava                               if doc['job_title'] == 'Sales' and doc['join_day'] == 1]
1518705c4a3SIrynaMironava            expected_result = sorted(expected_result)
1528705c4a3SIrynaMironava            self._verify_results(actual_result, expected_result)
1538705c4a3SIrynaMironava
1540dc85047SIrynaMironava    def test_where_in_subquery(self):
1550dc85047SIrynaMironava        for bucket in self.buckets:
1560dc85047SIrynaMironava            self.query = "select name, tasks_ids from %s where tasks_ids[0] IN" % bucket.name +\
157a0fa7aa8SIrynaMironava            " (select ARRAY_AGG(DISTINCT task_name) as names from %s d " % bucket.name +\
1588b581394SIrynaMironava            "use keys %s where project='MB')[0].names" % ('["test_task-1", "test_task-2"]')
1590dc85047SIrynaMironava            all_docs_list = self._generate_full_docs_list(self.gens_load)
1600dc85047SIrynaMironava            actual_result = self.run_cbq_query()
1610e54f998SIrynaMironava            actual_result = sorted(actual_result['results'])
1620dc85047SIrynaMironava            expected_result = [{'name' : doc['name'],
1630dc85047SIrynaMironava                                'tasks_ids' : doc['tasks_ids']}
1640dc85047SIrynaMironava                               for doc in all_docs_list
1650dc85047SIrynaMironava                               if doc['tasks_ids'] in ['test_task-1', 'test_task-2']]
1660dc85047SIrynaMironava            expected_result = sorted(expected_result)
1670dc85047SIrynaMironava            self._verify_results(actual_result, expected_result)
1682c4c48ebSIrynaMironava##############################################################################################
1692c4c48ebSIrynaMironava#
1702c4c48ebSIrynaMironava#   KEY
1712c4c48ebSIrynaMironava##############################################################################################
1722c4c48ebSIrynaMironava
1732c4c48ebSIrynaMironava    def test_keys(self):
1742c4c48ebSIrynaMironava        for bucket in self.buckets:
1752c4c48ebSIrynaMironava            keys_select = []
1762c4c48ebSIrynaMironava            generator = copy.deepcopy(self.gens_tasks[0])
1772c4c48ebSIrynaMironava            for i in xrange(5):
1782c4c48ebSIrynaMironava                key, _ = generator.next()
1792c4c48ebSIrynaMironava                keys_select.append(key)
1808b581394SIrynaMironava            self.query = 'select task_name FROM %s USE KEYS %s' % (bucket.name, keys_select)
1812c4c48ebSIrynaMironava            actual_result = self.run_cbq_query()
1820e54f998SIrynaMironava            actual_result = sorted(actual_result['results'], key=lambda doc: (
1832c4c48ebSIrynaMironava                                                                       doc['task_name']))
1842c4c48ebSIrynaMironava            full_list = self._generate_full_docs_list(self.gens_tasks, keys=keys_select)
1852c4c48ebSIrynaMironava            expected_result = [{"task_name" : doc['task_name']} for doc in full_list]
1862c4c48ebSIrynaMironava            expected_result = sorted(expected_result, key=lambda doc: (doc['task_name']))
1872c4c48ebSIrynaMironava            self._verify_results(actual_result, expected_result)
1882c4c48ebSIrynaMironava
1892c4c48ebSIrynaMironava            keys_select.extend(["wrong"])
1908b581394SIrynaMironava            self.query = 'select task_name FROM %s USE KEYS %s' % (bucket.name, keys_select)
1912c4c48ebSIrynaMironava            actual_result = self.run_cbq_query()
1920e54f998SIrynaMironava            actual_result = sorted(actual_result['results'])
1932c4c48ebSIrynaMironava            self._verify_results(actual_result, expected_result)
1942c4c48ebSIrynaMironava
1958b581394SIrynaMironava            self.query = 'select task_name FROM %s USE KEYS ["wrong_one","wrong_second"]' % (bucket.name)
1962c4c48ebSIrynaMironava            actual_result = self.run_cbq_query()
1970e54f998SIrynaMironava            self.assertFalse(actual_result['results'], "Having a wrong key query returned some result")
198356b1630SIrynaMironava
1997ad12bf7SIrynaMironava    def test_key_array(self):
2007ad12bf7SIrynaMironava        for bucket in self.buckets:
2017ad12bf7SIrynaMironava            gen_select = copy.deepcopy(self.gens_tasks[0])
2027ad12bf7SIrynaMironava            key_select, value_select = gen_select.next()
2038b581394SIrynaMironava            self.query = 'SELECT * FROM %s USE KEYS ARRAY emp._id FOR emp IN [%s] END' % (bucket.name, value_select)
2047ad12bf7SIrynaMironava            actual_result = self.run_cbq_query()
2050e54f998SIrynaMironava            actual_result = sorted(actual_result['results'])
2067ad12bf7SIrynaMironava            expected_result = self._generate_full_docs_list(self.gens_tasks, keys=[key_select])
207a0fa7aa8SIrynaMironava            expected_result = [{bucket.name : doc} for doc in expected_result]
2087ad12bf7SIrynaMironava            expected_result = sorted(expected_result)
2097ad12bf7SIrynaMironava            self._verify_results(actual_result, expected_result)
2107ad12bf7SIrynaMironava
2117ad12bf7SIrynaMironava            key2_select, value2_select = gen_select.next()
2128b581394SIrynaMironava            self.query = 'SELECT * FROM %s USE KEYS ARRAY emp._id FOR emp IN [%s,%s] END' % (bucket.name,
2137ad12bf7SIrynaMironava                                                                                      value_select,
2147ad12bf7SIrynaMironava                                                                                      value2_select)
2157ad12bf7SIrynaMironava            actual_result = self.run_cbq_query()
2160e54f998SIrynaMironava            actual_result = sorted(actual_result['results'])
2177ad12bf7SIrynaMironava            expected_result = self._generate_full_docs_list(self.gens_tasks, keys=[key_select, key2_select])
2181394025cSIrynaMironava            expected_result = [{bucket.name : doc} for doc in expected_result]
2197ad12bf7SIrynaMironava            expected_result = sorted(expected_result)
2207ad12bf7SIrynaMironava            self._verify_results(actual_result, expected_result)
2217ad12bf7SIrynaMironava
2222c4c48ebSIrynaMironava##############################################################################################
2232c4c48ebSIrynaMironava#
2242c4c48ebSIrynaMironava#   NEST
2252c4c48ebSIrynaMironava##############################################################################################
2262c4c48ebSIrynaMironava
2272c4c48ebSIrynaMironava
228a394e55aSIrynaMironava    def test_simple_nest_keys(self):
229a394e55aSIrynaMironava        for bucket in self.buckets:
230a394e55aSIrynaMironava            self.query = "SELECT * FROM %s emp %s NEST %s tasks " % (
231a394e55aSIrynaMironava                                                bucket.name, self.type_join, bucket.name) +\
2326c54ed5cSIrynaMironava                         "ON KEYS emp.tasks_ids"
233a394e55aSIrynaMironava            actual_result = self.run_cbq_query()
2346c54ed5cSIrynaMironava            actual_result = self.sort_nested_list(actual_result['results'])
2356c54ed5cSIrynaMironava            actual_result = sorted(actual_result, key=lambda doc:
236a394e55aSIrynaMironava                                   self._get_for_sort(doc))
237a394e55aSIrynaMironava            self._delete_ids(actual_result)
238a394e55aSIrynaMironava            full_list = self._generate_full_nested_docs_list(join_type=self.type_join)
239a394e55aSIrynaMironava            expected_result = [{"emp" : doc['item'], "tasks" : doc['items_nested']}
240a394e55aSIrynaMironava                               for doc in full_list if doc and 'items_nested' in doc]
241a394e55aSIrynaMironava            expected_result.extend([{"emp" : doc['item']}
242a394e55aSIrynaMironava                                    for doc in full_list if not 'items_nested' in doc])
243a394e55aSIrynaMironava            expected_result = sorted(expected_result, key=lambda doc:
244a394e55aSIrynaMironava                                   self._get_for_sort(doc))
245a394e55aSIrynaMironava            self._delete_ids(expected_result)
246a394e55aSIrynaMironava            self._verify_results(actual_result, expected_result)
247a394e55aSIrynaMironava
248a394e55aSIrynaMironava    def test_simple_nest_key(self):
249a394e55aSIrynaMironava        for bucket in self.buckets:
250a394e55aSIrynaMironava            self.query = "SELECT * FROM %s emp %s NEST %s tasks " % (
251a394e55aSIrynaMironava                                                bucket.name, self.type_join, bucket.name) +\
252a394e55aSIrynaMironava                         "KEY emp.tasks_ids[0]"
253a394e55aSIrynaMironava            actual_result = self.run_cbq_query()
2540e54f998SIrynaMironava            actual_result = sorted(actual_result['results'], key=lambda doc:
255a394e55aSIrynaMironava                                                            self._get_for_sort(doc))
256a394e55aSIrynaMironava            self._delete_ids(actual_result)
257a394e55aSIrynaMironava            full_list = self._generate_full_nested_docs_list(particular_key=0,
258a394e55aSIrynaMironava                                                             join_type=self.type_join)
259a394e55aSIrynaMironava            expected_result = [{"emp" : doc['item'], "tasks" : doc['items_nested']}
260a394e55aSIrynaMironava                               for doc in full_list if doc and 'items_nested' in doc]
261a394e55aSIrynaMironava            expected_result.extend([{"emp" : doc['item']}
262a394e55aSIrynaMironava                                    for doc in full_list if not 'items_nested' in doc])
263a394e55aSIrynaMironava            expected_result = sorted(expected_result, key=lambda doc:
264a394e55aSIrynaMironava                                                            self._get_for_sort(doc))
265a394e55aSIrynaMironava            self._delete_ids(expected_result)
266a394e55aSIrynaMironava            self._verify_results(actual_result, expected_result)
267a394e55aSIrynaMironava
268a394e55aSIrynaMironava    def test_nest_keys_with_array(self):
269a394e55aSIrynaMironava        for bucket in self.buckets:
270a394e55aSIrynaMironava            self.query = "select emp.name, ARRAY item.project FOR item in items end projects " +\
271a394e55aSIrynaMironava                         "FROM %s emp %s NEST %s items " % (
272a394e55aSIrynaMironava                                                    bucket.name, self.type_join, bucket.name) +\
27379fd7838SIrynaMironava                         "ON KEYS emp.tasks_ids"
274a394e55aSIrynaMironava            actual_result = self.run_cbq_query()
2756c54ed5cSIrynaMironava            actual_result = self.sort_nested_list(actual_result['results'])
2766c54ed5cSIrynaMironava            actual_result = sorted(actual_result)
277a394e55aSIrynaMironava            full_list = self._generate_full_nested_docs_list(join_type=self.type_join)
278a394e55aSIrynaMironava            expected_result = [{"name" : doc['item']['name'],
279a394e55aSIrynaMironava                                "projects" : [nested_doc['project'] for nested_doc in doc['items_nested']]}
280a394e55aSIrynaMironava                               for doc in full_list if doc and 'items_nested' in doc]
281a394e55aSIrynaMironava            expected_result.extend([{} for doc in full_list if not 'items_nested' in doc])
282a394e55aSIrynaMironava            expected_result = sorted(expected_result)
283a394e55aSIrynaMironava            self._verify_results(actual_result, expected_result)
284a394e55aSIrynaMironava
285a394e55aSIrynaMironava    def test_nest_keys_where(self):
286a394e55aSIrynaMironava        for bucket in self.buckets:
287a394e55aSIrynaMironava            self.query = "select emp.name, ARRAY item.project FOR item in items end projects " +\
288a394e55aSIrynaMironava                         "FROM %s emp %s NEST %s items " % (
289a394e55aSIrynaMironava                                                    bucket.name, self.type_join, bucket.name) +\
29079fd7838SIrynaMironava                         "ON KEYS emp.tasks_ids where ANY item IN items SATISFIES item.project == 'CB' end"
291a394e55aSIrynaMironava            actual_result = self.run_cbq_query()
2920e54f998SIrynaMironava            actual_result = sorted(actual_result['results'], key=lambda doc: (doc['name'], doc['projects']))
293a394e55aSIrynaMironava            full_list = self._generate_full_nested_docs_list(join_type=self.type_join)
294a394e55aSIrynaMironava            expected_result = [{"name" : doc['item']['name'],
295a394e55aSIrynaMironava                                "projects" : [nested_doc['project'] for nested_doc in doc['items_nested']]}
296a394e55aSIrynaMironava                               for doc in full_list if doc and 'items_nested' in doc and\
297a394e55aSIrynaMironava                               len([nested_doc for nested_doc in doc['items_nested']
298a394e55aSIrynaMironava                                    if nested_doc['project'] == 'CB']) > 0]
299a394e55aSIrynaMironava            expected_result = sorted(expected_result, key=lambda doc: (doc['name'], doc['projects']))
300a394e55aSIrynaMironava            self._verify_results(actual_result, expected_result)
301a394e55aSIrynaMironava
302a394e55aSIrynaMironava    def _get_for_sort(self, doc):
303a394e55aSIrynaMironava        if not 'emp' in doc:
304a394e55aSIrynaMironava            return ''
305a394e55aSIrynaMironava        if 'name' in doc['emp']:
306a394e55aSIrynaMironava            return doc['emp']['name'], doc['emp']['join_yr'],\
307a394e55aSIrynaMironava                   doc['emp']['join_mo'], doc['emp']['job_title']
308a394e55aSIrynaMironava        else:
309a394e55aSIrynaMironava            return doc['emp']['task_name']
310a394e55aSIrynaMironava
311a394e55aSIrynaMironava    def _delete_ids(self, result):
312a394e55aSIrynaMironava        for item in result:
313a394e55aSIrynaMironava            if 'emp' in item:
314a394e55aSIrynaMironava                del item['emp']['_id']
3156c54ed5cSIrynaMironava            if 'tasks' in item:
3166c54ed5cSIrynaMironava                for task in item['tasks']:
3176c54ed5cSIrynaMironava                    if task and '_id' in task:
3186c54ed5cSIrynaMironava                        del task['_id']
319a394e55aSIrynaMironava
320008ea311SIrynaMironava    def generate_docs(self, docs_per_day, start=0):
321008ea311SIrynaMironava        generators = []
322008ea311SIrynaMironava        types = ['Engineer', 'Sales', 'Support']
323008ea311SIrynaMironava        join_yr = [2010, 2011]
324008ea311SIrynaMironava        join_mo = xrange(1, 12 + 1)
325008ea311SIrynaMironava        join_day = xrange(1, 28 + 1)
326008ea311SIrynaMironava        template = '{{ "name":"{0}", "join_yr":{1}, "join_mo":{2}, "join_day":{3},'
327008ea311SIrynaMironava        template += ' "job_title":"{4}", "tasks_ids":{5}}}'
328008ea311SIrynaMironava        for info in types:
329008ea311SIrynaMironava            for year in join_yr:
330008ea311SIrynaMironava                for month in join_mo:
331008ea311SIrynaMironava                    for day in join_day:
332008ea311SIrynaMironava                        name = ["employee-%s" % (str(day))]
333008ea311SIrynaMironava                        tasks_ids = ["test_task-%s" % day, "test_task-%s" % (day + 1)]
334ec17f464SIrynaMironava                        generators.append(DocumentGenerator("query-test-%s-%s-%s-%s" % (info, year, month, day),
335008ea311SIrynaMironava                                               template,
336008ea311SIrynaMironava                                               name, [year], [month], [day],
337008ea311SIrynaMironava                                               [info], [tasks_ids],
338008ea311SIrynaMironava                                               start=start, end=docs_per_day))
339008ea311SIrynaMironava        return generators
340008ea311SIrynaMironava
341008ea311SIrynaMironava    def generate_docs_tasks(self):
342008ea311SIrynaMironava        generators = []
343008ea311SIrynaMironava        start, end = 0, (28 + 1)
344f1142f95SIrynaMironava        template = '{{ "task_name":"{0}", "project": "{1}"}}'
345008ea311SIrynaMironava        generators.append(DocumentGenerator("test_task", template,
3460dc85047SIrynaMironava                                            ["test_task-%s" % i for i in xrange(0,10)],
347008ea311SIrynaMironava                                            ["CB"],
348008ea311SIrynaMironava                                            start=start, end=10))
349008ea311SIrynaMironava        generators.append(DocumentGenerator("test_task", template,
3500dc85047SIrynaMironava                                            ["test_task-%s" % i for i in xrange(10,20)],
351008ea311SIrynaMironava                                            ["MB"],
352008ea311SIrynaMironava                                            start=10, end=20))
353008ea311SIrynaMironava        generators.append(DocumentGenerator("test_task", template,
3540dc85047SIrynaMironava                                            ["test_task-%s" % i for i in xrange(20,end)],
355008ea311SIrynaMironava                                            ["IT"],
356008ea311SIrynaMironava                                            start=20, end=end))
357008ea311SIrynaMironava        return generators
358008ea311SIrynaMironava
359008ea311SIrynaMironava    def _generate_full_joined_docs_list(self, join_type=JOIN_INNER,
360008ea311SIrynaMironava                                        particular_key=None):
361008ea311SIrynaMironava        joined_list = []
362008ea311SIrynaMironava        all_docs_list = self._generate_full_docs_list(self.gens_load)
363ebd4ee10SIrynaMironava        if join_type.upper() == JOIN_INNER:
364008ea311SIrynaMironava            for item in all_docs_list:
365008ea311SIrynaMironava                keys = item["tasks_ids"]
366ebd4ee10SIrynaMironava                if particular_key is not None:
367008ea311SIrynaMironava                    keys=[item["tasks_ids"][particular_key]]
368008ea311SIrynaMironava                tasks_items = self._generate_full_docs_list(self.gens_tasks, keys=keys)
369008ea311SIrynaMironava                for tasks_item in tasks_items:
370008ea311SIrynaMironava                    item_to_add = copy.deepcopy(item)
371008ea311SIrynaMironava                    item_to_add.update(tasks_item)
372008ea311SIrynaMironava                    joined_list.append(item_to_add)
373ebd4ee10SIrynaMironava        elif join_type.upper() == JOIN_LEFT:
374ebd4ee10SIrynaMironava            for item in all_docs_list:
375ebd4ee10SIrynaMironava                keys = item["tasks_ids"]
376a394e55aSIrynaMironava                if particular_key is not None:
377ebd4ee10SIrynaMironava                    keys=[item["tasks_ids"][particular_key]]
378ebd4ee10SIrynaMironava                tasks_items = self._generate_full_docs_list(self.gens_tasks, keys=keys)
379ebd4ee10SIrynaMironava                for key in keys:
380ebd4ee10SIrynaMironava                    item_to_add = copy.deepcopy(item)
381ebd4ee10SIrynaMironava                    if key in [doc["_id"] for doc in tasks_items]:
382ebd4ee10SIrynaMironava                        item_to_add.update([doc for doc in tasks_items if key == doc['_id']][0])
383ebd4ee10SIrynaMironava                    joined_list.append(item_to_add)
384ebd4ee10SIrynaMironava            joined_list.extend([{}] * self.gens_tasks[-1].end)
385ebd4ee10SIrynaMironava        elif join_type.upper() == JOIN_RIGHT:
386ebd4ee10SIrynaMironava            raise Exception("RIGHT JOIN doen't exists in corrunt implementation")
387008ea311SIrynaMironava        else:
388008ea311SIrynaMironava            raise Exception("Unknown type of join")
389a394e55aSIrynaMironava        return joined_list
390a394e55aSIrynaMironava
391a394e55aSIrynaMironava    def _generate_full_nested_docs_list(self, join_type=JOIN_INNER,
392a394e55aSIrynaMironava                                        particular_key=None):
393a394e55aSIrynaMironava        nested_list = []
394a394e55aSIrynaMironava        all_docs_list = self._generate_full_docs_list(self.gens_load)
395a394e55aSIrynaMironava        if join_type.upper() == JOIN_INNER:
396a394e55aSIrynaMironava            for item in all_docs_list:
397a394e55aSIrynaMironava                keys = item["tasks_ids"]
398a394e55aSIrynaMironava                if particular_key is not None:
399a394e55aSIrynaMironava                    keys=[item["tasks_ids"][particular_key]]
400a394e55aSIrynaMironava                tasks_items = self._generate_full_docs_list(self.gens_tasks, keys=keys)
401a394e55aSIrynaMironava                if tasks_items:
402a394e55aSIrynaMironava                    nested_list.append({"items_nested" : tasks_items,
403a394e55aSIrynaMironava                                        "item" : item})
404a394e55aSIrynaMironava        elif join_type.upper() == JOIN_LEFT:
405a394e55aSIrynaMironava            for item in all_docs_list:
406a394e55aSIrynaMironava                keys = item["tasks_ids"]
407a394e55aSIrynaMironava                if particular_key is not None:
408a394e55aSIrynaMironava                    keys=[item["tasks_ids"][particular_key]]
409a394e55aSIrynaMironava                tasks_items = self._generate_full_docs_list(self.gens_tasks, keys=keys)
410a394e55aSIrynaMironava                if tasks_items:
411a394e55aSIrynaMironava                    nested_list.append({"items_nested" : tasks_items,
412a394e55aSIrynaMironava                                        "item" : item})
413a394e55aSIrynaMironava            tasks_doc_list = self._generate_full_docs_list(self.gens_tasks)
414a394e55aSIrynaMironava            for item in tasks_doc_list:
415a394e55aSIrynaMironava                nested_list.append({"item" : item})
416a394e55aSIrynaMironava        elif join_type.upper() == JOIN_RIGHT:
417a394e55aSIrynaMironava            raise Exception("RIGHT JOIN doen't exists in corrunt implementation")
418a394e55aSIrynaMironava        else:
419a394e55aSIrynaMironava            raise Exception("Unknown type of join")
4207ad12bf7SIrynaMironava        return nested_list
421