示例#1
0
    private Type getOperator(
        AnalysisContext context,
        Expression node,
        OperatorType operatorType,
        Expression... arguments) {
      ImmutableList.Builder<Type> argumentTypes = ImmutableList.builder();
      for (Expression expression : arguments) {
        argumentTypes.add(process(expression, context));
      }

      Signature operatorSignature;
      try {
        operatorSignature = functionRegistry.resolveOperator(operatorType, argumentTypes.build());
      } catch (OperatorNotFoundException e) {
        throw new SemanticException(TYPE_MISMATCH, node, e.getMessage());
      }

      for (int i = 0; i < arguments.length; i++) {
        Expression expression = arguments[i];
        Type type = typeManager.getType(operatorSignature.getArgumentTypes().get(i));
        coerceType(
            context,
            expression,
            type,
            String.format("Operator %s argument %d", operatorSignature, i));
      }

      Type type = typeManager.getType(operatorSignature.getReturnType());
      expressionTypes.put(node, type);

      return type;
    }
 private ReflectionParametricScalar(
     Signature signature,
     String description,
     boolean hidden,
     Map<Signature, Implementation> exactImplementations,
     List<Implementation> specializedImplementations,
     List<Implementation> implementations,
     boolean deterministic) {
   super(
       signature.getName(),
       signature.getTypeParameterRequirements(),
       signature.getReturnType().toString(),
       signature
           .getArgumentTypes()
           .stream()
           .map(TypeSignature::toString)
           .collect(toImmutableList()));
   this.description = description;
   this.hidden = hidden;
   this.exactImplementations =
       ImmutableMap.copyOf(requireNonNull(exactImplementations, "exactImplementations is null"));
   this.specializedImplementations =
       ImmutableList.copyOf(
           requireNonNull(specializedImplementations, "specializedImplementations is null"));
   this.implementations =
       ImmutableList.copyOf(requireNonNull(implementations, "implementations is null"));
   this.deterministic = deterministic;
 }
 public MethodHandleAndConstructor specialize(
     Signature boundSignature,
     Map<String, Type> boundTypeParameters,
     TypeManager typeManager,
     FunctionRegistry functionRegistry) {
   for (Map.Entry<String, Class<?>> entry : specializedTypeParameters.entrySet()) {
     if (!entry
         .getValue()
         .isAssignableFrom(boundTypeParameters.get(entry.getKey()).getJavaType())) {
       return null;
     }
   }
   Class<?> returnContainerType =
       getNullAwareContainerType(
           typeManager.getType(boundSignature.getReturnType()).getJavaType(), nullable);
   if (!returnContainerType.equals(methodHandle.type().returnType())) {
     return null;
   }
   for (int i = 0; i < boundSignature.getArgumentTypes().size(); i++) {
     Class<?> argumentContainerType =
         getNullAwareContainerType(
             typeManager.getType(boundSignature.getArgumentTypes().get(i)).getJavaType(),
             nullableArguments.get(i));
     if (!argumentNativeContainerTypes.get(i).isAssignableFrom(argumentContainerType)) {
       return null;
     }
   }
   MethodHandle methodHandle = this.methodHandle;
   for (ImplementationDependency dependency : dependencies) {
     methodHandle =
         methodHandle.bindTo(
             dependency.resolve(boundTypeParameters, typeManager, functionRegistry));
   }
   MethodHandle constructor = null;
   if (this.constructor.isPresent()) {
     constructor = this.constructor.get();
     for (ImplementationDependency dependency : constructorDependencies) {
       constructor =
           constructor.bindTo(
               dependency.resolve(boundTypeParameters, typeManager, functionRegistry));
     }
   }
   return new MethodHandleAndConstructor(methodHandle, Optional.ofNullable(constructor));
 }
