Example #1
0
 def _determine_opening_parenthesis_type(self, token: SQLToken):
     """
     Determines the type of left parenthesis in query
     """
     if token.previous_token.normalized in SUBQUERY_PRECEDING_KEYWORDS:
         # inside subquery / derived table
         token.is_subquery_start = True
         self._subquery_level += 1
         token.subquery_level = self._subquery_level
     elif token.previous_token.normalized in KEYWORDS_BEFORE_COLUMNS.union({","}):
         # we are in columns and in a column subquery definition
         token.is_column_definition_start = True
     elif (
         token.previous_token.is_as_keyword
         and token.last_keyword_normalized != "WINDOW"
     ):
         # window clause also contains AS keyword, but it is not a query
         token.is_with_query_start = True
     elif (
         token.last_keyword_normalized == "TABLE"
         and token.find_nearest_token("(") is EmptyToken
     ):
         token.is_create_table_columns_declaration_start = True
     elif token.previous_token.normalized == "OVER":
         token.is_partition_clause_start = True
     else:
         # nested function
         token.is_nested_function_start = True
         self._nested_level += 1
         self._is_in_nested_function = True
     self._open_parentheses.append(token)
     self._parenthesis_level += 1
Example #2
0
 def _add_to_columns_aliases_subsection(self, token: SQLToken):
     """
     Add alias to the section in which it appears in query
     """
     keyword = token.last_keyword_normalized
     alias = token.left_expanded
     if (
         token.last_keyword_normalized in ["FROM", "WITH"]
         and token.find_nearest_token("(").is_with_columns_start
     ):
         keyword = "SELECT"
     section = COLUMNS_SECTIONS[keyword]
     self._columns_aliases_dict = self._columns_aliases_dict or dict()
     self._columns_aliases_dict.setdefault(section, UniqueList()).append(alias)
Example #3
0
 def _resolve_function_alias(self, token: SQLToken) -> Union[str, List[str]]:
     # it can be one function or a chain of functions
     # like: sum(a) + sum(b) as alias
     # or operation on columns like: col1 + col2 as alias
     start_token = token.find_nearest_token(
         [",", "SELECT"], value_attribute="normalized"
     )
     while start_token.is_in_nested_function:
         start_token = start_token.find_nearest_token(
             [",", "SELECT"], value_attribute="normalized"
         )
     return self._find_all_columns_between_tokens(
         start_token=start_token, end_token=token
     )
Example #4
0
 def _handle_with_name_save(token: SQLToken, with_names: List[str]) -> None:
     if token.is_right_parenthesis:
         # inside columns of with statement
         # like: with (col1, col2) as (subquery)
         token.is_with_columns_end = True
         token.is_nested_function_end = False
         start_token = token.find_nearest_token("(")
         start_token.is_with_columns_start = True
         start_token.is_nested_function_start = False
         prev_token = start_token.previous_token
         prev_token.token_type = TokenType.WITH_NAME
         with_names.append(prev_token.value)
     else:
         token.token_type = TokenType.WITH_NAME
         with_names.append(token.value)
Example #5
0
 def _find_column_for_with_column_alias(self, token: SQLToken) -> str:
     start_token = token.find_nearest_token(
         True, direction="right", value_attribute="is_with_query_start"
     )
     if start_token not in self._with_columns_candidates:
         end_token = start_token.find_nearest_token(
             True, direction="right", value_attribute="is_with_query_end"
         )
         columns = self._find_all_columns_between_tokens(
             start_token=start_token, end_token=end_token
         )
         self._with_columns_candidates[start_token] = columns
     if isinstance(self._with_columns_candidates[start_token], list):
         alias_of = self._with_columns_candidates[start_token].pop(0)
     else:
         alias_of = self._with_columns_candidates[start_token]
     return alias_of
Example #6
0
    def _resolve_subquery_alias(self, token: SQLToken) -> Union[str, List[str]]:
        # nested subquery like select a, (select a as b from x) as column
        start_token = token.find_nearest_token(
            True, value_attribute="is_column_definition_start"
        )
        if start_token.next_token.normalized == "SELECT":
            # we have a subquery
            alias_token = start_token.next_token.find_nearest_token(
                self._aliases_to_check,
                direction="right",
                value_attribute="value",
            )
            return self._resolve_alias_to_column(alias_token)

        # chain of functions or redundant parenthesis
        return self._find_all_columns_between_tokens(
            start_token=start_token, end_token=token
        )