Creates a function that returns a Boolean. The returned value is a Tuple > where the first function is the root of the tree and the list contains relational functions (though other relational functions may also be in the tree). The root function's argumen
(self, require_relational_func=False,
relational_col_types=None, allow_subquery=False,
allowed_signatures=None)
| 1345 | _enable_distinct_helper(item.val_expr) |
| 1346 | |
| 1347 | def _create_boolean_func_tree(self, require_relational_func=False, |
| 1348 | relational_col_types=None, allow_subquery=False, |
| 1349 | allowed_signatures=None): |
| 1350 | '''Creates a function that returns a Boolean. The returned value is a |
| 1351 | Tuple<Function, List<Function>> where the first function is the root of the tree |
| 1352 | and the list contains relational functions (though other relational functions |
| 1353 | may also be in the tree). The root function's arguments may be other functions |
| 1354 | depending on the query profile in use. The leaf arguments of the tree will all be |
| 1355 | set to a NULL literal. |
| 1356 | |
| 1357 | Args: |
| 1358 | require_relational_func: If True, at least one function in the tree will be a |
| 1359 | relational function such as Equals, LessThanOrEquals, etc. |
| 1360 | |
| 1361 | relational_col_types: Can be used to restrict the signature of the chosen |
| 1362 | relational function to the given types. |
| 1363 | |
| 1364 | allow_subquery: If True, a subquery may be added to the function tree. |
| 1365 | |
| 1366 | allowed_signatures: A list of allowable signatures to be used inside the function |
| 1367 | tree. This list is not definitive, functions outside this list may be added to |
| 1368 | the function tree if they are explicitly added by the QueryProfile. |
| 1369 | ''' |
| 1370 | # To create a realistic expression, the nodes nearest the root of the tree will be |
| 1371 | # ANDs and ORs, their children will be relational functions, then other number of |
| 1372 | # functions requested by the profile will be added as children of the relational |
| 1373 | # functions. There is no requirement that all children of ANDs and ORs will be |
| 1374 | # relational functions so a wide variety of queries should be generated. |
| 1375 | |
| 1376 | # Determine the number of non-leaf nodes in the tree. |
| 1377 | if require_relational_func: |
| 1378 | # Just assume this is for a JOIN. |
| 1379 | func_count = self.profile.choose_join_condition_count() |
| 1380 | if func_count <= 0: |
| 1381 | raise Exception("Relational condition count must be greater than zero") |
| 1382 | else: |
| 1383 | func_count = self.profile.choose_nested_expr_count() + 1 |
| 1384 | |
| 1385 | and_or_fill_ratio = self.profile.choose_conjunct_disjunct_fill_ratio() |
| 1386 | and_or_count = int(and_or_fill_ratio * func_count) |
| 1387 | if and_or_count == func_count and require_relational_func: |
| 1388 | # Leave a space for a relational function. |
| 1389 | and_or_count -= 1 |
| 1390 | |
| 1391 | relational_fill_ratio = self.profile.choose_relational_func_fill_ratio() |
| 1392 | relational_count = int(relational_fill_ratio * (func_count - and_or_count)) |
| 1393 | if relational_count > and_or_count + 1: |
| 1394 | # Reduce the AND/OR count to the number of boolean spaces that are guaranteed to |
| 1395 | # exist. |
| 1396 | relational_count = and_or_count + 1 |
| 1397 | elif relational_count == 0 and require_relational_func: |
| 1398 | relational_count = 1 |
| 1399 | |
| 1400 | root_func = None # The root of the function tree. |
| 1401 | relational_funcs = list() # These will be in the tree somewhere. |
| 1402 | |
| 1403 | # After a root function is chosen, each additional function will be chosen based on |
| 1404 | # the types required by the leaves (existing unused function args). For example if |
no test coverage detected