class TestPrepare(unittest.TestCase, TestBase): @classmethod def setUpClass(cls): cls.set_up_class() create_statement = ( 'CREATE TABLE ' + table_name + '(fld_id INTEGER, fld_long LONG, \ fld_float FLOAT, fld_double DOUBLE, fld_bool BOOLEAN, fld_str STRING, \ fld_bin BINARY, fld_time TIMESTAMP(3), fld_num NUMBER, fld_json JSON, \ fld_arr ARRAY(STRING), fld_map MAP(STRING), \ fld_rec RECORD(fld_id LONG, fld_bool BOOLEAN, fld_str STRING), \ PRIMARY KEY(fld_id)) USING TTL 1 HOURS') limits = TableLimits(100, 100, 1) create_request = TableRequest().set_statement( create_statement).set_table_limits(limits) cls.table_request(create_request) create_idx_request = TableRequest() create_idx_statement = ('CREATE INDEX ' + index_name + '1 ON ' + table_name + '(fld_str)') create_idx_request.set_statement(create_idx_statement) cls.table_request(create_idx_request) create_idx_statement = ('CREATE INDEX ' + index_name + '2 ON ' + table_name + '(fld_map.values())') create_idx_request.set_statement(create_idx_statement) cls.table_request(create_idx_request) @classmethod def tearDownClass(cls): cls.tear_down_class() def setUp(self): self.set_up() self.prepare_statement = ('SELECT fld_id FROM ' + table_name) self.prepare_request = PrepareRequest().set_timeout(timeout) def tearDown(self): self.tear_down() def testPrepareSetIllegalStatement(self): self.assertRaises(IllegalArgumentException, self.prepare_request.set_statement, {}) self.assertRaises(IllegalArgumentException, self.prepare_request.set_statement, '') self.prepare_request.set_statement('IllegalStatement') self.assertRaises(IllegalArgumentException, self.handle.prepare, self.prepare_request) self.prepare_request.set_statement( 'SELECT fld_id FROM IllegalTableName') self.assertRaises(TableNotFoundException, self.handle.prepare, self.prepare_request) def testPrepareSetIllegalCompartment(self): self.assertRaises(IllegalArgumentException, self.prepare_request.set_compartment, {}) self.assertRaises(IllegalArgumentException, self.prepare_request.set_compartment, '') def testPrepareSetIllegalGetQueryPlan(self): self.assertRaises(IllegalArgumentException, self.prepare_request.set_get_query_plan, 'IllegalGetQueryPlan') def testPrepareSetIllegalTimeout(self): self.assertRaises(IllegalArgumentException, self.prepare_request.set_timeout, 'IllegalTimeout') self.assertRaises(IllegalArgumentException, self.prepare_request.set_timeout, 0) self.assertRaises(IllegalArgumentException, self.prepare_request.set_timeout, -1) def testPrepareNoStatement(self): self.assertRaises(IllegalArgumentException, self.handle.prepare, self.prepare_request) def testPrepareGets(self): self.prepare_request.set_statement( self.prepare_statement).set_get_query_plan(True) self.assertEqual(self.prepare_request.get_statement(), self.prepare_statement) self.assertIsNone(self.prepare_request.get_compartment()) self.assertTrue(self.prepare_request.get_query_plan()) self.assertEqual(self.prepare_request.get_timeout(), timeout) def testPrepareIllegalRequest(self): self.assertRaises(IllegalArgumentException, self.handle.prepare, 'IllegalRequest') def testPrepareNormal(self): self.prepare_request.set_statement( self.prepare_statement).set_get_query_plan(True) result = self.handle.prepare(self.prepare_request) prepared_statement = result.get_prepared_statement() # test set illegal variable to the prepared statement self.assertRaises(IllegalArgumentException, prepared_statement.set_variable, 0, 0) # test set variable to the prepared statement set_vars = dict() set_vars['$fld_id'] = 0 set_vars['$fld_long'] = 2147483648 for var in set_vars: prepared_statement.set_variable(var, set_vars[var]) self._check_prepared_result(result, True, variables=set_vars) # test copy the prepared statement statement = prepared_statement.get_statement() copied_statement = prepared_statement.copy_statement() self.assertEqual(copied_statement.get_statement(), statement) self.assertEqual(copied_statement.get_query_plan(), prepared_statement.get_query_plan()) self.assertEqual(copied_statement.get_sql_text(), prepared_statement.get_sql_text()) self.assertIsNone(copied_statement.get_variables()) # test clear variables from the prepared statement prepared_statement.clear_variables() self.assertEqual(prepared_statement.get_statement(), statement) self.assertEqual(prepared_statement.get_variables(), {}) def testPrepareOrderBy(self): # test order by primary index field statement = ('SELECT fld_time FROM ' + table_name + ' ORDER BY fld_id') self.prepare_request.set_statement(statement) result = self.handle.prepare(self.prepare_request) self._check_prepared_result(result) # test order by secondary index field statement = ('SELECT fld_time FROM ' + table_name + ' ORDER BY fld_str') self.prepare_request.set_statement(statement).set_get_query_plan( True) result = self.handle.prepare(self.prepare_request) self._check_prepared_result(result, True) def testPrepareFuncMinMaxGroupBy(self): # test min function group by primary index field statement = ('SELECT min(fld_time) FROM ' + table_name + ' GROUP BY fld_id') self.prepare_request.set_statement(statement) result = self.handle.prepare(self.prepare_request) self._check_prepared_result(result) # test max function group by primary index field statement = ('SELECT max(fld_time) FROM ' + table_name + ' GROUP BY fld_id') self.prepare_request.set_statement(statement).set_get_query_plan( True) result = self.handle.prepare(self.prepare_request) self._check_prepared_result(result, True) # test min function group by secondary index field statement = ('SELECT min(fld_time) FROM ' + table_name + ' GROUP BY fld_str') self.prepare_request.set_statement(statement).set_get_query_plan( False) result = self.handle.prepare(self.prepare_request) self._check_prepared_result(result) # test max function group by secondary index field statement = ('SELECT max(fld_time) FROM ' + table_name + ' GROUP BY fld_str') self.prepare_request.set_statement(statement).set_get_query_plan( True) result = self.handle.prepare(self.prepare_request) self._check_prepared_result(result, True) def testPrepareFuncSumGroupBy(self): # test sum function group by primary index field statement = ('SELECT sum(fld_float) FROM ' + table_name + ' GROUP BY fld_id') self.prepare_request.set_statement(statement) result = self.handle.prepare(self.prepare_request) self._check_prepared_result(result) # test sum function group by secondary index field statement = ('SELECT sum(fld_float) FROM ' + table_name + ' GROUP BY fld_str') self.prepare_request.set_statement(statement).set_get_query_plan( True) result = self.handle.prepare(self.prepare_request) self._check_prepared_result(result, True) def testPrepareFuncAvgGroupBy(self): # test avg function group by primary index field statement = ('SELECT avg(fld_double) FROM ' + table_name + ' GROUP BY fld_id') self.prepare_request.set_statement(statement) result = self.handle.prepare(self.prepare_request) self._check_prepared_result(result) # test avg function group by secondary index field statement = ('SELECT avg(fld_double) FROM ' + table_name + ' GROUP BY fld_str') self.prepare_request.set_statement(statement).set_get_query_plan( True) result = self.handle.prepare(self.prepare_request) self._check_prepared_result(result, True) def testPrepareFuncCountGroupBy(self): # test count function group by primary index field statement = ('SELECT count(*) FROM ' + table_name + ' GROUP BY fld_id') self.prepare_request.set_statement(statement) result = self.handle.prepare(self.prepare_request) self._check_prepared_result(result) # test count function group by secondary index field statement = ('SELECT count(*) FROM ' + table_name + ' GROUP BY fld_str') self.prepare_request.set_statement(statement).set_get_query_plan( True) result = self.handle.prepare(self.prepare_request) self._check_prepared_result(result, True) def testPrepareOrderByWithLimit(self): statement = ('SELECT fld_str FROM ' + table_name + ' ORDER BY fld_str LIMIT 10') self.prepare_request.set_statement(statement).set_get_query_plan( True) result = self.handle.prepare(self.prepare_request) self._check_prepared_result(result, True) def testPrepareOrderByWithOffset(self): statement = ('DECLARE $offset INTEGER; SELECT fld_str FROM ' + table_name + ' ORDER BY fld_str OFFSET $offset') self.prepare_request.set_statement(statement) result = self.handle.prepare(self.prepare_request) self._check_prepared_result(result) def testPrepareFuncGeoNear(self): statement = ( 'SELECT fld_id, tb.fld_json.point FROM ' + table_name + ' tb WHERE geo_near(tb.fld_json.point, ' + '{"type": "point", "coordinates": [ 24.0175, 35.5156 ]}, 5000)') self.prepare_request.set_statement(statement) result = self.handle.prepare(self.prepare_request) self._check_prepared_result(result) def _check_prepared_result(self, result, has_query_plan=False, has_sql_text=True, variables=None): prepared_statement = result.get_prepared_statement() self.assertIsNotNone(prepared_statement) self.check_cost(result, 2, 2, 0, 0) # test get query plan from the prepared statement query_plan = prepared_statement.get_query_plan() (self.assertIsNotNone(query_plan) if has_query_plan else self.assertIsNone(query_plan)) # test get sql text from the prepared statement sql_text = prepared_statement.get_sql_text() (self.assertIsNotNone(sql_text) if has_sql_text else self.assertIsNone(sql_text)) # test get variables from the prepared statement self.assertEqual(prepared_statement.get_variables(), variables)
def _do_rate_limited_queries(self, num_seconds, read_limit, max_kb, single_partition, use_percent, use_external_limiters): """ Runs queries continuously for N seconds. Verify that the resultant RUs used match the given rate limit. """ start_time = int(round(time() * 1000)) end_time = start_time + num_seconds * 1000 read_units_used = 0 rlim = None wlim = None if not use_external_limiters: # Reset internal limiters so they don't have unused units. self.handle.get_client().reset_rate_limiters(table_name) else: rlim = SimpleRateLimiter(read_limit * use_percent / 100.0, 1) wlim = SimpleRateLimiter(read_limit * use_percent / 100.0, 1) prep_req = PrepareRequest() if single_partition: # Query based on single partition scanning. fld_id = int(random() * 500) prep_req.set_statement('SELECT * FROM ' + table_name + ' WHERE id = ' + str(fld_id)) else: # Query based on all partitions scanning. prep_req.set_statement('SELECT * FROM ' + table_name + ' WHERE name = "jane"') prep_res = self.handle.prepare(prep_req) self.assertTrue(prep_res.get_prepared_statement() is not None, 'Prepare statement failed.') read_units_used += prep_res.get_read_units() while True: """ We need a 20 second timeout because in some cases this is called on a table with 500 rows and 50RUs (uses 1000RUs = 20 seconds). """ query_req = QueryRequest().set_prepared_statement( prep_res).set_timeout(20000).set_read_rate_limiter( rlim).set_write_rate_limiter(wlim) if max_kb > 0: # Query with size limit. query_req.set_max_read_kb(max_kb) try: while True: res = self.handle.query(query_req) res.get_results() read_units_used += res.get_read_units() if query_req.is_done(): break except ReadThrottlingException: self.fail('Expected no throttling exceptions, got one.') except RequestTimeoutException: # This may happen for very small limit tests. pass if int(round(time() * 1000)) >= end_time: break num_seconds = (int(round(time() * 1000)) - start_time) / 1000 use_percent /= 100.0 rus = read_units_used / num_seconds expected_rus = read_limit * use_percent # For very small expected amounts, just verify within 1 RU. if (expected_rus < 4 and expected_rus - 1 <= rus <= expected_rus + 1): return if rus < expected_rus * 0.6 or rus > expected_rus * 1.5: self.fail('Queries: Expected around ' + str(expected_rus) + ' RUs, got ' + str(rus))
class TestPrepare(unittest.TestCase, TestBase): @classmethod def setUpClass(cls): TestBase.set_up_class() create_statement = ('CREATE TABLE ' + table_name + '(fld_id INTEGER, fld_long LONG, \ fld_float FLOAT, fld_double DOUBLE, fld_bool BOOLEAN, fld_str STRING, \ fld_bin BINARY, fld_time TIMESTAMP(3), fld_num NUMBER, fld_json JSON, \ fld_arr ARRAY(STRING), fld_map MAP(STRING), \ fld_rec RECORD(fld_id LONG, fld_bool BOOLEAN, fld_str STRING), \ PRIMARY KEY(fld_id)) USING TTL 1 HOURS') limits = TableLimits(5000, 5000, 50) create_request = TableRequest().set_statement( create_statement).set_table_limits(limits) cls._result = TestBase.table_request(create_request, State.ACTIVE) @classmethod def tearDownClass(cls): TestBase.tear_down_class() def setUp(self): TestBase.set_up(self) self.prepare_statement = ('SELECT fld_id FROM ' + table_name) self.prepare_request = PrepareRequest().set_timeout(timeout) def tearDown(self): TestBase.tear_down(self) def testPrepareSetIllegalStatement(self): self.prepare_request.set_statement('IllegalStatement') self.assertRaises(IllegalArgumentException, self.handle.prepare, self.prepare_request) self.prepare_request.set_statement( 'SELECT fld_id FROM IllegalTableName') self.assertRaises(TableNotFoundException, self.handle.prepare, self.prepare_request) def testPrepareSetIllegalTimeout(self): self.assertRaises(IllegalArgumentException, self.prepare_request.set_timeout, 'IllegalTimeout') self.assertRaises(IllegalArgumentException, self.prepare_request.set_timeout, 0) self.assertRaises(IllegalArgumentException, self.prepare_request.set_timeout, -1) def testPrepareNoStatement(self): self.assertRaises(IllegalArgumentException, self.handle.prepare, self.prepare_request) def testPrepareGets(self): self.prepare_request.set_statement(self.prepare_statement) self.assertEqual(self.prepare_request.get_statement(), self.prepare_statement) self.assertEqual(self.prepare_request.get_timeout(), timeout) def testPrepareIllegalRequest(self): self.assertRaises(IllegalArgumentException, self.handle.prepare, 'IllegalRequest') def testPrepareNormal(self): self.prepare_request.set_statement(self.prepare_statement) result = self.handle.prepare(self.prepare_request) prepared_statement = result.get_prepared_statement() self.assertIsNotNone(prepared_statement) self.assertEqual(result.get_read_kb(), 2) self.assertEqual(result.get_read_units(), 2) self.assertEqual(result.get_write_kb(), 0) self.assertEqual(result.get_write_units(), 0) # test PreparedStatement statement = prepared_statement.get_statement() self.assertIsNotNone(statement) # test set illegal variable to the prepared statement self.assertRaises(IllegalArgumentException, prepared_statement.set_variable, 0, 0) # test set variable to the prepared statement set_vars = dict() set_vars['$fld_id'] = 0 set_vars['$fld_long'] = 2147483648 for var in set_vars: prepared_statement.set_variable(var, set_vars[var]) # test get variables from the prepared statement get_vars = prepared_statement.get_variables() self.assertEqual(set_vars, get_vars) # test copy the prepared statement copied_statement = prepared_statement.copy_statement() self.assertEqual(copied_statement.get_statement(), statement) self.assertEqual(0, len(copied_statement.get_variables())) # test clear variables from the prepared statement prepared_statement.clear_variables() self.assertEqual(prepared_statement.get_statement(), statement) self.assertEqual(prepared_statement.get_variables(), {})