class RelMetadataQueryEx extends RelMetadataQuery {
    static {
        ConfigurationBuilder cfg = new ConfigurationBuilder()
            .forPackages("org.apache.ignite.internal.processors.query.calcite.rel")
            .addClassLoaders(U.gridClassLoader())
            .addScanners(new SubTypesScanner());

        List<Class<? extends RelNode>> types = new Reflections(cfg)
            .getSubTypesOf(IgniteRel.class).stream()
            .filter(type -> !type.isInterface())
            .filter(type -> !Modifier.isAbstract(type.getModifiers()))
            .collect(Collectors.toList());

        JaninoRelMetadataProvider.DEFAULT.register(types);
    }

    /** */
    private static final IgniteMetadata.FragmentMappingMetadata.Handler SOURCE_DISTRIBUTION_INITIAL_HANDLER =
        initialHandler(IgniteMetadata.FragmentMappingMetadata.Handler.class);

    /** */
    private IgniteMetadata.FragmentMappingMetadata.Handler sourceDistributionHandler;

    /**
     * Factory method.
     *
     * @return return Metadata query instance.
     */
    public static RelMetadataQueryEx create() {
        return create(IgniteMetadata.METADATA_PROVIDER);
    }

    /**
     * Factory method.
     *
     * @return return Metadata query instance.
     */
    public static RelMetadataQueryEx create(RelMetadataProvider metadataProvider) {<FILL_FUNCTION_BODY>}

    /** */
    private RelMetadataQueryEx() {
        sourceDistributionHandler = SOURCE_DISTRIBUTION_INITIAL_HANDLER;
    }

    /**
     * Calculates data location mapping for a query fragment the given relation node is a root of.
     *
     * @param rel Relational node.
     * @return Fragment meta information.
     */
    public FragmentMapping fragmentMapping(RelNode rel, MappingQueryContext ctx) {
        for (;;) {
            try {
                return sourceDistributionHandler.fragmentMapping(rel, this, ctx);
            }
            catch (JaninoRelMetadataProvider.NoHandler e) {
                sourceDistributionHandler = revise(e.relClass, IgniteMetadata.FragmentMappingMetadata.DEF);
            }
        }
    }
}

        THREAD_PROVIDERS.set(JaninoRelMetadataProvider.of(metadataProvider));
        try {
            return new RelMetadataQueryEx();
        }
        finally {
            THREAD_PROVIDERS.remove();
        }
    
<no_super_class>