/** Throws a validation error if a DISTINCT or ALL quantifier is present but not allowed. */
 protected void validateQuantifier(SqlValidator validator, SqlCall call) {
   if ((null != call.getFunctionQuantifier()) && !isQuantifierAllowed()) {
     throw validator.newValidationError(
         call.getFunctionQuantifier(),
         EigenbaseResource.instance()
             .FunctionQuantifierNotAllowed
             .ex(call.getOperator().getName()));
   }
 }
Beispiel #2
0
 public RelNode convertSqlToRel(String sql) {
   Util.pre(sql != null, "sql != null");
   final SqlNode sqlQuery;
   try {
     sqlQuery = parseQuery(sql);
   } catch (Exception e) {
     throw Util.newInternal(e); // todo: better handling
   }
   final RelDataTypeFactory typeFactory = getTypeFactory();
   final Prepare.CatalogReader catalogReader = createCatalogReader(typeFactory);
   final SqlValidator validator = createValidator(catalogReader, typeFactory);
   final SqlToRelConverter converter =
       createSqlToRelConverter(validator, catalogReader, typeFactory);
   converter.setTrimUnusedFields(true);
   final SqlNode validatedQuery = validator.validate(sqlQuery);
   final RelNode rel = converter.convertQuery(validatedQuery, false, true);
   Util.post(rel != null, "return != null");
   return rel;
 }
 public void validate(SqlValidator validator, SqlValidatorScope scope) {
   validator.validateDynamicParam(this);
 }
  private RelDataType deriveType(
      SqlValidator validator,
      SqlValidatorScope scope,
      SqlCall call,
      boolean convertRowArgToColumnList) {
    final SqlNode[] operands = call.operands;
    RelDataType[] argTypes = new RelDataType[operands.length];

    // Scope for operands. Usually the same as 'scope'.
    final SqlValidatorScope operandScope = scope.getOperandScope(call);

    // Indicate to the validator that we're validating a new function call
    validator.pushFunctionCall();

    try {
      boolean containsRowArg = false;
      for (int i = 0; i < operands.length; ++i) {
        RelDataType nodeType;

        // for row arguments that should be converted to ColumnList
        // types, set the nodeType to a ColumnList type but defer
        // validating the arguments of the row constructor until we know
        // for sure that the row argument maps to a ColumnList type
        if (operands[i].getKind() == SqlKind.ROW && convertRowArgToColumnList) {
          containsRowArg = true;
          RelDataTypeFactory typeFactory = validator.getTypeFactory();
          nodeType = typeFactory.createSqlType(SqlTypeName.COLUMN_LIST);
        } else {
          nodeType = validator.deriveType(operandScope, operands[i]);
        }
        validator.setValidatedNodeType(operands[i], nodeType);
        argTypes[i] = nodeType;
      }

      SqlFunction function =
          SqlUtil.lookupRoutine(
              validator.getOperatorTable(), getNameAsId(), argTypes, getFunctionType());

      // if we have a match on function name and parameter count, but
      // couldn't find a function with  a COLUMN_LIST type, retry, but
      // this time, don't convert the row argument to a COLUMN_LIST type;
      // if we did find a match, go back and revalidate the row operands
      // (corresponding to column references), now that we can set the
      // scope to that of the source cursor referenced by that ColumnList
      // type
      if (containsRowArg) {
        if ((function == null)
            && SqlUtil.matchRoutinesByParameterCount(
                validator.getOperatorTable(), getNameAsId(), argTypes, getFunctionType())) {
          // remove the already validated node types corresponding to
          // row arguments before revalidating
          for (SqlNode operand : operands) {
            if (operand.getKind() == SqlKind.ROW) {
              validator.removeValidatedNodeType(operand);
            }
          }
          return deriveType(validator, scope, call, false);
        } else if (function != null) {
          validator.validateColumnListParams(function, argTypes, operands);
        }
      }

      if (getFunctionType() == SqlFunctionCategory.UserDefinedConstructor) {
        return validator.deriveConstructorType(scope, call, this, function, argTypes);
      }
      if (function == null) {
        validator.handleUnresolvedFunction(call, this, argTypes);
      }

      // REVIEW jvs 25-Mar-2005:  This is, in a sense, expanding
      // identifiers, but we ignore shouldExpandIdentifiers()
      // because otherwise later validation code will
      // choke on the unresolved function.
      call.setOperator(function);
      return function.validateOperands(validator, operandScope, call);
    } finally {
      validator.popFunctionCall();
    }
  }
 /**
  * Validates this node in an expression context.
  *
  * <p>Usually, this method does much the same as {@link #validate}, but a {@link SqlIdentifier}
  * can occur in expression and non-expression contexts.
  */
 public void validateExpr(SqlValidator validator, SqlValidatorScope scope) {
   validate(validator, scope);
   Util.discard(validator.deriveType(scope, this));
 }