Java Code Examples for org.apache.calcite.util.Util#last()

The following examples show how to use org.apache.calcite.util.Util#last() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: SqlValidatorUtil.java    From calcite with Apache License 2.0 6 votes vote down vote up
/**
 * Finds a {@link org.apache.calcite.jdbc.CalciteSchema.TypeEntry} in a
 * given schema whose type has the given name, possibly qualified.
 *
 * @param rootSchema root schema
 * @param typeName name of the type, may be qualified or fully-qualified
 *
 * @return TypeEntry with a table with the given name, or null
 */
public static CalciteSchema.TypeEntry getTypeEntry(
    CalciteSchema rootSchema, SqlIdentifier typeName) {
  final String name;
  final List<String> path;
  if (typeName.isSimple()) {
    path = ImmutableList.of();
    name = typeName.getSimple();
  } else {
    path = Util.skipLast(typeName.names);
    name = Util.last(typeName.names);
  }
  CalciteSchema schema = rootSchema;
  for (String p : path) {
    if (schema == rootSchema
        && SqlNameMatchers.withCaseSensitive(true).matches(p, schema.getName())) {
      continue;
    }
    schema = schema.getSubSchema(p, true);
  }
  return schema == null ? null : schema.getType(name, false);
}
 
Example 2
Source File: SqlValidatorUtil.java    From calcite with Apache License 2.0 6 votes vote down vote up
/**
 * Derives an alias for a node, and invents a mangled identifier if it
 * cannot.
 *
 * <p>Examples:
 *
 * <ul>
 * <li>Alias: "1 + 2 as foo" yields "foo"
 * <li>Identifier: "foo.bar.baz" yields "baz"
 * <li>Anything else yields "expr$<i>ordinal</i>"
 * </ul>
 *
 * @return An alias, if one can be derived; or a synthetic alias
 * "expr$<i>ordinal</i>" if ordinal &lt; 0; otherwise null
 */
public static String getAlias(SqlNode node, int ordinal) {
  switch (node.getKind()) {
  case AS:
    // E.g. "1 + 2 as foo" --> "foo"
    return ((SqlCall) node).operand(1).toString();

  case OVER:
    // E.g. "bids over w" --> "bids"
    return getAlias(((SqlCall) node).operand(0), ordinal);

  case IDENTIFIER:
    // E.g. "foo.bar" --> "bar"
    return Util.last(((SqlIdentifier) node).names);

  default:
    if (ordinal < 0) {
      return null;
    } else {
      return SqlUtil.deriveAliasFromOrdinal(ordinal);
    }
  }
}
 
Example 3
Source File: RexLiteral.java    From calcite with Apache License 2.0 6 votes vote down vote up
private String intervalString(BigDecimal v) {
  final List<TimeUnit> timeUnits = getTimeUnits(type.getSqlTypeName());
  final StringBuilder b = new StringBuilder();
  for (TimeUnit timeUnit : timeUnits) {
    final BigDecimal[] result = v.divideAndRemainder(timeUnit.multiplier);
    if (b.length() > 0) {
      b.append(timeUnit.separator);
    }
    final int width = b.length() == 0 ? -1 : width(timeUnit); // don't pad 1st
    pad(b, result[0].toString(), width);
    v = result[1];
  }
  if (Util.last(timeUnits) == TimeUnit.MILLISECOND) {
    while (b.toString().matches(".*\\.[0-9]*0")) {
      if (b.toString().endsWith(".0")) {
        b.setLength(b.length() - 2); // remove ".0"
      } else {
        b.setLength(b.length() - 1); // remove "0"
      }
    }
  }
  return b.toString();
}
 
Example 4
Source File: RexLiteralImpl.java    From Bats with Apache License 2.0 6 votes vote down vote up
private String intervalString(BigDecimal v) {
    final List<TimeUnit> timeUnits = getTimeUnits(type.getSqlTypeName());
    final StringBuilder b = new StringBuilder();
    for (TimeUnit timeUnit : timeUnits) {
        final BigDecimal[] result = v.divideAndRemainder(timeUnit.multiplier);
        if (b.length() > 0) {
            b.append(timeUnit.separator);
        }
        final int width = b.length() == 0 ? -1 : width(timeUnit); // don't pad 1st
        pad(b, result[0].toString(), width);
        v = result[1];
    }
    if (Util.last(timeUnits) == TimeUnit.MILLISECOND) {
        while (b.toString().matches(".*\\.[0-9]*0")) {
            if (b.toString().endsWith(".0")) {
                b.setLength(b.length() - 2); // remove ".0"
            } else {
                b.setLength(b.length() - 1); // remove "0"
            }
        }
    }
    return b.toString();
}
 