示例#4
0
  public static Expression toExpression(Object object, Type type) {
    requireNonNull(type, "type is null");

    if (object instanceof Expression) {
      return (Expression) object;
    }

    if (object == null) {
      if (type.equals(UNKNOWN)) {
        return new NullLiteral();
      }
      return new Cast(new NullLiteral(), type.getTypeSignature().toString(), false, true);
    }

    checkArgument(
        Primitives.wrap(type.getJavaType()).isInstance(object),
        "object.getClass (%s) and type.getJavaType (%s) do not agree",
        object.getClass(),
        type.getJavaType());

    if (type.equals(BIGINT)) {
      return new LongLiteral(object.toString());
    }

    if (type.equals(DOUBLE)) {
      Double value = (Double) object;
      // WARNING: the ORC predicate code depends on NaN and infinity not appearing in a tuple
      // domain, so
      // if you remove this, you will need to update the TupleDomainOrcPredicate
      if (value.isNaN()) {
        return new FunctionCall(new QualifiedName("nan"), ImmutableList.<Expression>of());
      } else if (value.equals(Double.NEGATIVE_INFINITY)) {
        return ArithmeticUnaryExpression.negative(
            new FunctionCall(new QualifiedName("infinity"), ImmutableList.<Expression>of()));
      } else if (value.equals(Double.POSITIVE_INFINITY)) {
        return new FunctionCall(new QualifiedName("infinity"), ImmutableList.<Expression>of());
      } else {
        return new DoubleLiteral(object.toString());
      }
    }

    if (type instanceof VarcharType) {
      if (object instanceof String) {
        object = Slices.utf8Slice((String) object);
      }

      if (object instanceof Slice) {
        Slice value = (Slice) object;
        int length = SliceUtf8.countCodePoints(value);

        if (length == ((VarcharType) type).getLength()) {
          return new StringLiteral(value.toStringUtf8());
        }

        return new Cast(
            new StringLiteral(value.toStringUtf8()), type.getDisplayName(), false, true);
      }

      throw new IllegalArgumentException(
          "object must be instance of Slice or String when type is VARCHAR");
    }

    if (type.equals(BOOLEAN)) {
      return new BooleanLiteral(object.toString());
    }

    if (object instanceof Block) {
      SliceOutput output = new DynamicSliceOutput(((Block) object).getSizeInBytes());
      BlockSerdeUtil.writeBlock(output, (Block) object);
      object = output.slice();
      // This if condition will evaluate to true: object instanceof Slice && !type.equals(VARCHAR)
    }

    if (object instanceof Slice) {
      // HACK: we need to serialize VARBINARY in a format that can be embedded in an expression to
      // be
      // able to encode it in the plan that gets sent to workers.
      // We do this by transforming the in-memory varbinary into a call to
      // from_base64(<base64-encoded value>)
      FunctionCall fromBase64 =
          new FunctionCall(
              new QualifiedName("from_base64"),
              ImmutableList.of(
                  new StringLiteral(VarbinaryFunctions.toBase64((Slice) object).toStringUtf8())));
      Signature signature = FunctionRegistry.getMagicLiteralFunctionSignature(type);
      return new FunctionCall(new QualifiedName(signature.getName()), ImmutableList.of(fromBase64));
    }

    Signature signature = FunctionRegistry.getMagicLiteralFunctionSignature(type);
    Expression rawLiteral = toExpression(object, FunctionRegistry.typeForMagicLiteral(type));

    return new FunctionCall(new QualifiedName(signature.getName()), ImmutableList.of(rawLiteral));
  }
示例#5
0
    @Override
    protected Type visitFunctionCall(FunctionCall node, AnalysisContext context) {
      if (node.getWindow().isPresent()) {
        for (Expression expression : node.getWindow().get().getPartitionBy()) {
          process(expression, context);
          Type type = expressionTypes.get(expression);
          if (!type.isComparable()) {
            throw new SemanticException(
                TYPE_MISMATCH,
                node,
                "%s is not comparable, and therefore cannot be used in window function PARTITION BY",
                type);
          }
        }

        for (SortItem sortItem : node.getWindow().get().getOrderBy()) {
          process(sortItem.getSortKey(), context);
          Type type = expressionTypes.get(sortItem.getSortKey());
          if (!type.isOrderable()) {
            throw new SemanticException(
                TYPE_MISMATCH,
                node,
                "%s is not orderable, and therefore cannot be used in window function ORDER BY",
                type);
          }
        }

        if (node.getWindow().get().getFrame().isPresent()) {
          WindowFrame frame = node.getWindow().get().getFrame().get();

          if (frame.getStart().getValue().isPresent()) {
            Type type = process(frame.getStart().getValue().get(), context);
            if (!type.equals(BIGINT)) {
              throw new SemanticException(
                  TYPE_MISMATCH,
                  node,
                  "Window frame start value type must be BIGINT (actual %s)",
                  type);
            }
          }

          if (frame.getEnd().isPresent() && frame.getEnd().get().getValue().isPresent()) {
            Type type = process(frame.getEnd().get().getValue().get(), context);
            if (!type.equals(BIGINT)) {
              throw new SemanticException(
                  TYPE_MISMATCH,
                  node,
                  "Window frame end value type must be BIGINT (actual %s)",
                  type);
            }
          }
        }
      }

      ImmutableList.Builder<TypeSignature> argumentTypes = ImmutableList.builder();
      for (Expression expression : node.getArguments()) {
        argumentTypes.add(process(expression, context).getTypeSignature());
      }

      Signature function =
          functionRegistry.resolveFunction(
              node.getName(), argumentTypes.build(), context.isApproximate());
      for (int i = 0; i < node.getArguments().size(); i++) {
        Expression expression = node.getArguments().get(i);
        Type type = typeManager.getType(function.getArgumentTypes().get(i));
        requireNonNull(type, format("Type %s not found", function.getArgumentTypes().get(i)));
        if (node.isDistinct() && !type.isComparable()) {
          throw new SemanticException(
              TYPE_MISMATCH,
              node,
              "DISTINCT can only be applied to comparable types (actual: %s)",
              type);
        }
        coerceType(
            context, expression, type, String.format("Function %s argument %d", function, i));
      }
      resolvedFunctions.put(node, function);

      Type type = typeManager.getType(function.getReturnType());
      expressionTypes.put(node, type);

      return type;
    }