UDFHelper { public static String generateUDTFClause( final String inTableName, final String functionName, final String[] outputCols, final String[] selectedCols, final String[] reservedCols) { final String selectedColsStr = TableUtil.columnsToSqlClause(selectedCols); final String[] shadedOutputCols = Arrays.stream(outputCols) .map(d -> d + "_" + UUID.randomUUID().toString().replace("-", "")) .toArray(String[]::new); final String shadedOutputColsStr = TableUtil.columnsToSqlClause(shadedOutputCols); final Set<String> outputColsSet = new HashSet<>(Arrays.asList(outputCols)); final String[] cleanedReservedCols = Arrays.stream(reservedCols) .filter(d -> !outputColsSet.contains(d)) .toArray(String[]::new); StringBuilder sb = new StringBuilder(); if (cleanedReservedCols.length > 0) { sb.append(TableUtil.columnsToSqlClause(cleanedReservedCols)).append(", "); } for (int i = 0; i < outputCols.length; i += 1) { sb.append("`").append(shadedOutputCols[i]).append("` as `").append(outputCols[i]).append("`"); if (i < outputCols.length - 1) { sb.append(", "); } } String selectClause = sb.toString(); final String joinTemplate = "SELECT %s FROM %s, LATERAL TABLE(%s(%s)) as T(%s)"; final String[] finalOutputCols = ArrayUtils.addAll(cleanedReservedCols, shadedOutputCols); final String finalOutputColsStr = TableUtil.columnsToSqlClause(finalOutputCols); final String joinClause = String.format(joinTemplate, finalOutputColsStr, inTableName, functionName, selectedColsStr, shadedOutputColsStr); return String.format("SELECT %s FROM (%s)", selectClause, joinClause); }  static String generateRandomFuncName(); static String generateUDFClause(
        final String inTableName, final String functionName,
        final String outputCol, final String[] selectedCols, final String[] reservedCols); static String generateUDTFClause(
        final String inTableName, final String functionName,
        final String[] outputCols, final String[] selectedCols, final String[] reservedCols);  }
@Test public void generateUDTFClause() { String clause = UDFHelper.generateUDTFClause( "input", "func", new String[]{"c1", "c2"}, new String[]{"c0", "c1"}, new String[]{"c0", "c1", "c2"}); String pattern = "SELECT `c0`, `c1_[0-9a-z]{32}` as `c1`, `c2_[0-9a-z]{32}` as `c2` FROM \\(" + "SELECT `c0`,`c1_[0-9a-z]{32}`,`c2_[0-9a-z]{32}` FROM input, " + "LATERAL TABLE\\(func\\(`c0`,`c1`\\)\\) as T\\(`c1_[0-9a-z]{32}`,`c2_[0-9a-z]{32}`\\)" + "\\)"; assertTrue(clause.matches(pattern)); }