Example 5
Source File: RexInterpreter.java    From Bats with Apache License 2.0 6 votes vote down vote up
private Comparable case_(List<Comparable> values) {
    final int size;
    final Comparable elseValue;
    if (values.size() % 2 == 0) {
        size = values.size();
        elseValue = N;
    } else {
        size = values.size() - 1;
        elseValue = Util.last(values);
    }
    for (int i = 0; i < size; i += 2) {
        if (values.get(i).equals(true)) {
            return values.get(i + 1);
        }
    }
    return elseValue;
}
 
Example 6
Source File: SqlUserDefinedAggFunction.java    From calcite with Apache License 2.0 5 votes vote down vote up
/** Creates a SqlUserDefinedAggFunction. */
public SqlUserDefinedAggFunction(SqlIdentifier opName,
    SqlReturnTypeInference returnTypeInference,
    SqlOperandTypeInference operandTypeInference,
    SqlOperandTypeChecker operandTypeChecker, AggregateFunction function,
    boolean requiresOrder, boolean requiresOver,
    Optionality requiresGroupOrder, RelDataTypeFactory typeFactory) {
  super(Util.last(opName.names), opName, SqlKind.OTHER_FUNCTION,
      returnTypeInference, operandTypeInference, operandTypeChecker,
      SqlFunctionCategory.USER_DEFINED_FUNCTION, requiresOrder, requiresOver,
      requiresGroupOrder);
  this.function = function;
  this.typeFactory = typeFactory;
}
 
Example 7
Source File: SqlValidatorImpl.java    From Flink-CEPplus with Apache License 2.0 5 votes vote down vote up
private Pair<String, String> findTableColumnPair(SqlIdentifier identifier,
	SqlValidatorScope scope) {
	SqlCall call = SqlUtil.makeCall(getOperatorTable(), identifier);
	if (call != null) {
		return null;
	}
	SqlQualified qualified = scope.fullyQualify(identifier);
	List<String> names = qualified.identifier.names;

	if (names.size() < 2) {
		return null;
	}

	return new Pair<>(names.get(names.size() - 2), Util.last(names));
}
 
Example 8
Source File: SqlValidatorImpl.java    From Flink-CEPplus with Apache License 2.0 5 votes vote down vote up
private void checkRollUpInUsing(SqlIdentifier identifier, SqlNode leftOrRight) {
	leftOrRight = stripAs(leftOrRight);
	// if it's not a SqlIdentifier then that's fine, it'll be validated somewhere else.
	if (leftOrRight instanceof SqlIdentifier) {
		SqlIdentifier from = (SqlIdentifier) leftOrRight;
		Table table = findTable(catalogReader.getRootSchema(), Util.last(from.names),
			catalogReader.nameMatcher().isCaseSensitive());
		String name = Util.last(identifier.names);

		if (table != null && table.isRolledUp(name)) {
			throw newValidationError(identifier, RESOURCE.rolledUpNotAllowed(name, "USING"));
		}
	}
}
 
Example 9
Source File: MockCatalogReader.java    From calcite with Apache License 2.0 5 votes vote down vote up
@Override public Table extend(final List<RelDataTypeField> fields) {
  return new ModifiableTable(Util.last(names)) {
    @Override public RelDataType getRowType(RelDataTypeFactory typeFactory) {
      ImmutableList<RelDataTypeField> allFields = ImmutableList.copyOf(
          Iterables.concat(
              ModifiableTable.this.getRowType(typeFactory).getFieldList(),
              fields));
      return typeFactory.createStructType(allFields);
    }
  };
}
 
Example 10
Source File: PigRelBuilder.java    From calcite with Apache License 2.0 5 votes vote down vote up
public String getAlias() {
  if (lastAlias != null) {
    return lastAlias;
  } else {
    RelNode top = peek();
    if (top instanceof TableScan) {
      return Util.last(top.getTable().getQualifiedName());
    } else {
      return null;
    }
  }
}
 
