quickstep-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From zuyu <...@git.apache.org>
Subject [GitHub] incubator-quickstep pull request #39: QUICKSTEP-20: Resolver support for Win...
Date Thu, 23 Jun 2016 23:26:03 GMT
Github user zuyu commented on a diff in the pull request:

    https://github.com/apache/incubator-quickstep/pull/39#discussion_r68332715
  
    --- Diff: query_optimizer/resolver/Resolver.cpp ---
    @@ -2471,6 +2679,154 @@ E::ScalarPtr Resolver::resolveFunctionCall(
       return E::ToRef(aggregate_alias);
     }
     
    +E::ScalarPtr Resolver::resolveWindowAggregateFunction(
    +    const ParseFunctionCall &parse_function_call,
    +    ExpressionResolutionInfo *expression_resolution_info) {
    +  if (!expression_resolution_info->window_aggregation_info->window_aggregate_expressions.empty())
{
    +    THROW_SQL_ERROR_AT(&parse_function_call)
    +       << "Currently we only support single window aggregate in the query";
    +  }
    +
    +  std::string function_name = ToLower(parse_function_call.name()->value());
    +
    +  // First check for the special case COUNT(*).
    +  bool count_star = false;
    +  if (parse_function_call.star() != nullptr) {
    +    if (function_name != "count") {
    +      THROW_SQL_ERROR_AT(parse_function_call.star())
    +          << "Only COUNT can have star (*) as an argument";
    +    }
    +    count_star = true;
    +  }
    +
    +  std::vector<E::ScalarPtr> resolved_arguments;
    +  const PtrList<ParseExpression> *unresolved_arguments =
    +      parse_function_call.arguments();
    +  // The first aggregate function in the arguments.
    +  const ParseTreeNode *first_aggregate_function = nullptr;
    +  const ParseTreeNode *first_window_aggregate_function = nullptr;
    +  if (unresolved_arguments != nullptr) {
    +    for (const ParseExpression &unresolved_argument : *unresolved_arguments) {
    +      ExpressionResolutionInfo expr_resolution_info(
    +          *expression_resolution_info);
    +      resolved_arguments.push_back(
    +          resolveExpression(unresolved_argument,
    +                            nullptr,  // No Type hint.
    +                            &expr_resolution_info));
    +
    +      // We don't allow aggregate or window aggregate nested in a window
    +      // aggregate function.
    +      if (expr_resolution_info.hasAggregate() &&
    +          first_aggregate_function == nullptr) {
    +        first_aggregate_function =
    +            expr_resolution_info.parse_aggregate_expression;
    +      }
    +
    +      if (expr_resolution_info.hasWindowAggregate() &&
    +          first_window_aggregate_function == nullptr) {
    +        first_window_aggregate_function =
    +            expr_resolution_info.parse_window_aggregate_expression;
    +      }
    +    }
    +  }
    +
    +  if (count_star && !resolved_arguments.empty()) {
    +    THROW_SQL_ERROR_AT(&parse_function_call)
    +        << "COUNT aggregate has both star (*) and non-star arguments.";
    +  }
    +
    +  // Try to look up the AggregateFunction by name using
    +  // AggregateFunctionFactory.
    +  const ::quickstep::AggregateFunction *window_aggregate
    +      = AggregateFunctionFactory::GetByName(function_name);
    +  if (window_aggregate == nullptr) {
    +    THROW_SQL_ERROR_AT(&parse_function_call)
    +        << "Unrecognized function name \""
    +        << parse_function_call.name()->value()
    +        << "\"";
    +  }
    +
    +  // Make sure aggregates are allowed in this context.
    +  if (first_aggregate_function != nullptr) {
    +    THROW_SQL_ERROR_AT(first_aggregate_function)
    +        << "Window aggregation of aggregates is not allowed";
    +  }
    +
    +  // TODO(Shixuan): We currently don't support nested window aggregation since
    +  // TPC-DS doesn't have that. However, it is essentially a nested scalar
    +  // function, which should be supported in the future version of Quickstep.
    +  if (first_window_aggregate_function != nullptr) {
    +    THROW_SQL_ERROR_AT(first_window_aggregate_function)
    +        << "Window aggregation of window aggregates is not allowed";
    +  }
    +
    +  // Make sure a naked COUNT() with no arguments wasn't specified.
    +  if ((window_aggregate->getAggregationID() == AggregationID::kCount)
    +      && (resolved_arguments.empty())
    +      && (!count_star)) {
    +    THROW_SQL_ERROR_AT(&parse_function_call)
    +        << "COUNT aggregate requires an argument (either scalar or star (*))";
    +  }
    +
    +  // Resolve each of the Scalar arguments to the aggregate.
    +  std::vector<const Type*> argument_types;
    +  for (const E::ScalarPtr &argument : resolved_arguments) {
    +    argument_types.emplace_back(&argument->getValueType());
    +  }
    +
    +  // Make sure that the aggregate can apply to the specified argument(s).
    +  if (!window_aggregate->canApplyToTypes(argument_types)) {
    +    THROW_SQL_ERROR_AT(&parse_function_call)
    +        << "Aggregate function " << window_aggregate->getName()
    +        << " can not apply to the given argument(s).";
    +  }
    +
    +  // A window aggregate function might be defined OVER a window name or a window.
    +  E::WindowAggregateFunctionPtr window_aggregate_function;
    +  if (parse_function_call.window_name() != nullptr) {
    +    std::unordered_map<std::string, WindowPlan> window_map
    +        = expression_resolution_info->window_aggregation_info->window_map;
    +    std::string window_name = parse_function_call.window_name()->value();
    +    std::unordered_map<std::string, WindowPlan>::const_iterator map_it
    +        = window_map.find(window_name);
    +
    +    if (map_it == window_map.end()) {
    +      THROW_SQL_ERROR_AT(parse_function_call.window_name())
    +        << "Undefined window " << window_name;
    --- End diff --
    
    Code style: please add two more whitespace indentations.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

Mime
View raw message