# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

from collections import defaultdict
from copy import deepcopy
from itertools import ifilter
from logging import getLogger
from random import shuffle, choice, randint, randrange

from tests.comparison.common import TableExprList, ValExpr, ValExprList, Table, Column
from tests.comparison.query_profile import DefaultProfile
from tests.comparison.funcs import (
    AGG_FUNCS,
    AggFunc,
    ANALYTIC_FUNCS,
    AnalyticFunc,
    And,
    Coalesce,
    Equals,
    Func,
    FUNCS,
    PartitionByClause,
    WindowBoundary,
    WindowClause)
from tests.comparison.db_types import (
    Boolean,
    Int,
    Float,
    TYPES)
from tests.comparison.query import (
    FromClause,
    GroupByClause,
    HavingClause,
    InlineView,
    JoinClause,
    LimitClause,
    OrderByClause,
    Query,
    SelectClause,
    SelectItem,
    Subquery,
    UnionClause,
    WhereClause,
    WithClause,
    WithClauseInlineView)

UNBOUNDED_PRECEDING = WindowBoundary.UNBOUNDED_PRECEDING
PRECEDING = WindowBoundary.PRECEDING
CURRENT_ROW = WindowBoundary.CURRENT_ROW
FOLLOWING = WindowBoundary.FOLLOWING
UNBOUNDED_FOLLOWING = WindowBoundary.UNBOUNDED_FOLLOWING

LOG = getLogger(__name__)