Example 11
Source File: ListScope.java    From calcite with Apache License 2.0 5 votes vote down vote up
private ScopeChild findChild(List<String> names,
    SqlNameMatcher nameMatcher) {
  for (ScopeChild child : children) {
    String lastName = Util.last(names);
    if (child.name != null) {
      if (!nameMatcher.matches(child.name, lastName)) {
        // Alias does not match last segment. Don't consider the
        // fully-qualified name. E.g.
        //    SELECT sales.emp.name FROM sales.emp AS otherAlias
        continue;
      }
      if (names.size() == 1) {
        return child;
      }
    }

    // Look up the 2 tables independently, in case one is qualified with
    // catalog & schema and the other is not.
    final SqlValidatorTable table = child.namespace.getTable();
    if (table != null) {
      final ResolvedImpl resolved = new ResolvedImpl();
      resolveTable(names, nameMatcher, Path.EMPTY, resolved);
      if (resolved.count() == 1
          && resolved.only().remainingNames.isEmpty()
          && resolved.only().namespace instanceof TableNamespace
          && resolved.only().namespace.getTable().getQualifiedName().equals(
              table.getQualifiedName())) {
        return child;
      }
    }
  }
  return null;
}
 
Example 12
Source File: RelOptTableImpl.java    From calcite with Apache License 2.0 5 votes vote down vote up
public static MySchemaPlus create(Path path) {
  final Pair<String, Schema> pair = Util.last(path);
  final SchemaPlus parent;
  if (path.size() == 1) {
    parent = null;
  } else {
    parent = create(path.parent());
  }
  return new MySchemaPlus(parent, pair.left, pair.right);
}
 
Example 13
Source File: RelOptUtilTest.java    From calcite with Apache License 2.0 4 votes vote down vote up
/**
 * Test {@link RelOptUtil#createCastRel(RelNode, RelDataType, boolean)}
 * with changed field nullability or field name.
 */
