class DB2Dialect extends BasicJdbcDialect {
    /** */
    private static final long serialVersionUID = 0L;

    /** {@inheritDoc} */
    @Override public String loadCacheSelectRangeQuery(String fullTblName, Collection<String> keyCols) {
        String cols = mkString(keyCols, ",");

        return String.format(
            "SELECT %1$s FROM (SELECT %1$s, ROW_NUMBER() OVER(ORDER BY %1$s) AS rn FROM %2$s) WHERE mod(rn, ?) = 0 ORDER BY %1$s",
            cols,
            fullTblName
        );
    }

    /** {@inheritDoc} */
    @Override public boolean hasMerge() {
        return true;
    }

    /** {@inheritDoc} */
    @Override public String mergeQuery(String fullTblName, Collection<String> keyCols, Collection<String> uniqCols) {<FILL_FUNCTION_BODY>}
}

        Collection<String> cols = F.concat(false, keyCols, uniqCols);

        String colsLst = mkString(cols, ", ");

        String match = mkString(keyCols, new C1<String, String>() {
            @Override public String apply(String col) {
                return String.format("t.%s=v.%s", col, col);
            }
        }, "", ", ", "");

        String setCols = mkString(uniqCols, new C1<String, String>() {
            @Override public String apply(String col) {
                return String.format("t.%s = v.%s", col, col);
            }
        }, "", ", ", "");

        String valuesCols = mkString(cols, new C1<String, String>() {
            @Override public String apply(String col) {
                return "v." + col;
            }
        }, "", ", ", "");

        return String.format("MERGE INTO %s t" +
                " USING (VALUES(%s)) AS v (%s)" +
                "  ON %s" +
                " WHEN MATCHED THEN" +
                "  UPDATE SET %s" +
                " WHEN NOT MATCHED THEN" +
                "  INSERT (%s) VALUES (%s)", fullTblName, repeat("?", cols.size(), "", ",", ""), colsLst,
            match, setCols, colsLst, valuesCols);
    
<methods>public non-sealed void <init>() ,public java.lang.String escape(java.lang.String) ,public int getFetchSize() ,public int getMaxParameterCount() ,public boolean hasMerge() ,public java.lang.String insertQuery(java.lang.String, Collection<java.lang.String>, Collection<java.lang.String>) ,public java.lang.String loadCacheQuery(java.lang.String, Iterable<java.lang.String>) ,public java.lang.String loadCacheRangeQuery(java.lang.String, Collection<java.lang.String>, Iterable<java.lang.String>, boolean, boolean) ,public java.lang.String loadCacheSelectRangeQuery(java.lang.String, Collection<java.lang.String>) ,public java.lang.String loadQuery(java.lang.String, Collection<java.lang.String>, Iterable<java.lang.String>, int) ,public java.lang.String mergeQuery(java.lang.String, Collection<java.lang.String>, Collection<java.lang.String>) ,public java.lang.String removeQuery(java.lang.String, Iterable<java.lang.String>) ,public void setFetchSize(int) ,public void setMaxParameterCount(int) ,public java.lang.String updateQuery(java.lang.String, Collection<java.lang.String>, Iterable<java.lang.String>) <variables>protected static final int DFLT_MAX_PARAMS_CNT,protected int fetchSize,protected int maxParamsCnt,private static final long serialVersionUID