class QueryGenerator(object):

  def __init__(self, query_profile):
    self.profile = query_profile
    self.queries_under_construction = list()
    self.max_nested_query_count = None
    self.cur_id = 0

  def get_next_id(self):
    self.cur_id += 1
    return 'a' + str(self.cur_id)

  @property
  def current_query(self):
    if self.queries_under_construction:
      return self.queries_under_construction[-1]

  @property
  def root_query(self):
    if self.queries_under_construction:
      return self.queries_under_construction[0]

  def clear_state(self):
    # This function clears the state from the previous query.
    self.cur_id = 0
    self.profile.query = None
    self.max_nested_query_count = None

  def generate_statement(self,
      table_exprs,
      allow_with_clause=True,
      allow_union_clause=True,
      select_item_data_types=None,
      required_select_item_type=None,
      required_table_expr_col_type=None,
      require_aggregate=None,
      dml_table=None,
      table_alias_prefix='t'):
    '''Create a random query using various language features.

       The initial call to this method should only use tables in the table_exprs
       parameter, and not  inline views or WITH definitions. The other types of
       table exprs may be added as part of the query generation.

       Due to implementation limitations, nested queries are not distributed evenly by
       default even if the query profile assigns an equal likelihood of use to each
       possible nested query decision. This is because the implementation chooses nested
       queries in a fixed order (WITH -> FROM -> WHERE). For example if only one nested
       query were allowed and each clause had a 50% chance of using a subquery, the
       resulting set of generated queries would contain a subquery in the WITH clause
       50% of the time, in the FROM 25% of the time, and WHERE 12.5% of the time. If the
       max nested queries were two, it's most likely that the generated query would
       contain a WITH clause which has the second nested query within it....

       If select_item_data_types is specified it must be a sequence or iterable of
       DataType. The generated query.select_clause.select will have data types suitable
       for use in a UNION.

       required_select_item_type may be set to a DataType to force at least one of the
       SELECT items to be of the given type. This can be used to ensure that inline
       views will have at least one joinable column.

       required_table_expr_col_type may be set to ensure that at least one of the
       TableExprs used in the FROM clause will have a column of the given type. This
       can be used to unsure that a correlation condition can be made for a Subquery.

       require_aggregate can be set to True or False to force or disable the creation
       of an aggregate query. This is used during Subquery creation where the context
       may require an aggregate or non-aggregate.

       dml_table exists for kwargs compatibility with other statement generators but is
       ignored
    '''
    if not table_exprs:
      raise Exception("At least one TableExpr is needed")

    query = Query()
    query.parent = self.current_query
    self.queries_under_construction.append(query)
    self.profile.query = query

    # Make a copy so tables can be added if a WITH clause is used
    table_exprs = TableExprList(table_exprs)

    if self.max_nested_query_count is None:
      self.max_nested_query_count = self.profile.get_max_nested_query_count()
    elif self.max_nested_query_count == 0:
      raise Exception('Maximum nested query count exceeded')
    else:
      self.max_nested_query_count -= 1

    with_clause = None
    if allow_with_clause \
        and self.allow_more_nested_queries \
        and self.profile.use_with_clause():
      with_clause = self._create_with_clause(table_exprs)
      table_exprs.extend(with_clause.table_exprs)
      query.with_clause = with_clause

    from_clause = self._create_from_clause(
        table_exprs, table_alias_prefix, required_table_expr_col_type)
    query.from_clause = from_clause

    select_clause = self._create_select_clause(
        from_clause.visible_table_exprs,
        select_item_data_types,
        required_select_item_type,
        require_aggregate)
    query.select_clause = select_clause

    if self.profile.use_where_clause():
      query.where_clause = self._create_where_clause(
          from_clause.visible_table_exprs, table_alias_prefix)

    # If agg and non-agg SELECT items are present then a GROUP BY is required otherwise
    # it's optional and is effectively a "SELECT DISTINCT".
    if (select_clause.agg_items and select_clause.basic_items) \
        or (require_aggregate is None \
            and select_clause.basic_items \
            and not select_clause.analytic_items \
            and not select_clause.contains_approximate_types \
            and self.profile.use_group_by_clause()):
      group_by_items = [deepcopy(item) for item in select_clause.basic_items
                        if not item.val_expr.is_constant]
      # TODO: What if there are select_clause.analytic_items?
      if group_by_items:
        query.group_by_clause = GroupByClause(group_by_items)

    # Impala doesn't support DISTINCT with analytics or "SELECT DISTINCT" when
    # GROUP BY is used.
    if not select_clause.analytic_items \
        and not query.group_by_clause \
        and not select_clause.contains_approximate_types \
        and self.profile.use_distinct():
      if select_clause.agg_items:
        self._enable_distinct_on_random_agg_items(select_clause.agg_items)
      else:
        select_clause.distinct = True

    if self.profile.use_having_clause() \
        and (query.group_by_clause
             or (self.profile.use_having_without_groupby()
             and select_clause.agg_items)):
      basic_select_item_exprs = \
          ValExprList(item.val_expr for item in select_clause.basic_items)
      query.having_clause = self._create_having_clause(
          from_clause.visible_table_exprs, basic_select_item_exprs)

    if allow_union_clause \
        and self.allow_more_nested_queries \
        and self.profile.use_union_clause():
      data_type_candidates_by_base_type = defaultdict(list)
      for data_type in TYPES:
        data_type_candidates_by_base_type[data_type.get_base_type()].append(data_type)
      select_item_data_types = list()
      for select_item in select_clause.items:
        select_item_data_types.append(
            choice(data_type_candidates_by_base_type[select_item.val_expr.base_type]))
      query.union_clause = UnionClause(self.generate_statement(
          table_exprs,
          allow_with_clause=False,
          select_item_data_types=select_item_data_types))
      if select_clause.contains_approximate_types or any(
          q.select_clause.contains_approximate_types for q in query.union_clause.queries):
        query.union_clause.all = True
      else:
        query.union_clause.all = self.profile.use_union_all()

    self.queries_under_construction.pop()
    if self.queries_under_construction:
      self.profile.query = self.queries_under_construction[-1]
    else:
      self.clear_state()

    return query

  @property
  def allow_more_nested_queries(self):
    return self.max_nested_query_count > 0

  def _create_with_clause(self, table_exprs):
    # Make a copy so newly created tables can be added and made available for use in
    # future table definitions.
    table_exprs = TableExprList(table_exprs)
    with_clause_inline_views = TableExprList()
    for with_clause_inline_view_idx \
        in xrange(self.profile.get_with_clause_table_ref_count()):
      query = self.generate_statement(table_exprs,
                                      allow_with_clause=self.profile.use_nested_with())
      with_clause_alias_count = getattr(self.root_query, 'with_clause_alias_count', 0) + 1
      self.root_query.with_clause_alias_count = with_clause_alias_count
      with_clause_inline_view = \
          WithClauseInlineView(query, 'with_%s' % with_clause_alias_count)
      table_exprs.append(with_clause_inline_view)
      with_clause_inline_views.append(with_clause_inline_view)
      if not self.allow_more_nested_queries:
        break
    return WithClause(with_clause_inline_views)

  def _create_select_clause(self,
      table_exprs,
      select_item_data_types,
      required_select_item_type,
      require_aggregate):
    if select_item_data_types:
      select_item_data_types = tuple(select_item_data_types)
    if select_item_data_types \
        and required_select_item_type \
        and not issubclass(required_select_item_type, select_item_data_types):
      raise Exception('Required select item type is not in allowed types')

    # Generate column types for the select clause if not specified.
    if not select_item_data_types:
      select_item_data_types = []
      desired_item_count = self.profile.get_select_item_count()
      if required_select_item_type:
        select_item_data_types.append(required_select_item_type)
      while len(select_item_data_types) < desired_item_count:
        select_item_data_types.append(self.profile.choose_type(table_exprs.col_types))
      shuffle(select_item_data_types)
      select_item_data_types = tuple(select_item_data_types)

    # We want to assign BASIC, AGG or ANALYTIC to each column. We want to prevent GROUP BY
    # float_col, because the groupings will differ across databases because floats are
    # approximate values.
    column_categories = ['-' for _ in select_item_data_types]
    if require_aggregate:
      column_categories[randint(0, len(column_categories) - 1)] = 'AGG'
    # Assign AGG and ANALYTIC some columns
    for i in range(len(column_categories)):
      item_category = self.profile._choose_from_weights(
          self.profile.weights('SELECT_ITEM_CATEGORY'))
      if item_category in ('AGG', 'ANALYTIC'):
        column_categories[i] = item_category
    agg_present = 'AGG' in column_categories
    # Assign BASIC to the remaining columns
    for i in range(len(column_categories)):
      if column_categories[i] == '-':
        if select_item_data_types[i].is_approximate() and agg_present:
          column_categories[i] = 'AGG'
        else:
          # If AGG column is present, BASIC can only be assigned to a column if it's not a
          # Float.
          column_categories[i] = 'BASIC'

    select_items = []

    for i, column_category in enumerate(column_categories):
      if column_category == 'BASIC':
        select_items.append(self._create_basic_select_item(
          table_exprs, select_item_data_types[i]))
      else:
        select_items.append((column_category, select_item_data_types[i]))

    analytic_count = sum(1 for c in column_category if c == 'ANALYTIC')

    select_item_exprs = \
        ValExprList(item.val_expr for item in select_items if type(item) == SelectItem)
    for idx, item in enumerate(select_items):
      if type(item) == tuple and item[0] == 'AGG':
        select_items[idx] = \
            self._create_agg_select_item(table_exprs, select_item_exprs, item[1])

    for item in select_items:
      if type(item) == tuple:
        continue
      if item.is_agg:
        select_item_exprs.append(item.val_expr)
    for idx, item in enumerate(select_items):
      if type(item) == tuple:
        select_items[idx] = self._create_analytic_select_item(
            table_exprs,
            select_item_exprs,
            len(select_item_exprs) == 0 and analytic_count == 1,
            item[1])

    # So far all the SELECT items are defined and set but none of them have aliases. If
    # an item is a simple column reference, then it will only get an alias if there is a
    # conflict with another simple column ref. All other item types, such as functions
    # or constants, will always have an alias.
    #
    # item_names is the set of final names or aliases for each item in the SELECT list.
    item_names = set()
    for item in select_items:
      if not item.alias and not item.val_expr.is_col:
        continue
      if item.name in item_names:
        item.alias = '*CONFLICT*'
      else:
        item_names.add(item.name)

    # base_item_name_counts stores the number of conflicts that occurred for a name,
    # and hence the number of name to skip forward to create a non-conflicting name.
    base_item_name_counts = defaultdict(int)
    for item in select_items:
      if item.alias == '*CONFLICT*' or (not item.val_expr.is_col and not item.alias):
        # Use names close to the Impala functional test database so that bugs in
        # resolution will be more likely to surface.
        alias = base_alias = '%s_col' % item.type.__name__.lower()
        while alias in item_names:
          base_item_name_counts[base_alias] += 1
          alias = base_alias + '_' + str(base_item_name_counts[base_alias])
        item.alias = alias
        item_names.add(alias)
    return SelectClause(select_items)

  def _create_basic_select_item(self, table_exprs, return_type):
    max_children = self.profile.choose_nested_expr_count()
    if max_children:
      value = self.create_func_tree(return_type)
      value = self.populate_func_with_vals(value, table_exprs)
    elif return_type in table_exprs.col_types:
      value = self.profile.choose_val_expr(table_exprs.cols_by_type[return_type])
    else:
      value = self.profile.choose_constant(return_type)
    return SelectItem(value)

  def create_func_tree(self, return_type, allow_subquery=False):
    '''Returns an instance of a basic function that has all of it's arguments either set
       to None or another instance of a function that has it's arguments set likewise. The
       caller should replace the None values with column references or constants as
       desired. The depth of the tree is determined by the query profile (self.profile).
    '''
    signatures = self._funcs_to_allowed_signatures(FUNCS)
    root_signatures = self._find_matching_signatures(
        signatures, returns=return_type, allow_subquery=allow_subquery)
    root_signature = self.profile.choose_func_signature(root_signatures)
    func = root_signature.func(root_signature)   # An instance of a function
    max_children = self.profile.choose_nested_expr_count()
    if max_children:
      # Impala does not allow functions that contain subqueries to have arguments
      # that contain subqueries. Ex: ... WHERE (int_col IN (SELECT 1)) IN (SELECT TRUE)
      subquery_allowed_null_args = list()
      subquery_not_allowed_null_args = list()
      if func.contains_subquery:
        null_args = subquery_not_allowed_null_args
      else:
        null_args = subquery_allowed_null_args
      null_args.extend((func, idx) for idx, arg in enumerate(func.args)
                       if type(arg) != list and arg.val is None)
      while max_children \
          and (subquery_allowed_null_args or subquery_not_allowed_null_args):
        idx = randrange(
            len(subquery_allowed_null_args) + len(subquery_not_allowed_null_args))
        if idx < len(subquery_allowed_null_args):
          null_args = subquery_allowed_null_args
        else:
          null_args = subquery_not_allowed_null_args
        shuffle(null_args)
        parent_func, parent_arg_idx = null_args.pop()
        child_signatures = self._find_matching_signatures(
            signatures,
            returns=parent_func.args[parent_arg_idx].type,
            allow_subquery=(allow_subquery and null_args == subquery_allowed_null_args))
        child_signature = self.profile.choose_func_signature(child_signatures)
        child_func = child_signature.func(child_signature)
        parent_func.args[parent_arg_idx] = child_func
        if child_func.contains_subquery:
          null_args = subquery_not_allowed_null_args
        else:
          null_args = subquery_allowed_null_args
        null_args.extend((child_func, idx) for idx, arg in enumerate(child_func.args)
                         if type(arg) != list and arg.val is None)
        max_children -= 1
    return func

  def _funcs_to_allowed_signatures(self, funcs):
    '''Return a list of the signatures contained in "funcs" that are eligible for use
       based on the query profile.
    '''
    return [signature for func in funcs for signature in func.signatures()
            if self.profile.allow_func_signature(signature)]

  def _find_matching_signatures(self,
      signatures,
      returns=None,
      accepts=None,
      accepts_only=None,
      allow_subquery=False):
    '''Returns the subset of signatures matching the given criteria.
         returns: The signature must return this type.
         accepts: The signature must have at least one argument of this type.
         accepts_only: The signature must have arguments of only this type.
         allow_subquery: If False, the signature cannot contain a subquery.
    '''
    matching_signatures = list()
    for signature in signatures:
      if returns and not issubclass(signature.return_type, returns):
        continue
      if accepts and not any(not arg.is_subquery and issubclass(arg.type, accepts)
                             for arg in signature.args):
        continue
      if accepts_only and (not signature.args or any(
          not arg.is_subquery and not issubclass(arg.type, accepts_only)
          for arg in signature.args)):
        continue
      if not allow_subquery and any(arg.is_subquery for arg in signature.args):
        continue
      matching_signatures.append(signature)
    return matching_signatures

  def populate_func_with_vals(self,
      func,
      table_exprs=TableExprList(),
      val_exprs=ValExprList(),
      table_alias_prefix='',
      allow_subquery=False,
      _allow_table_exprs=None):
    if not _allow_table_exprs and func.is_agg:
      _allow_table_exprs = True
    elif _allow_table_exprs is None and func.contains_agg:
      _allow_table_exprs = False
    elif _allow_table_exprs is None:
      _allow_table_exprs = True
    # If a function's return type depends on some of its args then at least one of those
    # args must not be the NULL literal. Example: IF(false, NULL, NULL) is considered
    # invalid because the return type cannot be determined.
    has_non_null_literal_arg = False
    for idx, arg in enumerate(func.args):
      signature_arg = func.signature.args[idx]
      if signature_arg.is_subquery \
          or (allow_subquery \
              and self.allow_more_nested_queries \
              and self.profile.use_scalar_subquery()):
        usage = self.profile.choose_subquery_predicate_category(
            func.name(),
            self.current_query.from_clause.table_exprs.joinable_cols_by_type)
        if usage is not None \
            and self.allow_more_nested_queries \
            and (usage[1] == 'UNCORRELATED'
                or self.current_query.from_clause.table_exprs.joinable_cols_by_type):
          use_scalar_subquery = (usage[0] == 'Scalar')
          use_agg_subquery = (usage[1] == 'AGG')
          use_correlated_subquery = (usage[2] == 'CORRELATED')
          if use_correlated_subquery:
            # TODO: Sometimes this causes an exception because the list is empty
            join_expr_type = self.profile.choose_type(list(
                self.current_query.from_clause.table_exprs.joinable_cols_by_type))
          else:
            join_expr_type = None
          select_item_data_types = \
              [signature_arg.type] if use_scalar_subquery else signature_arg.type
          query = self.generate_statement(
              table_exprs,
              select_item_data_types=select_item_data_types,
              required_table_expr_col_type=join_expr_type,
              require_aggregate=use_agg_subquery,
              # Don't use UNION + LIMIT; IMPALA-1379
              allow_union_clause=(not signature_arg.is_subquery),
              table_alias_prefix=(table_alias_prefix +
                  ('t' if use_correlated_subquery else '')),
              allow_with_clause=self.profile.use_nested_with())
          if use_scalar_subquery and not use_agg_subquery:
            # Impala will assume the query will return more than one row unless a LIMIT 1
            # is added. An ORDER BY will also be added under the assumption that we want
            # deterministic results.
            query.order_by_clause = OrderByClause([Int(1)])
            query.limit_clause = LimitClause(Int(1))
          if use_correlated_subquery:
            outer_table_expr = choice(
                self.current_query.from_clause.table_exprs.by_col_type[join_expr_type])
            correlation_condition = self._create_relational_join_condition(
                outer_table_expr,
                query.from_clause.table_exprs.by_col_type[join_expr_type])
            if query.where_clause:
              query.where_clause.boolean_expr = And.create_from_args(
                  query.where_clause.boolean_expr, correlation_condition)
            else:
              query.where_clause = WhereClause(correlation_condition)
          func.args[idx] = Subquery(query)
        else:
          replacement_func = self.create_func_tree(func.type)
          return self.populate_func_with_vals(
              replacement_func,
              table_exprs=table_exprs,
              val_exprs=val_exprs,
              table_alias_prefix=table_alias_prefix,
              allow_subquery=allow_subquery,
              _allow_table_exprs=_allow_table_exprs)
      else:
        if arg.is_constant and arg.val is None:
          candidate_val_exprs = ValExprList()
          if val_exprs:
            candidate_val_exprs.extend(val_exprs.by_type[arg.type])
          if _allow_table_exprs:
            candidate_val_exprs.extend(table_exprs.cols_by_type[arg.type])
          if candidate_val_exprs:
            val = self.profile.choose_val_expr(candidate_val_exprs)
          else:
            val = self.profile.choose_constant(
                return_type=arg.type,
                allow_null=(signature_arg.can_be_null \
                    and signature_arg.can_be_null_literal \
                    and (has_non_null_literal_arg \
                        or not signature_arg.determines_signature)))
          func.args[idx] = val
          arg = val
        elif arg.is_func:
          func.args[idx] = self.populate_func_with_vals(
              arg,
              table_exprs=table_exprs,
              val_exprs=val_exprs,
              _allow_table_exprs=_allow_table_exprs)
        if not signature_arg.can_be_null and not arg.is_constant:
          val = self.profile.choose_constant(return_type=arg.type, allow_null=False)
          func.args[idx] = Coalesce.create_from_args(arg, val)
        if not arg.is_constant or arg.val is not None:
          has_non_null_literal_arg = True
    return func

  def _create_agg_select_item(self, table_exprs, basic_select_item_exprs, return_type):
    value = self._create_agg_func_tree(return_type)
    value = self.populate_func_with_vals(value, table_exprs, basic_select_item_exprs)
    return SelectItem(value)

  def _create_agg_func_tree(self, return_type):
    return self._create_agg_or_analytic_tree(return_type, agg_funcs=AGG_FUNCS)

  def _create_agg_or_analytic_tree(self, return_type, agg_funcs=[], analytic_funcs=[],
                                   basic_funcs=FUNCS):
    '''Returns an instance of a function that is guaranteed to either be or contain an
       aggregate or analytic function. The arguments of the returned function will either
       be None or an instance of a function as in create_func_tree.

       The chosen aggregate or analytic functions will be restricted to the list of
       functions in agg_funcs and analytic_funcs.

       If analytic_funcs is non-empty the returned function will be guaranteed to
       be an analytic or contain at least on analytic function.

       return_type must be set and refers to the data type of the function output.
       agg_funcs and analytic_funcs should be used to determine the class of the
       returned function. The caller is responsible for restricting the return_type
       to types that can be generated by permutations of available functions. If the max
       nested expr count in the query profile is at least one, then any return_type
       should be possible to generate but this is not guaranteed.

       basic_funcs is a list of allowed basic functions that will be used in the function
       tree. By default, all basic funcs defined in funcs.py will be allowed. A basic
       function is any non-aggregate, non-analytic function.
    '''
    # The creation of aggregate and analytic functions is so similar that they are
    # combined here. "basic" function creation is much simpler so that is kept separate.
    # What's going to happen is there will be essentially two important data structures:
    #
    #   1) A tree of functions, the root of which will be returned. The leaves of the
    #      tree are "place holders" which are actually instances of a concrete DataType,
    #      such as Int, with a value of None. In other words, the arguments to all
    #      functions are either other functions or SQL NULL.
    #
    #   2) A mapping to place holders from the type of function that they may be replaced
    #      with. The actual data structure is
    #      dict<func class> -> list<tuple<tree node, index of place holder in tree node>>
    #      where "func class" is one of "AggFunc", "AnalyticFunc" or "Func".
    #
    # This means once a child function is generated, a spot where it can be placed into
    # the tree can easily be identified. Although the work is actually done in reverse
    # order, a place holder is chosen, then a replacement is generated.
    if not agg_funcs and not analytic_funcs:
      raise Exception('At least one analytic or aggregate function is required')

    basic_signatures_by_return_type = self._group_signatures_by_return_type(
        self._find_matching_signatures(
            self._funcs_to_allowed_signatures(basic_funcs),
            allow_subquery=False))
    agg_signatures_by_return_type = self._group_signatures_by_return_type(
        self._funcs_to_allowed_signatures(agg_funcs))
    analytic_signatures_by_return_type = self._group_signatures_by_return_type(
        self._funcs_to_allowed_signatures(analytic_funcs))
    if analytic_funcs:
      return_class = AnalyticFunc
      return_signatures_by_return_type = analytic_signatures_by_return_type
    else:
      return_class = AggFunc
      return_signatures_by_return_type = agg_signatures_by_return_type

    min_children, max_children = self.profile.bounds('MAX_NESTED_EXPR_COUNT')
    if max_children == 0 and return_type not in return_signatures_by_return_type:
      raise Exception(('At least one child expr is required to create a %s expr'
          + ' using an %s function')
          % (return_type.__name__,
             'aggregate' if return_class == AggFunc else 'analytic'))
    if min_children == 0 and return_type not in return_signatures_by_return_type:
      min_children = 1
    max_children = self.profile._choose_from_bounds(min_children, max_children)

    if not max_children:
      signature = self.profile.choose_func_signature(
          return_signatures_by_return_type[return_type])
      return signature.func(signature)

    root_func = None

    # Every time a function is created its arguments will initially be NULL. Those NULL
    # arguments may be replaced by other functions up to "max_children". The types of
    # valid child functions depends on the type of parent function.
    #
    #  * Analytics may not contain other analytics
    #  * Analytics may contain aggregates or basic functions
    #  * Aggregates may not contain other aggregates or analytics
    #  * Aggregates may contain basic functions
    #  * Basic functions may contain any function so long as the above conditions are
    #    not broken (indirectly).
    null_args_by_func_allowed = {AggFunc: list(), AnalyticFunc: list(), Func: list()}
    while max_children:
      null_arg_pool = None
      parent_func, parent_arg_idx = None, None
      chosen_signature=None

      # Since aggregate (and let's assume analytic functions) return a limited set of
      # types, some prep work may be needed if the return type isn't in the set of
      # directly producible types. For example if a Boolean is desired and there are
      # only two children remaining, the next child must be something that accepts an
      # aggregate and returns a Boolean, such as GreaterThan.
      if (not root_func and max_children == 1) \
          or (root_func and max_children == 2 \
              and ((return_class == AggFunc and not root_func.contains_agg)
                  or (return_class == AnalyticFunc and not root_func.contains_analytic))):
        if root_func:
          idx = randrange(len(null_args_by_func_allowed[return_class])
              + len(null_args_by_func_allowed[Func]))
          use_return_class = idx < len(null_args_by_func_allowed[return_class])
          if use_return_class:
            null_arg_pool = null_args_by_func_allowed[return_class]
            signature_pools_by_return_type = return_signatures_by_return_type
          else:
            null_arg_pool = null_args_by_func_allowed[Func]
            signature_pools_by_return_type = basic_signatures_by_return_type
          shuffle(null_arg_pool)
          parent_func, parent_arg_idx = null_arg_pool.pop()
          parent_arg_type = parent_func.args[parent_arg_idx].type
          if use_return_class:
            signature_pool = signature_pools_by_return_type[parent_arg_type]
          else:
            # This is a basic functions so it needs to accept one of the types returned
            # by the desired return_class.
            signature_pool = self._find_matching_signatures(
                signature_pools_by_return_type[parent_arg_type],
                accepts=tuple(return_signatures_by_return_type))
        else:
          signature_pool = list()
          if return_type in return_signatures_by_return_type:
            signature_pool.extend(return_signatures_by_return_type[return_type])
          if return_type in basic_signatures_by_return_type:
            signature_pool.extend(self._find_matching_signatures(
                basic_signatures_by_return_type[return_type],
                accepts=tuple(return_signatures_by_return_type)))
        chosen_signature = self.profile.choose_func_signature(signature_pool)
      elif max_children == 1 \
          and ((return_class == AggFunc and not root_func.contains_agg)
              or (return_class == AnalyticFunc and not root_func.contains_analytic)):
        # This is the last iteration and the generated function still doesn't contain
        # an instance of the desired function class. From the setup above, at least
        # one of the available place holder arguments can be replaced by an aggregate or
        # analytic.
        null_arg_pool = null_args_by_func_allowed[return_class]
        if not null_arg_pool:
          raise Exception(
              'No leaves in the expr tree may be replaced by an %s function'
              % ('aggregate' if return_class == AggFunc else 'analytic'))
        shuffle(null_arg_pool)
        return_types = tuple(return_signatures_by_return_type)
        while null_arg_pool:
          parent_func, parent_arg_idx = null_arg_pool.pop()
          parent_arg_type = parent_func.args[parent_arg_idx].type
          if issubclass(parent_arg_type, return_types):
            break
          if not null_arg_pool:
            raise Exception('No functions could accept an %s function'
                % ('aggregate' if return_class == AggFunc else 'analytic'))
        chosen_signature = self.profile.choose_func_signature(
            return_signatures_by_return_type[parent_arg_type])
      elif not root_func:
        # No restrictions, just choose a root_func that returns the needed type.
        signature_pool = list()
        if return_type in return_signatures_by_return_type:
          signature_pool.extend(return_signatures_by_return_type[return_type])
        if return_type in basic_signatures_by_return_type:
          signature_pool.extend(basic_signatures_by_return_type[return_type])
        chosen_signature= self.profile.choose_func_signature(signature_pool)
      else:
        # A root_func was chosen and it's children are in one or more of the
        # null_args_by_func_allowed pools. A pool will be chosen, then a child function.
        null_arg_counts_by_pool = dict((pool_category, len(pool)) for pool_category, pool
                                       in null_args_by_func_allowed.iteritems())
        # There is a special case that would lead to a dead end. If there is only one
        # distinct place holder across all the pools and an analytic is still needed,
        # then that place holder cannot be replaced by an aggregate since aggregates
        # are not allowed to contain analytics. Example: an analytic is impossible once
        # the tree is FLOOR(AVG(NULL)).
        if return_class == AnalyticFunc \
            and not root_func.contains_analytic \
            and len(null_args_by_func_allowed[AnalyticFunc]) == 1 \
            and null_args_by_func_allowed[AnalyticFunc][0] \
                in null_args_by_func_allowed[AggFunc]:
          null_arg_counts_by_pool[AggFunc] = 0

        null_arg_pool_category = \
            self.profile._choose_from_weights(null_arg_counts_by_pool)
        null_arg_pool = null_args_by_func_allowed[null_arg_pool_category]
        shuffle(null_arg_pool)
        parent_func, parent_arg_idx = null_arg_pool.pop()
        parent_arg_type = parent_func.args[parent_arg_idx].type

        if null_arg_pool_category == AggFunc:
          signature_pool = agg_signatures_by_return_type[parent_arg_type]
        elif null_arg_pool_category == AnalyticFunc:
          signature_pool = analytic_signatures_by_return_type[parent_arg_type]
        else:
          signature_pool = basic_signatures_by_return_type[parent_arg_type]
        chosen_signature = self.profile.choose_func_signature(signature_pool)

      chosen_func = chosen_signature.func(chosen_signature)
      if root_func:
        max_children -= 1
      else:
        root_func = chosen_func

      if parent_func:
        # Remove the place holder from all of the other pools.
        for pool_category, pool in null_args_by_func_allowed.iteritems():
          for null_arg_idx, (func, arg_idx) in enumerate(pool):
            if func is parent_func and arg_idx == parent_arg_idx:
              del pool[null_arg_idx]

        # Replace the place holder with the child function
        parent_func.args[parent_arg_idx] = chosen_func
        parent_func.validate()
        chosen_func.parent = parent_func
      else:
        chosen_func.parent = None

      # Check if the func_tree contains any analytic functions returned by
      # profile.get_analytic_funcs_that_cannot_contain_aggs; if it does then aggregate
      # functions are not allowed in child operators
      allow_agg_func = not self._func_tree_contains_funcs(
          chosen_func, self.profile.get_analytic_funcs_that_cannot_contain_aggs())

      # Place the args of the chosen function into the appropriate pools. Aggregate and
      # analytic functions have different rules about which functions they accept as
      # arguments. If the chosen function is neither then the tree must be inspected to
      # find the first aggregate or analytic ancestor.
      child_null_arg_pools = set()
      node = chosen_func
      while True:
        if node.is_analytic:
          if allow_agg_func:
            child_null_arg_pools.add(AggFunc)
          child_null_arg_pools.add(Func)
          break
        elif node.is_agg:
          child_null_arg_pools.add(Func)
          break
        node = node.parent
        if not node:
          # This means the root_func is a non-aggregate and non-analytic, it can accept
          # anything.
          child_null_arg_pools.add(AggFunc)
          child_null_arg_pools.add(Func)
          if return_class == AnalyticFunc:
            child_null_arg_pools.add(AnalyticFunc)
          break
      for func_allowed in child_null_arg_pools:
        null_args = null_args_by_func_allowed[func_allowed]
        for idx, arg in enumerate(chosen_func.args):
          if arg.val is not None:
            # Some functions come with unusual arguments pre-populated.
            # Ex: The analytic function LEAD(foo, constant) will have "constant" non-NULL.
            continue
          if func_allowed == AggFunc:
            returnable_types = agg_signatures_by_return_type
          elif func_allowed == AnalyticFunc:
            returnable_types = analytic_signatures_by_return_type
          else:
            returnable_types = basic_signatures_by_return_type
          # Skip place holders that are impossible to replace. The function selection
          # logic depends on this.
          if arg.type not in returnable_types:
            continue
          null_args.append((chosen_func, idx))

      if not any(null_args_by_func_allowed.itervalues()):
        # Some analytic functions take no arguments. Ex: ROW_NUM()
        break

    if (return_class == AggFunc and not root_func.contains_agg) \
        or (return_class == AnalyticFunc and not root_func.contains_analytic):
      raise Exception('Unable to create an %s function'
          % ('aggregate' if return_class == AggFunc else 'analytic'))

    return root_func

  def _func_tree_contains_funcs(self, func_tree, funcs):
    """
    Returns True if any of the funcs are in the given func_tree. A func_tree must have
    a parent property defined that links to the parent function. This method compares
    functions based on their name.
    """
    if not funcs:
      return False
    node = func_tree
    func_names = set(func.name() for func in funcs)
    while node:
      if node.name() in func_names:
        return True
      node = node.parent
    return False

  def _create_analytic_select_item(self,
      table_exprs,
      select_item_exprs,
      is_only_item,
      return_type):
    '''Create and return a list of SelectItems where each item includes an anayltic
       function in its val_expr.

       table_exprs must be a non-empty collection of tables exprs to choose columns from.

       select_items may be an empty collection. If not empty, anayltic function
       expressions will be restricted so that PARTITION BY and ORDER BY values are
       chosen from within this set. If empty, any random expr may be chosen.

       is_only_item should be True if this analytic item will be the only SelectItem in
       the SELECT clause. When True, an additional analytic variation that would
       otherwise produce a non-deterministic result set is enabled.
    '''
    # Results may not be deterministic when analytics have an ORDER BY. The code below
    # will assume we want deterministic results though we know this may not be true
    # for certain use cases such as just searching for crashes where results will be
    # thrown away.
    #
    # These cases will produce a deterministic result when ORDER BY is used
    #
    #   1) There is only one SELECT item and the analytic function has no argument
    #      or the ORDER BY includes the argument.
    #
    #   2) The analytic has set of ORDER BY expressions that has a deterministic
    #      result. Ex: ORDER BY primary_key. This is only reliable if there are no
    #      JOINs.
    #
    #   3) A window is explicitly specified as UNBOUNDED PRECEDING to UNBOUNDED
    #      FOLLOWING and either the analytic function is an aggregate or the
    #      analytic function is FIRST_VALUE or LAST_VALUE.
    #
    #   4) RANK is a special case, it is intrinsically deterministic
    excluded_designs = list()
    if len(self.queries_under_construction) > 1:
      excluded_designs.append('TOP_LEVEL_QUERY_WITHOUT_LIMIT')
    if not is_only_item:
      excluded_designs.append('ONLY_ITEM')
    if len(table_exprs) == 1:
      unique_col_combos = []
      if table_exprs[0].unique_cols:
        if select_item_exprs:
          select_cols = set(val_expr for val_expr in select_item_exprs if val_expr.is_col)
          for unique_cols in table_exprs[0].unique_cols:
            if unique_cols <= select_cols:
              unique_col_combos.append(unique_cols)
        else:
          unique_col_combos = table_exprs[0].unique_cols
      if not unique_col_combos:
        excluded_designs.append('DETERMINISTIC_ORDER')
    else:
      excluded_designs.append('DETERMINISTIC_ORDER')

    allow_agg = any(ifilter(lambda expr: expr.contains_agg, select_item_exprs))
    value = self._create_analytic_func_tree(return_type, excluded_designs, allow_agg)
    value = self.populate_func_with_vals(
        value,
        table_exprs=TableExprList(),
        val_exprs=ValExprList())
    self._populate_analytic_clauses(value, table_exprs, select_item_exprs)
    return SelectItem(value)

  def _create_analytic_func_tree(self, return_type, excluded_designs, allow_agg):
    # The results of queries with analytic functions may not be deterministic. Let's
    # assume deterministic results are required. To generate deterministic results, the
    # structure of queries will be limited to one of several "designs". The goal of each
    # design is to ensure that results are deterministic. See the notes in
    # _create_analytic_select_item for more info on designs.
    designs = set(self.profile.allowed_analytic_designs())
    for design in excluded_designs:
      if design in designs:
        designs.remove(design)
    window_weigts = self.profile.weights('ANALYTIC_WINDOW')
    if 'UNBOUNDED_WINDOW' in designs \
        and window_weigts[('ROWS', UNBOUNDED_PRECEDING, UNBOUNDED_FOLLOWING)] == 0 \
        and window_weigts[('RANGE', UNBOUNDED_PRECEDING, UNBOUNDED_FOLLOWING)] == 0:
      designs.remove('UNBOUNDED_WINDOW')
    if not designs:
      raise Exception('No options for creating a deterministic analytic function are'
          ' available')

    available_funcs = list()
    for func in ANALYTIC_FUNCS:
      if 'TOP_LEVEL_QUERY_WITHOUT_LIMIT' in designs \
          or 'DETERMINISTIC_ORDER_BY' in designs \
          or 'ONLY_SELECT_ITEM' in designs \
          or ('RANK_FUNC' in designs and func.name() == 'Rank') \
          or ('NO_ORDER_BY' in designs and not func.REQUIRES_ORDER_BY) \
          or ('UNBOUNDED_WINDOW' in designs and func.SUPPORTS_WINDOWING):
        available_funcs.append(func)
    if not available_funcs:
      raise Exception('No analytic functions available')

    # In general this may be a tree-like val expr that is guaranteed to contain at least
    # one analytic function. The arguments to the function are already outlined but the
    # analytic clause is still undetermined.
    root_func = self._create_agg_or_analytic_tree(
        return_type,
        analytic_funcs=available_funcs,
        agg_funcs=(AGG_FUNCS if allow_agg else []))

    # The following designs are preferred because they place no restrictions on the
    # analytic. From now on, if "designs" is non-empty this means that a design must
    # be chosen.
    if 'TOP_LEVEL_QUERY_WITHOUT_LIMIT' in designs \
        or 'DETERMINISTIC_ORDER_BY' in designs \
        or 'ONLY_SELECT_ITEM' in designs:
      designs.clear()
    else:
      designs = list(designs)

    # Set the analytic clauses, such as PARTITION BY, etc, for each analytic function.
    analytic_funcs = list()
    if root_func.is_analytic:
      analytic_funcs.append(root_func)
    for func in root_func.iter_exprs(lambda expr: expr.is_analytic):
      analytic_funcs.append(func)
    for func in analytic_funcs:
      if designs:
        func.design = choice([design for design in designs
                              if design != 'RANK' or func.name() != 'Rank'])
      else:
        func.design = 'NO_RESTRICTIONS'

      use_window = (func.design == 'UNBOUNDED_WINDOW') \
          or (func.design != 'NO_ORDER_BY'
              and (func.SUPPORTS_WINDOWING and self.profile.use_window_in_analytic()))
      if use_window:
        window_range_or_rows, window_start_boundary_type, window_end_boundary_type \
            = self.profile.choose_window_type()
        if window_start_boundary_type in (PRECEDING, FOLLOWING):
          start_val = Int(self.profile._choose_from_bounds('ANALYTIC_WINDOW_OFFSET'))
        else:
          start_val = None
        if window_end_boundary_type in (PRECEDING, FOLLOWING):
          end_val = Int(self.profile.get_window_offset())
          if window_start_boundary_type == PRECEDING \
              and window_end_boundary_type == PRECEDING:
            if start_val.val < end_val.val:
              start_val, end_val = end_val, start_val
            elif start_val.val == end_val.val:
              end_val.val -= 1
          elif window_start_boundary_type == FOLLOWING \
              and window_end_boundary_type == FOLLOWING:
            if start_val.val > end_val.val:
              start_val, end_val = end_val, start_val
            elif start_val.val == end_val.val:
              start_val.val -= 1
        else:
          end_val = None
        func.window_clause = WindowClause(
            window_range_or_rows,
            WindowBoundary(window_start_boundary_type, start_val),
            WindowBoundary(window_end_boundary_type, end_val) \
                if window_end_boundary_type else None)

      if self.profile.use_partition_by_clause_in_analytic():
        func.partition_by_clause = PartitionByClause([])

      if (func.design == 'DETERMINISTIC_ORDER') \
          or use_window \
          or func.REQUIRES_ORDER_BY \
          or (func.design != 'NO_ORDER_BY' \
              and self.profile.use_order_by_clause_in_analytic()):
        func.order_by_clause = OrderByClause([])

      if func.name() in ('Lead', 'Lag') and len(func.args) == 2:
        func.args[1].val = self.profile.get_offset_for_analytic_lead_or_lag()

    return root_func

  def _group_signatures_by_return_type(self, signatures):
    groups = defaultdict(list)
    for signature in signatures:
      groups[signature.return_type].append(signature)
    return dict(groups)

  def _populate_analytic_clauses(self, func, table_exprs, val_exprs):
    for arg in func.args:
      if arg.is_func:
        self._populate_analytic_clauses(arg, table_exprs, val_exprs)
    if func.is_analytic:
      if func.design == 'DETERMINISTIC_ORDER':
        unique_cols = shuffle(list(choice(table_exprs[0].unique_cols)))
      else:
        unique_cols = list()

      if func.partition_by_clause:
        if len(unique_cols) > 1:
          func.partition_by_clause.val_exprs.append(unique_cols.pop())
        elif len(val_exprs) > 1:
          shuffle(val_exprs)
          func.partition_by_clause.val_exprs.append(val_exprs[0])
        else:
          func.partition_by_clause = None

      if func.order_by_clause:
        if unique_cols:
          order_by_exprs = unique_cols
        elif val_exprs:
          order_by_exprs = val_exprs[:2]
        else:
          cols = list(table_exprs.cols)
          shuffle(cols)
          order_by_exprs = cols[:2]
        for order_by_expr in order_by_exprs:
          func.order_by_clause.exprs_to_order.append(
              (order_by_expr, choice([None, 'ASC', 'DESC', 'DESC'])))

  def _create_from_clause(self,
      table_exprs,
      table_alias_prefix,
      required_table_expr_col_type):
    from_clause = None
    table_count = self.profile.get_table_count()

    candidate_table_exprs = TableExprList(table_exprs)
    candidate_table_exprs.extend(candidate_table_exprs.collections)
    # If filter out table expressions with no scalar columns.
    candidate_table_exprs = TableExprList(
        table_expr for table_expr in candidate_table_exprs if table_expr.cols)

    if required_table_expr_col_type:
      candidate_table_exprs = \
          candidate_table_exprs.by_col_type[required_table_expr_col_type]
      if not candidate_table_exprs:
        raise Exception('No tables have the required column type')

    if table_count > 1:
      # If there are multiple multiple tables, the first chosen table must have joinable
      # columns.
      candidate_table_exprs = TableExprList(
          table_expr for table_expr in candidate_table_exprs
          if table_expr.joinable_cols_by_type)
      if not candidate_table_exprs:
        raise Exception('No tables have any joinable types')
      required_type = self.profile.choose_type(
          candidate_table_exprs.joinable_cols_by_type)
    else:
      required_type = None
    table_expr = self._create_table_expr(candidate_table_exprs,
        required_type=required_type)
    table_expr.alias = self.get_next_id()
    from_clause = FromClause(table_expr)

    for idx in xrange(1, table_count):
      join_clause = self._create_join_clause(from_clause, table_exprs)
      join_clause.table_expr.alias = self.get_next_id()
      from_clause.join_clauses.append(join_clause)

    return from_clause

  def _create_table_expr(self, table_exprs, required_type=None):
    if not table_exprs:
      raise Exception('At least one table_expr is required')
    if self.allow_more_nested_queries and self.profile.use_inline_view():
      return self._create_inline_view(table_exprs, required_type=required_type)
    if required_type:
      candidiate_table_exprs = TableExprList()
      for table_expr in table_exprs:
        for col in table_expr.cols:
          if issubclass(col.type, required_type):
            candidiate_table_exprs.append(table_expr)
            break
      if not candidiate_table_exprs:
        raise Exception('No tables have a column with the required data type')
      table_exprs = candidiate_table_exprs
    return deepcopy(self.profile.choose_table(table_exprs))

  def _create_inline_view(self, table_exprs, required_type=None):
    return InlineView(self.generate_statement(
        table_exprs, required_select_item_type=required_type,
        allow_with_clause=self.profile.use_nested_with()))

  def _create_join_clause(self, from_clause, table_exprs):
    join_type = self.profile.choose_join_type(JoinClause.JOINS_TYPES)
    use_lateral = self.profile.use_lateral_join()
    correlated_collections = from_clause.collections
    if use_lateral and correlated_collections:
      # TODO: Add correlated collections from ancestor queries
      if self.allow_more_nested_queries and self.profile.use_inline_view():
        collection = self._create_inline_view(correlated_collections)
      else:
        collection = deepcopy(choice(correlated_collections))
      join_clause = JoinClause(join_type, table_expr=collection)
      join_clause.is_lateral_join = True
      for _ in range(self.profile.get_num_boolean_exprs_for_lateral_join()):
        predicate = self._create_single_join_condition(collection, from_clause.table_exprs)
        if not predicate:
          break
        join_clause.boolean_expr = And.create_from_args(join_clause.boolean_expr,
            predicate) if join_clause.boolean_expr else predicate
      return join_clause
    else:
      candidate_table_exprs = TableExprList(table_exprs)
      candidate_table_exprs.extend(candidate_table_exprs.collections)
      if join_type == 'CROSS':
        table_expr = self._create_table_expr(candidate_table_exprs)
      else:
        available_join_expr_types = set(from_clause.table_exprs.joinable_cols_by_type) \
            & set(candidate_table_exprs.col_types)
        if not available_join_expr_types:
          raise Exception('No tables have any columns eligible for joining')
        join_expr_type = self.profile.choose_type(tuple(available_join_expr_types))
        table_expr = self._create_table_expr(
            candidate_table_exprs, required_type=join_expr_type)

      if join_type in ('LEFT ANTI', 'LEFT SEMI'):
        table_expr.is_visible = False

      join_clause = JoinClause(join_type, table_expr)

      if join_type == 'CROSS':
        return join_clause

      join_table_expr_candidates = from_clause.table_exprs.by_col_type[join_expr_type]
      if not join_table_expr_candidates:
        raise Exception('table_expr has no common joinable columns')
      join_clause.boolean_expr = self._create_relational_join_condition(
          table_expr, join_table_expr_candidates)
      return join_clause

  def _get_joinable_cols_in_common(self, table_expr, other_table_expr):
    common_col_types = set(table_expr.joinable_cols_by_type) \
        & set(other_table_expr.joinable_cols_by_type)
    return common_col_types

  _has_joinable_cols_in_common = _get_joinable_cols_in_common

  def _create_single_join_condition(self, cur_table_expr, available_table_exprs):
    candidates = []
    for possible_table_expr in available_table_exprs:
      if self._has_joinable_cols_in_common(cur_table_expr, possible_table_expr):
        candidates.append(possible_table_expr)

    if not candidates:
      return None

    target_table_expr = choice(candidates)
    common_col_types = set(cur_table_expr.joinable_cols_by_type) \
        & set(target_table_expr.joinable_cols_by_type)

    col_type = choice(list(common_col_types))
    left_col = choice(cur_table_expr.joinable_cols_by_type[col_type])
    right_col = choice(target_table_expr.joinable_cols_by_type[col_type])
    return Equals.create_from_args(left_col, right_col)

  def _create_relational_join_condition(self,
      right_table_expr, possible_left_table_exprs):
    assert possible_left_table_exprs

    table_exprs_by_col_types = defaultdict(list)
    candidiate_table_exprs = list()

    for left_table_expr in possible_left_table_exprs:
      joinable_col_types = self._get_joinable_cols_in_common(
          right_table_expr, left_table_expr)
      if joinable_col_types:
        for col_type in joinable_col_types:
          table_exprs_by_col_types[col_type].append(left_table_expr)
          candidiate_table_exprs.append(left_table_expr)
    if not table_exprs_by_col_types:
      raise Exception('Tables have no joinable columns in common')

    join_signatures = self._funcs_to_allowed_signatures(FUNCS)
    if self.profile.only_use_equality_join_predicates():
      join_signatures = [sig for sig in join_signatures if not
          self.profile.is_non_equality_join_predicate(sig.func)]
    else:
      join_signatures = self.profile.get_allowed_join_signatures(join_signatures)

    root_predicate, relational_predicates = self._create_boolean_func_tree(
      require_relational_func=True,
      relational_col_types=table_exprs_by_col_types.keys(),
      allowed_signatures=join_signatures)

    for predicate in relational_predicates:
      left_table_expr = choice(candidiate_table_exprs)
      joinable_col_types = self._get_joinable_cols_in_common(
          right_table_expr, left_table_expr)

      left_null_args = self._populate_null_args_list(
          predicate, tuple(joinable_col_types), arg_stop_idx=1)
      arg_idx, func = choice(left_null_args)
      arg_type = func.args[arg_idx].type
      func.args[arg_idx] = choice(left_table_expr.cols_by_type[arg_type])

      right_null_args = self._populate_null_args_list(
          predicate, tuple(joinable_col_types), arg_start_idx=1)
      arg_idx, func = choice(right_null_args)
      arg_type = func.args[arg_idx].type
      func.args[arg_idx] = choice(right_table_expr.cols_by_type[arg_type])

    table_exprs = TableExprList(possible_left_table_exprs)
    table_exprs.append(right_table_expr)
    self.populate_func_with_vals(root_predicate, table_exprs=table_exprs)
    return root_predicate

  def _populate_null_args_list(self,
      func,
      allowed_types,  # Only allow args of this type in the result list.
      arg_start_idx=0,  # Start at this arg index, only applies to "func".
      arg_stop_idx=None,  # Stop at this arg index, only applies to "func".
      null_args=None):  # Used internally for recursion.
    '''Walks through func and creates a list of function arguments that are null. The
       returned list contains tuples with values (arg index, parent func).
    '''
    if arg_stop_idx is None:
      arg_stop_idx = len(func.args)
    if arg_stop_idx < arg_start_idx:
      raise Exception("'arg_stop_idx' (%s) cannot be less than 'arg_start_idx' (%s)"
          % (arg_stop_idx, arg_start_idx))
    if null_args is None:
      null_args = list()
    for idx in xrange(arg_start_idx, arg_stop_idx):
      arg = func.args[idx]
      if arg.is_constant and issubclass(arg.type, allowed_types):
        assert arg.val is None
        null_args.append((idx, func))
      elif arg.is_func:
        self._populate_null_args_list(arg, allowed_types, null_args=null_args)
    return null_args

  def _create_where_clause(self,
      table_exprs,
      table_alias_prefix):
    predicate, _ = self._create_boolean_func_tree(allow_subquery=True)
    predicate = self.populate_func_with_vals(
        predicate,
        table_exprs=table_exprs,
        table_alias_prefix=table_alias_prefix)
    if predicate.contains_subquery and not table_exprs[0].alias:
      # TODO: Figure out if an alias is really needed.
      table_exprs[0].alias = self.get_next_id()
    return WhereClause(predicate)

  def _create_having_clause(self, table_exprs, basic_select_item_exprs):
    if self.profile.only_use_aggregates_in_having_clause():
      predicate = self._create_agg_func_tree(Boolean)
    else:
      predicate, _ = self._create_boolean_func_tree()
    predicate = self.populate_func_with_vals(
        predicate, val_exprs=basic_select_item_exprs)
    # IMPALA-1423
    # Make sure any cols used have a table identifier. As of this writing the only
    # single table FROM clauses don't use table aliases. Setting a table alias
    # automatically propagates as a column table identifier ("t1.col" instead of "col").
    for arg in predicate.iter_exprs():
      if isinstance(arg, ValExpr) and arg.is_col and not arg.owner.alias:
        # TODO: Figure out if an alias is really needed.
        arg.owner.alias = self.get_next_id()
    return HavingClause(predicate)

  def _enable_distinct_on_random_agg_items(self, agg_items):
    '''For each agg function, set it to be DISTINCT with some probability'''
    def _enable_distinct_helper(val_expr):
      if val_expr.is_agg:
        if self.profile.use_distinct_in_func():
          val_expr.distinct = True
      elif val_expr.is_func:
        for arg in val_expr.args:
          _enable_distinct_helper(arg)

    for item in agg_items:
      _enable_distinct_helper(item.val_expr)

  def _create_boolean_func_tree(self, require_relational_func=False,
                                relational_col_types=None, allow_subquery=False,
                                allowed_signatures=None):
    '''Creates a function that returns a Boolean. The returned value is a
       Tuple<Function, List<Function>> 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 arguments may be other functions
       depending on the query profile in use. The leaf arguments of the tree will all be
       set to a NULL literal.

       Args:
         require_relational_func: If True, at least one function in the tree will be a
         relational function such as Equals, LessThanOrEquals, etc.

         relational_col_types: Can be used to restrict the signature of the chosen
         relational function to the given types.

         allow_subquery: If True, a subquery may be added to the function tree.

         allowed_signatures: A list of allowable signatures to be used inside the function
         tree. This list is not definitive, functions outside this list may be added to
         the function tree if they are explicitly added by the QueryProfile.
    '''
    # To create a realistic expression, the nodes nearest the root of the tree will be
    # ANDs and ORs, their children will be relational functions, then other number of
    # functions requested by the profile will be added as children of the relational
    # functions. There is no requirement that all children of ANDs and ORs will be
    # relational functions so a wide variety of queries should be generated.

    # Determine the number of non-leaf nodes in the tree.
    if require_relational_func:
      # Just assume this is for a JOIN.
      func_count = self.profile.choose_join_condition_count()
      if func_count <= 0:
        raise Exception("Relational condition count must be greater than zero")
    else:
      func_count = self.profile.choose_nested_expr_count() + 1

    and_or_fill_ratio = self.profile.choose_conjunct_disjunct_fill_ratio()
    and_or_count = int(and_or_fill_ratio * func_count)
    if and_or_count == func_count and require_relational_func:
      # Leave a space for a relational function.
      and_or_count -= 1

    relational_fill_ratio = self.profile.choose_relational_func_fill_ratio()
    relational_count = int(relational_fill_ratio * (func_count - and_or_count))
    if relational_count > and_or_count + 1:
      # Reduce the AND/OR count to the number of boolean spaces that are guaranteed to
      # exist.
      relational_count = and_or_count + 1
    elif relational_count == 0 and require_relational_func:
      relational_count = 1

    root_func = None   # The root of the function tree.
    relational_funcs = list()  # These will be in the tree somewhere.

    # After a root function is chosen, each additional function will be chosen based on
    # the types required by the leaves (existing unused function args). For example if
    # the current tree is
    #      And
    #     /   \
    #   And  Equals(Int, Int)
    # Then the next function chosen must either return a Boolean or an Int. The dict
    # below tracks which arg types are available.
    #
    # In the example above, assuming Equals was chosen as a relational function, the
    # children of Equals must preserve the Int arg if the caller requested Ints using
    # 'relational_col_types'.
    null_args_by_type = defaultdict(list)

    if not allowed_signatures:
      allowed_signatures = self._funcs_to_allowed_signatures(FUNCS)

    if not relational_col_types:
      relational_col_types = tuple()

    for _ in xrange(func_count):
      is_relational = False

      if and_or_count > 0:
        and_or_count -= 1
        func_class = self.profile.choose_conjunct_disjunct()
        signature = self.profile.choose_func_signature(func_class.signatures())
      elif relational_count > 0:
        relational_count -= 1
        is_relational = True
        relational_signatures = self._find_matching_signatures(
          allowed_signatures, accepts_only=tuple(relational_col_types), returns=Boolean)
        signature = self.profile.choose_relational_func_signature(relational_signatures)
      else:
        if not root_func or Boolean in null_args_by_type:
          # Prefer to replace Boolean leaves to get a more realistic expression.
          return_type = Boolean
        else:
          return_type = choice(null_args_by_type.keys())
        # Rather than track if this is a child of a relational function, in which case
        # the arg type needs to be preserved, just always assume that this is a child of
        # a relational function.
        accepts = return_type if return_type in relational_col_types else None
        matching_signatures = self._find_matching_signatures(
            allowed_signatures, returns=return_type, accepts=accepts,
            allow_subquery=allow_subquery)
        if matching_signatures:
          signature = self.profile.choose_func_signature(matching_signatures)
        else:
          continue

      func = signature.func(signature)
      if root_func:
        null_args = null_args_by_type[signature.return_type]
        shuffle(null_args)
        parent_func, parent_arg_idx = null_args.pop()
        parent_func.args[parent_arg_idx] = func
        if not null_args:
          del null_args_by_type[signature.return_type]
      else:
        root_func = func

      if is_relational:
        relational_funcs.append(func)

      for idx, arg in enumerate(func.args):
        if signature.args[idx].is_subquery:
          continue
        null_args = null_args_by_type[arg.type]
        null_args.append((func, idx))
      if not null_args_by_type:
        # Subqueries might not provide leaves, so stopping early may be necessary. Ex
        # WHERE EXISTS(...).
        assert func.contains_subquery
        break

    return root_func, relational_funcs