@Test void testCreateCastRel() {
  // Equivalent SQL:
  // select empno, ename, count(job)
  // from emp
  // group by empno, ename

  // Row type:
  // RecordType(SMALLINT NOT NULL EMPNO, VARCHAR(10) ENAME, BIGINT NOT NULL $f2) NOT NULL
  final RelNode agg = relBuilder
      .push(empScan)
      .aggregate(
          relBuilder.groupKey("EMPNO", "ENAME"),
          relBuilder.count(relBuilder.field("JOB")))
      .build();
  // Cast with row type(change nullability):
  // RecordType(SMALLINT EMPNO, VARCHAR(10) ENAME, BIGINT $f2) NOT NULL
  // The fields.
  final RelDataTypeField fieldEmpno = agg.getRowType().getField("EMPNO", false, false);
  final RelDataTypeField fieldEname = agg.getRowType().getField("ENAME", false, false);
  final RelDataTypeField fieldJobCnt = Util.last(agg.getRowType().getFieldList());
  final RelDataTypeFactory typeFactory = relBuilder.getTypeFactory();
  // The field types.
  final RelDataType fieldTypeEmpnoNullable = typeFactory
      .createTypeWithNullability(fieldEmpno.getType(), true);
  final RelDataType fieldTypeJobCntNullable = typeFactory
      .createTypeWithNullability(fieldJobCnt.getType(), true);

  final RexBuilder rexBuilder = relBuilder.getRexBuilder();
  final RelDataType castRowType = typeFactory
      .createStructType(
          ImmutableList.of(
          Pair.of(fieldEmpno.getName(), fieldTypeEmpnoNullable),
          Pair.of(fieldEname.getName(), fieldEname.getType()),
          Pair.of(fieldJobCnt.getName(), fieldTypeJobCntNullable)));
  final RelNode castNode = RelOptUtil.createCastRel(agg, castRowType, false);
  final RelNode expectNode = relBuilder
      .push(agg)
      .project(
          rexBuilder.makeCast(
              fieldTypeEmpnoNullable,
              RexInputRef.of(0, agg.getRowType()),
              true),
          RexInputRef.of(1, agg.getRowType()),
          rexBuilder.makeCast(
              fieldTypeJobCntNullable,
              RexInputRef.of(2, agg.getRowType()),
              true))
      .build();
  assertThat(RelOptUtil.toString(castNode), is(RelOptUtil.toString(expectNode)));

  // Cast with row type(change field name):
  // RecordType(SMALLINT NOT NULL EMPNO, VARCHAR(10) ENAME, BIGINT NOT NULL JOB_CNT) NOT NULL
  final RelDataType castRowType1 = typeFactory
      .createStructType(
          ImmutableList.of(
          Pair.of(fieldEmpno.getName(), fieldEmpno.getType()),
          Pair.of(fieldEname.getName(), fieldEname.getType()),
          Pair.of("JOB_CNT", fieldJobCnt.getType())));
  final RelNode castNode1 = RelOptUtil.createCastRel(agg, castRowType1, true);
  final RelNode expectNode1 = RelFactories
      .DEFAULT_PROJECT_FACTORY
      .createProject(
          agg,
          ImmutableList.of(),
          ImmutableList.of(
              RexInputRef.of(0, agg.getRowType()),
              RexInputRef.of(1, agg.getRowType()),
              RexInputRef.of(2, agg.getRowType())),
          ImmutableList.of(
              fieldEmpno.getName(),
              fieldEname.getName(),
              "JOB_CNT"));
  assertThat(RelOptUtil.toString(castNode1), is(RelOptUtil.toString(expectNode1)));
  // Change the field JOB_CNT field name again.
  // The projection expect to be merged.
  final RelDataType castRowType2 = typeFactory
      .createStructType(
          ImmutableList.of(
          Pair.of(fieldEmpno.getName(), fieldEmpno.getType()),
          Pair.of(fieldEname.getName(), fieldEname.getType()),
          Pair.of("JOB_CNT2", fieldJobCnt.getType())));
  final RelNode castNode2 = RelOptUtil.createCastRel(agg, castRowType2, true);
  final RelNode expectNode2 = RelFactories
      .DEFAULT_PROJECT_FACTORY
      .createProject(
          agg,
          ImmutableList.of(),
          ImmutableList.of(
              RexInputRef.of(0, agg.getRowType()),
              RexInputRef.of(1, agg.getRowType()),
              RexInputRef.of(2, agg.getRowType())),
          ImmutableList.of(
              fieldEmpno.getName(),
              fieldEname.getName(),
              "JOB_CNT2"));
  assertThat(RelOptUtil.toString(castNode2), is(RelOptUtil.toString(expectNode2)));
}
 
Example 14
Source File: SqlAdvisor.java    From calcite with Apache License 2.0 4 votes vote down vote up
public String getReplacement(SqlMoniker hint, boolean quoted, Casing preferredCasing) {
  String name = Util.last(hint.getFullyQualifiedNames());
  boolean isKeyword = hint.getType() == SqlMonikerType.KEYWORD;
  // If replacement has mixed case, we need to quote it (or not depending
  // on quotedCasing/unquotedCasing
  quoted &= !isKeyword;

  if (!quoted && !isKeyword && getReservedAndKeyWordsSet().contains(name)) {
    quoted = true;
  }

  StringBuilder sb =
      new StringBuilder(name.length() + (quoted ? 2 : 0));

  if (!isKeyword && !Util.isValidJavaIdentifier(name)) {
    // needs quotes ==> quoted
    quoted = true;
  }
  String idToAppend = name;

  if (!quoted) {
    // id ==preferredCasing==> preferredId ==unquotedCasing==> recasedId
    // if recasedId matches id, then use preferredId
    String preferredId = applyCasing(name, preferredCasing);
    if (isKeyword || matchesUnquoted(name, preferredId)) {
      idToAppend = preferredId;
    } else {
      // Check if we can use unquoted identifier as is: for instance, unquotedCasing==UNCHANGED
      quoted = !matchesUnquoted(name, idToAppend);
    }
  }
  if (quoted) {
    sb.append(quoteStart());
  }
  sb.append(idToAppend);
  if (quoted) {
    sb.append(quoteEnd());
  }

  return sb.toString();
}
 