def generate_queries_for_manual_inspection():
  '''Generate some queries for manual inspection. The query won't run anywhere because the
     tables used are fake. To make real queries, we'd need to connect to a database and
     read the table metadata and such.
  '''
  from model_translator import SqlWriter

  NUM_TABLES = 5
  NUM_COLS_EACH_TYPE = 10
  NUM_QUERIES = 3000

  tables = list()
  data_types = list(TYPES)
  data_types.remove(Float)
  for table_idx in xrange(NUM_TABLES):
    table = Table('table_%s' % table_idx)
    tables.append(table)
    cols = table.cols
    col_idx = 0
    for _ in xrange(NUM_COLS_EACH_TYPE):
      for col_type in data_types:
        col = Column(table, '%s_col_%s' % (col_type.__name__.lower(), col_idx), col_type)
        cols.append(col)
        col_idx += 1
    table.cols = cols

  query_profile = DefaultProfile()
  query_generator = QueryGenerator(query_profile)
  sql_writer = SqlWriter.create(dialect='IMPALA')
  ref_writer = SqlWriter.create(dialect='POSTGRESQL',
      nulls_order_asc=query_profile.nulls_order_asc())
  for _ in xrange(NUM_QUERIES):
    query = query_generator.generate_statement(tables)
    print("Test db")
    print(sql_writer.write_query(query) + '\n')
    print("Ref db")
    print(ref_writer.write_query(query) + '\n')


if __name__ == '__main__':
  generate_queries_for_manual_inspection()