Example 15
Source File: ReflectiveSqlOperatorTable.java    From calcite with Apache License 2.0 4 votes vote down vote up
public void lookupOperatorOverloads(SqlIdentifier opName,
    SqlFunctionCategory category, SqlSyntax syntax,
    List<SqlOperator> operatorList, SqlNameMatcher nameMatcher) {
  // NOTE jvs 3-Mar-2005:  ignore category until someone cares

  String simpleName;
  if (opName.names.size() > 1) {
    if (opName.names.get(opName.names.size() - 2).equals(IS_NAME)) {
      // per SQL99 Part 2 Section 10.4 Syntax Rule 7.b.ii.1
      simpleName = Util.last(opName.names);
    } else {
      return;
    }
  } else {
    simpleName = opName.getSimple();
  }

  final Collection<SqlOperator> list =
      lookUpOperators(simpleName, syntax, nameMatcher);
  if (list.isEmpty()) {
    return;
  }
  for (SqlOperator op : list) {
    if (op.getSyntax() == syntax) {
      operatorList.add(op);
    } else if (syntax == SqlSyntax.FUNCTION
        && op instanceof SqlFunction) {
      // this special case is needed for operators like CAST,
      // which are treated as functions but have special syntax
      operatorList.add(op);
    }
  }

  // REVIEW jvs 1-Jan-2005:  why is this extra lookup required?
  // Shouldn't it be covered by search above?
  switch (syntax) {
  case BINARY:
  case PREFIX:
  case POSTFIX:
    for (SqlOperator extra
        : lookUpOperators(simpleName, syntax, nameMatcher)) {
      // REVIEW: should only search operators added during this method?
      if (extra != null && !operatorList.contains(extra)) {
        operatorList.add(extra);
      }
    }
    break;
  }
}
 
Example 16
Source File: SqlAnalyzeTable.java    From Bats with Apache License 2.0 4 votes vote down vote up
public String getName() {
  return Util.last(tblName.names);
}
 
Example 17
Source File: SqlAdvisor.java    From calcite with Apache License 2.0 4 votes vote down vote up
/**
 * Gets completion hints for a partially completed or syntactically incorrect
 * sql statement with cursor pointing to the position where completion hints
 * are requested.
 *
 * <p>Writes into <code>replaced[0]</code> the string that is being
 * replaced. Includes the cursor and the preceding identifier. For example,
 * if <code>sql</code> is "select abc^de from t", sets <code>
 * replaced[0]</code> to "abc". If the cursor is in the middle of
 * whitespace, the replaced string is empty. The replaced string is never
 * null.
 *
 * @param sql      A partial or syntactically incorrect sql statement for
 *                 which to retrieve completion hints
 * @param cursor   to indicate the 0-based cursor position in the query at
 * @param replaced String which is being replaced (output)
 * @return completion hints
 */
public List<SqlMoniker> getCompletionHints(
    String sql,
    int cursor,
    String[] replaced) {
  // search backward starting from current position to find a "word"
  int wordStart = cursor;
  boolean quoted = false;
  while (wordStart > 0
      && Character.isJavaIdentifierPart(sql.charAt(wordStart - 1))) {
    --wordStart;
  }
  if ((wordStart > 0)
      && (sql.charAt(wordStart - 1) == quoteStart())) {
    quoted = true;
    --wordStart;
  }

  if (wordStart < 0) {
    return Collections.emptyList();
  }

  // Search forwards to the end of the word we should remove. Eat up
  // trailing double-quote, if any
  int wordEnd = cursor;
  while (wordEnd < sql.length()
      && Character.isJavaIdentifierPart(sql.charAt(wordEnd))) {
    ++wordEnd;
  }
  if (quoted
      && (wordEnd < sql.length())
      && (sql.charAt(wordEnd) == quoteEnd())) {
    ++wordEnd;
  }

  // remove the partially composed identifier from the
  // sql statement - otherwise we get a parser exception
  String word = replaced[0] = sql.substring(wordStart, cursor);
  if (wordStart < wordEnd) {
    sql =
        sql.substring(0, wordStart)
            + sql.substring(wordEnd);
  }

  final List<SqlMoniker> completionHints =
      getCompletionHints0(sql, wordStart);

  if (quoted) {
    word = word.substring(1);
  }

  if (word.isEmpty()) {
    return completionHints;
  }

  // If cursor was part of the way through a word, only include hints
  // which start with that word in the result.
  final List<SqlMoniker> result = new ArrayList<>();
  Casing preferredCasing = getPreferredCasing(word);

  boolean ignoreCase = preferredCasing != Casing.UNCHANGED;
  for (SqlMoniker hint : completionHints) {
    List<String> names = hint.getFullyQualifiedNames();
    // For now we treat only simple cases where the added name is the last
    // See [CALCITE-2439] Smart complete for SqlAdvisor
    String cname = Util.last(names);
    if (cname.regionMatches(ignoreCase, 0, word, 0, word.length())) {
      result.add(hint);
    }
  }

  return result;
}
 
Example 18
Source File: SqlAdvisor.java    From Bats with Apache License 2.0 4 votes vote down vote up
public String getReplacement(SqlMoniker hint, boolean quoted, Casing preferredCasing) {
  String name = Util.last(hint.getFullyQualifiedNames());
  boolean isKeyword = hint.getType() == SqlMonikerType.KEYWORD;
  // If replacement has mixed case, we need to quote it (or not depending
  // on quotedCasing/unquotedCasing
  quoted &= !isKeyword;

  if (!quoted && !isKeyword && getReservedAndKeyWordsSet().contains(name)) {
    quoted = true;
  }

  StringBuilder sb =
      new StringBuilder(name.length() + (quoted ? 2 : 0));

  if (!isKeyword && !Util.isValidJavaIdentifier(name)) {
    // needs quotes ==> quoted
    quoted = true;
  }
  String idToAppend = name;

  if (!quoted) {
    // id ==preferredCasing==> preferredId ==unquotedCasing==> recasedId
    // if recasedId matches id, then use preferredId
    String preferredId = applyCasing(name, preferredCasing);
    if (isKeyword || matchesUnquoted(name, preferredId)) {
      idToAppend = preferredId;
    } else {
      // Check if we can use unquoted identifier as is: for instance, unquotedCasing==UNCHANGED
      quoted = !matchesUnquoted(name, idToAppend);
    }
  }
  if (quoted) {
    sb.append(quoteStart());
  }
  sb.append(idToAppend);
  if (quoted) {
    sb.append(quoteEnd());
  }

  return sb.toString();
}
 
Example 19
Source File: SqlFunction.java    From Bats with Apache License 2.0 3 votes vote down vote up
/**
 * Creates a placeholder SqlFunction for an invocation of a function with a
 * possibly qualified name. This name must be resolved into either a builtin
 * function or a user-defined function.
 *
 * @param sqlIdentifier        possibly qualified identifier for function
 * @param returnTypeInference  strategy to use for return type inference
 * @param operandTypeInference strategy to use for parameter type inference
 * @param operandTypeChecker   strategy to use for parameter type checking
 * @param paramTypes           array of parameter types
 * @param funcType             function category
 */
public SqlFunction(
    SqlIdentifier sqlIdentifier,
    SqlReturnTypeInference returnTypeInference,
    SqlOperandTypeInference operandTypeInference,
    SqlOperandTypeChecker operandTypeChecker,
    List<RelDataType> paramTypes,
    SqlFunctionCategory funcType) {
  this(Util.last(sqlIdentifier.names), sqlIdentifier, SqlKind.OTHER_FUNCTION,
      returnTypeInference, operandTypeInference, operandTypeChecker,
      paramTypes, funcType);
}
 
Example 20
Source File: SqlFunction.java    From calcite with Apache License 2.0 3 votes vote down vote up
/**
 * Creates a placeholder SqlFunction for an invocation of a function with a
 * possibly qualified name. This name must be resolved into either a builtin
 * function or a user-defined function.
 *
 * @param sqlIdentifier        possibly qualified identifier for function
 * @param returnTypeInference  strategy to use for return type inference
 * @param operandTypeInference strategy to use for parameter type inference
 * @param operandTypeChecker   strategy to use for parameter type checking
 * @param paramTypes           array of parameter types
 * @param funcType             function category
 */
public SqlFunction(
    SqlIdentifier sqlIdentifier,
    SqlReturnTypeInference returnTypeInference,
    SqlOperandTypeInference operandTypeInference,
    SqlOperandTypeChecker operandTypeChecker,
    List<RelDataType> paramTypes,
    SqlFunctionCategory funcType) {
  this(Util.last(sqlIdentifier.names), sqlIdentifier, SqlKind.OTHER_FUNCTION,
      returnTypeInference, operandTypeInference, operandTypeChecker,
      paramTypes, funcType);
}