        CREATE TABLE IF NOT EXISTS %I.route_trails (
            id SERIAL PRIMARY KEY,
            route_uuid TEXT NOT NULL,
            trail_id TEXT NOT NULL,
            trail_name TEXT NOT NULL,
            segment_order INTEGER NOT NULL,
            segment_distance_km REAL CHECK(segment_distance_km > 0),
            segment_elevation_gain REAL CHECK(segment_elevation_gain >= 0),
            segment_elevation_loss REAL CHECK(segment_elevation_loss >= 0),
            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        )
    ', staging_schema);
    EXECUTE format('
        CREATE TABLE IF NOT EXISTS %I.route_recommendations (
            id SERIAL PRIMARY KEY,
            route_uuid TEXT UNIQUE NOT NULL,
            region TEXT NOT NULL,
            input_distance_km REAL CHECK(input_distance_km > 0),
            input_elevation_gain REAL CHECK(input_elevation_gain >= 0),
            recommended_distance_km REAL CHECK(recommended_distance_km > 0),
            recommended_elevation_gain REAL CHECK(recommended_elevation_gain >= 0),
            route_type TEXT,
            route_shape TEXT,
            trail_count INTEGER,
            route_score INTEGER,
            route_path JSONB,
            route_edges JSONB,
            route_name TEXT,
            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        )
    ', staging_schema);
    FOR pattern IN SELECT * FROM get_route_patterns() LOOP
        current_tolerance := pattern.tolerance_percent;
        routes_found := 0;
        iteration := 0;
        WHILE routes_found < min_routes_per_pattern AND iteration < max_iterations AND current_tolerance <= max_tolerance_percent LOOP
            EXECUTE format('DELETE FROM %I.route_recommendations 
            WHERE input_distance_km = $1 
              AND input_elevation_gain = $2
              AND route_shape = $3', staging_schema)
            USING pattern.target_distance_km, pattern.target_elevation_gain, pattern.route_shape;
            EXECUTE format('INSERT INTO %I.route_recommendations (
                route_uuid,
                region,
                input_distance_km,
                input_elevation_gain,
                recommended_distance_km,
                recommended_elevation_gain,
                route_type,
                route_shape,
                trail_count,
                route_score,
                route_path,
                route_edges,
                route_name,
                created_at
            )
            SELECT 
                r.route_id,
                $1 as region,
                $2,
                $3,
                r.total_distance_km,
                r.total_elevation_gain,
                ''similar_distance'' as route_type,
                r.route_shape,
                r.trail_count,
                (r.similarity_score * 100)::integer as route_score,
                json_build_object(
                    ''type'', ''LineString'',
                    ''coordinates'', array_agg(
                        json_build_array(n.lng, n.lat, n.elevation)
                        ORDER BY array_position(r.route_path, n.id)
                    )
                )::jsonb as route_path,
                json_agg(r.route_edges)::jsonb as route_edges,
                generate_route_name(r.route_edges, r.route_shape) as route_name,
                NOW() as created_at
            FROM find_routes_recursive_configurable($4, $2, $3, $5, $6) r
            JOIN %I.routing_nodes n ON n.id = ANY(r.route_path)
            WHERE r.route_shape = $7
              AND r.similarity_score >= get_min_route_score()  -- Use configurable minimum score
            GROUP BY r.route_id, r.total_distance_km, r.total_elevation_gain, 
                     r.route_shape, r.trail_count, r.similarity_score, r.route_edges', staging_schema, staging_schema)
            USING region_name, pattern.target_distance_km, pattern.target_elevation_gain, staging_schema, current_tolerance, 8, pattern.route_shape;
            GET DIAGNOSTICS routes_found = ROW_COUNT;
            IF routes_found > 0 THEN
                RAISE NOTICE 'Routes found in iteration % (tolerance: %%%) for pattern %:', 
                    iteration, current_tolerance - 10.0, pattern.pattern_name;
                DECLARE
                    route_detail RECORD;
                    route_query TEXT;
                BEGIN
                    route_query := format('
                        SELECT 
                            route_name,
                            recommended_distance_km,
                            recommended_elevation_gain,
                            ROUND(recommended_elevation_gain / recommended_distance_km, 1) as gain_rate_m_per_km,
                            route_shape,
                            trail_count,
                            route_score
                        FROM %I.route_recommendations 
                        WHERE input_distance_km = %s 
                          AND input_elevation_gain = %s 
                          AND route_shape = ''%s''
                        ORDER BY route_score DESC
                        LIMIT 5', 
                        staging_schema, 
                        pattern.target_distance_km, 
                        pattern.target_elevation_gain, 
                        pattern.route_shape);
                    FOR route_detail IN EXECUTE route_query LOOP
                        RAISE NOTICE '  - %: %.1fkm, %.0fm gain (%.1f m/km), % shape, % trails, score: %', 
                            route_detail.route_name,
                            route_detail.recommended_distance_km,
                            route_detail.recommended_elevation_gain,
                            route_detail.gain_rate_m_per_km,
                            route_detail.route_shape,
                            route_detail.trail_count,
                            route_detail.route_score;
                    END LOOP;
                END;
            END IF;
            EXECUTE format('INSERT INTO %I.route_trails (
                route_uuid,
                trail_id,
                trail_name,
                segment_order,
                segment_distance_km,
                segment_elevation_gain,
                segment_elevation_loss
            )
            SELECT 
                r.route_id,
                e.app_uuid,
                e.trail_name,
                ROW_NUMBER() OVER (PARTITION BY r.route_id ORDER BY array_position(r.route_path, e.source)) as segment_order,
                e.length_km,
                e.elevation_gain,
                e.elevation_loss
            FROM find_routes_recursive_configurable($1, $2, $3, $4, $5) r
            JOIN %I.routing_edges e ON e.id = ANY(r.route_edges)
            WHERE r.route_shape = $6
              AND r.similarity_score >= get_min_route_score()', staging_schema, staging_schema)
            USING staging_schema, pattern.target_distance_km, pattern.target_elevation_gain, current_tolerance, 8, pattern.route_shape;
            current_tolerance := current_tolerance + 10.0;
            iteration := iteration + 1;
            RAISE NOTICE 'Pattern: %, Iteration: %, Tolerance: %%%, Routes found: %', 
                pattern.pattern_name, iteration, current_tolerance - 10.0, routes_found;
        END LOOP;
        total_routes := total_routes + routes_found;
        RAISE NOTICE 'Final: Generated % routes for pattern: % (tolerance: %%%)', 
            routes_found, pattern.pattern_name, current_tolerance - 10.0;
    END LOOP;
    RAISE NOTICE '=== ROUTE GENERATION SUMMARY ===';
    RAISE NOTICE 'Total routes generated: %', total_routes;
    RAISE NOTICE 'Patterns processed: %', (SELECT COUNT(*) FROM route_patterns);
    RAISE NOTICE '================================';
    RETURN total_routes;
END;
$function$
;

CREATE OR REPLACE FUNCTION public.generate_route_recommendations_configurable(staging_schema text, region_name text DEFAULT 'boulder'::text)
 RETURNS integer
 LANGUAGE plpgsql
AS $function$
DECLARE
    route_count integer := 0;
    pattern record;
    total_routes integer := 0;
BEGIN
    -- Generate recommendations for each pattern from config
    FOR pattern IN SELECT * FROM get_route_patterns() LOOP
        INSERT INTO route_recommendations (
            route_uuid,
            region,
            input_distance_km,
            input_elevation_gain,
            recommended_distance_km,
            recommended_elevation_gain,
            route_type,
            route_shape,
            trail_count,
            route_score,
            route_path,
            route_edges,
            route_name,
            created_at
        )
        SELECT 
            r.route_id,
            region_name as region,
            pattern.target_distance_km,
            pattern.target_elevation_gain,
            r.total_distance_km,
            r.total_elevation_gain,
            'similar_distance' as route_type,
            r.route_shape,
            r.trail_count,
            (r.similarity_score * 100)::integer as route_score,
            -- Convert path to GeoJSON (simplified) - FIXED: Use jsonb
            json_build_object(
                'type', 'LineString',
                'coordinates', array_agg(
                    json_build_array(lng, lat, elevation)
                    ORDER BY array_position(r.route_path, id)
                )
            )::jsonb as route_path,
            -- Convert edges to JSON array - FIXED: Use jsonb
            json_agg(r.route_edges)::jsonb as route_edges,
            -- Generate proper route name
            generate_route_name(r.route_edges, r.route_shape) as route_name,
            NOW() as created_at
        FROM find_routes_recursive_configurable(
            staging_schema,
            pattern.target_distance_km,
            pattern.target_elevation_gain,
            pattern.tolerance_percent,
            8
        ) r
        JOIN routing_nodes n ON n.id = ANY(r.route_path)
        WHERE r.route_shape = pattern.route_shape
          AND r.similarity_score >= get_min_route_score()  -- Use configurable minimum score
        GROUP BY r.route_id, r.total_distance_km, r.total_elevation_gain, 
                 r.route_shape, r.trail_count, r.similarity_score, r.route_edges;
        
        -- Populate route_trails junction table with trail composition data
        INSERT INTO route_trails (
            route_uuid,
            trail_id,
            trail_name,
            segment_order,
            segment_distance_km,
            segment_elevation_gain,
            segment_elevation_loss
        )
        SELECT 
            r.route_id,
            e.app_uuid,
            e.trail_name,
            ROW_NUMBER() OVER (PARTITION BY r.route_id ORDER BY array_position(r.route_path, e.source)) as segment_order,
            e.length_km,
            e.elevation_gain,
            e.elevation_loss
        FROM find_routes_recursive_configurable(
            staging_schema,
            pattern.target_distance_km,
            pattern.target_elevation_gain,
            pattern.tolerance_percent,
            8
        ) r
        JOIN routing_edges e ON e.id = ANY(r.route_edges)
        WHERE r.route_shape = pattern.route_shape
          AND r.similarity_score >= get_min_route_score();
        
        GET DIAGNOSTICS route_count = ROW_COUNT;
        total_routes := total_routes + route_count;
        RAISE NOTICE 'Generated % routes for pattern: %', route_count, pattern.pattern_name;
    END LOOP;
    
    RETURN total_routes;
END;
$function$
;

CREATE OR REPLACE FUNCTION public.generate_route_recommendations_configurable(staging_schema text)
 RETURNS integer
 LANGUAGE plpgsql
AS $function$
DECLARE
    route_count integer := 0;
    pattern record;
    total_routes integer := 0;
BEGIN
    FOR pattern IN SELECT * FROM get_route_patterns() LOOP
        INSERT INTO route_recommendations (
            route_uuid,
            region,
            input_distance_km,
            input_elevation_gain,
            recommended_distance_km,
            recommended_elevation_gain,
            route_type,
            route_shape,
            trail_count,
            route_score,
            route_path,
            route_edges,
            route_name,
            created_at
        )
        SELECT 
            r.route_id,
            'boulder' as region,  -- TODO: Make this dynamic
            pattern.target_distance_km,
            pattern.target_elevation_gain,
            r.total_distance_km,
            r.total_elevation_gain,
            'similar_distance' as route_type,
            r.route_shape,
            r.trail_count,
            (r.similarity_score * 100)::integer as route_score,
            json_build_object(
                'type', 'LineString',
                'coordinates', array_agg(
                    json_build_array(n.lng, n.lat, n.elevation)
                    ORDER BY array_position(r.route_path, n.id)
                )
            )::text as route_path,
            json_agg(r.route_edges)::text as route_edges,
            generate_route_name(r.route_edges, r.route_shape) as route_name,
            NOW() as created_at
        FROM find_routes_recursive_configurable(
            staging_schema,
            pattern.target_distance_km,
            pattern.target_elevation_gain,
            pattern.tolerance_percent,
            8
        ) r
        JOIN routing_nodes n ON n.id = ANY(r.route_path)
        WHERE r.route_shape = pattern.route_shape
          AND r.similarity_score >= get_min_route_score()  -- Use configurable minimum score
        GROUP BY r.route_id, r.total_distance_km, r.total_elevation_gain, 
                 r.route_shape, r.trail_count, r.similarity_score, r.route_edges;
        GET DIAGNOSTICS route_count = ROW_COUNT;
        total_routes := total_routes + route_count;
        RAISE NOTICE 'Generated % routes for pattern: %', route_count, pattern.pattern_name;
    END LOOP;
    RETURN total_routes;
END;
$function$
;

CREATE OR REPLACE FUNCTION public.generate_route_recommendations_large_dataset(staging_schema text)
 RETURNS integer
 LANGUAGE plpgsql
AS $function$
DECLARE
    route_count integer := 0;
    pattern record;
    total_routes integer := 0;
BEGIN
    FOR pattern IN SELECT * FROM get_route_patterns() LOOP
        INSERT INTO route_recommendations (
            route_uuid,
            region,
            input_distance_km,
            input_elevation_gain,
            recommended_distance_km,
            recommended_elevation_gain,
            route_type,
            route_shape,
            trail_count,
            route_score,
            route_path,
            route_edges,
            route_name,
            created_at
        )
        SELECT 
            r.route_id,
            'boulder' as region,  -- TODO: Make this dynamic
            pattern.target_distance_km,
            pattern.target_elevation_gain,
            r.total_distance_km,
            r.total_elevation_gain,
            'similar_distance' as route_type,
            r.route_shape,
            r.trail_count,
            (r.similarity_score * 100)::integer as route_score,
            json_build_object(
                'type', 'LineString',
                'coordinates', array_agg(
                    json_build_array(n.lng, n.lat, n.elevation)
                    ORDER BY array_position(r.route_path, n.id)
                )
            )::text as route_path,
            json_agg(r.route_edges)::text as route_edges,
            generate_route_name(r.route_edges, r.route_shape) as route_name,
            NOW() as created_at
        FROM find_routes_recursive_configurable(
            staging_schema,
            pattern.target_distance_km,
            pattern.target_elevation_gain,
            pattern.tolerance_percent,
            12  -- Increased max depth for large datasets
        ) r
        JOIN routing_nodes n ON n.id = ANY(r.route_path)
        WHERE r.route_shape = pattern.route_shape
          AND r.similarity_score >= 0.3  -- Lower threshold for large datasets
        GROUP BY r.route_id, r.total_distance_km, r.total_elevation_gain, 
                 r.route_shape, r.trail_count, r.similarity_score, r.route_edges;
        GET DIAGNOSTICS route_count = ROW_COUNT;
        total_routes := total_routes + route_count;
        RAISE NOTICE 'Generated % routes for pattern: %', route_count, pattern.pattern_name;
    END LOOP;
    RETURN total_routes;
END;
$function$
;

CREATE OR REPLACE FUNCTION public.generate_route_recommendations_large_dataset(staging_schema text, region_name text DEFAULT 'boulder'::text)
 RETURNS integer
 LANGUAGE plpgsql
AS $function$
DECLARE
    route_count integer := 0;
    pattern record;
    total_routes integer := 0;
BEGIN
    FOR pattern IN SELECT * FROM get_route_patterns() LOOP
        INSERT INTO route_recommendations (
            route_uuid,
            region,
            input_distance_km,
            input_elevation_gain,
            recommended_distance_km,
            recommended_elevation_gain,
            route_type,
            route_shape,
            trail_count,
            route_score,
            route_path,
            route_edges,
            route_name,
            created_at
        )
        SELECT 
            r.route_id,
            region_name as region,
            pattern.target_distance_km,
            pattern.target_elevation_gain,
            r.total_distance_km,
            r.total_elevation_gain,
            'similar_distance' as route_type,
            r.route_shape,
            r.trail_count,
            (r.similarity_score * 100)::integer as route_score,
            json_build_object(
                'type', 'LineString',
                'coordinates', array_agg(
                    json_build_array(n.lng, n.lat, n.elevation)
                    ORDER BY array_position(r.route_path, n.id)
                )
            ) as route_path,
            json_agg(r.route_edges) as route_edges,
            generate_route_name(r.route_edges, r.route_shape) as route_name,
            NOW() as created_at
        FROM find_routes_recursive_configurable(
            staging_schema,
            pattern.target_distance_km,
            pattern.target_elevation_gain,
            pattern.tolerance_percent,
            12  -- Increased max depth for large datasets
        ) r
        JOIN routing_nodes n ON n.id = ANY(r.route_path)
        WHERE r.route_shape = pattern.route_shape
          AND r.similarity_score >= 0.3  -- Lower threshold for large datasets
        GROUP BY r.route_id, r.total_distance_km, r.total_elevation_gain, 
                 r.route_shape, r.trail_count, r.similarity_score, r.route_edges;
        GET DIAGNOSTICS route_count = ROW_COUNT;
        total_routes := total_routes + route_count;
        RAISE NOTICE 'Generated % routes for pattern: %', route_count, pattern.pattern_name;
    END LOOP;
    RETURN total_routes;
END;
$function$
;

CREATE OR REPLACE FUNCTION public.generate_routing_edges_native(staging_schema text, tolerance_meters real DEFAULT 2.0)
 RETURNS TABLE(edge_count integer, success boolean, message text)
 LANGUAGE plpgsql
AS $function$
DECLARE
    edge_count_var integer := 0;
    node_count_var integer := 0;
    max_node_id_var integer := 0;
BEGIN
    -- Clear existing routing edges
    EXECUTE format('DELETE FROM %I.routing_edges', staging_schema);
    
    -- Get node count and max node ID for validation
    EXECUTE format('SELECT COUNT(*), MAX(id) FROM %I.routing_nodes', staging_schema) INTO node_count_var, max_node_id_var;
    
    -- Validate that we have nodes to work with
    IF node_count_var = 0 THEN
        RETURN QUERY SELECT 
            0, false, 
            'No routing nodes available for edge generation' as message;
        RETURN;
    END IF;
    
    -- Generate routing edges from trail segments with improved validation
    EXECUTE format($f$
        INSERT INTO %I.routing_edges (id, app_uuid, name, trail_type, length_km, elevation_gain, elevation_loss, geom, source, target)
        SELECT 
            nextval('routing_edges_id_seq') as id,
            t.app_uuid,
            t.name,
            t.trail_type,
            t.length_km,
            t.elevation_gain,
            t.elevation_loss,
            t.geometry as geom,
            source_node.id as source,
            target_node.id as target
        FROM %I.trails t
        CROSS JOIN LATERAL (
            SELECT id FROM %I.routing_nodes 
            WHERE ST_DWithin(ST_SetSRID(ST_MakePoint(lng, lat), 4326), ST_StartPoint(t.geometry), $1)
              AND id IS NOT NULL
              AND id <= $2  -- Ensure node ID is within valid range
            ORDER BY ST_Distance(ST_SetSRID(ST_MakePoint(lng, lat), 4326), ST_StartPoint(t.geometry))
            LIMIT 1
        ) source_node
        CROSS JOIN LATERAL (
            SELECT id FROM %I.routing_nodes 
            WHERE ST_DWithin(ST_SetSRID(ST_MakePoint(lng, lat), 4326), ST_EndPoint(t.geometry), $1)
              AND id IS NOT NULL
              AND id <= $2  -- Ensure node ID is within valid range
            ORDER BY ST_Distance(ST_SetSRID(ST_MakePoint(lng, lat), 4326), ST_EndPoint(t.geometry))
            LIMIT 1
        ) target_node
        WHERE t.geometry IS NOT NULL 
          AND ST_IsValid(t.geometry) 
          AND t.length_km IS NOT NULL AND t.length_km > 0
          AND ST_Length(t.geometry) > 0
          AND ST_NumPoints(t.geometry) >= 2
          AND source_node.id IS NOT NULL
          AND target_node.id IS NOT NULL
          AND source_node.id <= $2  -- Double-check source node ID
          AND target_node.id <= $2  -- Double-check target node ID
    $f$, staging_schema, staging_schema, staging_schema, staging_schema) USING tolerance_meters, max_node_id_var;
    
    GET DIAGNOSTICS edge_count_var = ROW_COUNT;
    
    -- Validate that no orphaned edges were created
    EXECUTE format($f$
        SELECT COUNT(*) FROM %I.routing_edges e
        WHERE e.source NOT IN (SELECT id FROM %I.routing_nodes)
           OR e.target NOT IN (SELECT id FROM %I.routing_nodes)
    $f$, staging_schema, staging_schema) INTO edge_count_var;
    
    IF edge_count_var > 0 THEN
        RETURN QUERY SELECT 
            0, false, 
            format('Validation failed: %s edges reference non-existent nodes', edge_count_var) as message;
        RETURN;
    END IF;
    
    -- Get final edge count
    EXECUTE format('SELECT COUNT(*) FROM %I.routing_edges', staging_schema) INTO edge_count_var;
    
    -- Return results
    RETURN QUERY SELECT 
        edge_count_var,
        true as success,
        format('Successfully generated %s routing edges from %s nodes (max node ID: %s)', 
               edge_count_var, node_count_var, max_node_id_var) as message;
    
    RAISE NOTICE 'Generated % routing edges from % nodes (max node ID: %)', 
                 edge_count_var, node_count_var, max_node_id_var;
        
EXCEPTION WHEN OTHERS THEN
    -- Return error information
    RETURN QUERY SELECT 
        0, false, 
        format('Error during routing edges generation: %s', SQLERRM) as message;
    
    RAISE NOTICE 'Error during routing edges generation: %', SQLERRM;
END;
$function$
;

CREATE OR REPLACE FUNCTION public.generate_routing_edges_native_v2(staging_schema text, tolerance_meters real DEFAULT 0.5)
 RETURNS TABLE(edge_count integer, success boolean, message text)
 LANGUAGE plpgsql
AS $function$
DECLARE
    edge_count_var integer := 0;
    node_count_var integer := 0;
    orphaned_count integer := 0;
    orphaned_edges_count integer := 0;
    tolerance_degrees real := tolerance_meters / 111000.0;
BEGIN
    -- Clear existing routing edges
    EXECUTE format('DELETE FROM %I.routing_edges', staging_schema);
    
    -- Get node count for validation
    EXECUTE format('SELECT COUNT(*) FROM %I.routing_nodes', staging_schema) INTO node_count_var;
    
    -- Generate routing edges from actual trail segments (simplified version)
    EXECUTE format($f$
        INSERT INTO %I.routing_edges (source, target, trail_id, trail_name, length_km, elevation_gain, elevation_loss, geometry, geojson)
        SELECT 
            start_node.id as source, 
            end_node.id as target, 
            t.app_uuid as trail_id, 
            t.name as trail_name, 
            t.length_km as length_km, 
            t.elevation_gain, 
            t.elevation_loss, 
            t.geometry, 
            ST_AsGeoJSON(t.geometry, 6, 0) as geojson 
        FROM %I.trails t
        JOIN %I.routing_nodes start_node ON ST_DWithin(ST_StartPoint(t.geometry), ST_SetSRID(ST_MakePoint(start_node.lng, start_node.lat), 4326), %L)
        JOIN %I.routing_nodes end_node ON ST_DWithin(ST_EndPoint(t.geometry), ST_SetSRID(ST_MakePoint(end_node.lng, end_node.lat), 4326), %L)
        WHERE t.geometry IS NOT NULL 
        AND ST_IsValid(t.geometry) 
        AND t.length_km > 0
        AND start_node.id IS NOT NULL 
        AND end_node.id IS NOT NULL
        AND start_node.id <> end_node.id
    $f$, staging_schema, staging_schema, staging_schema, tolerance_degrees, staging_schema, tolerance_degrees);
    
    GET DIAGNOSTICS edge_count_var = ROW_COUNT;
    
    -- Clean up orphaned nodes (nodes that have no edges)
    EXECUTE format($f$
        DELETE FROM %I.routing_nodes 
        WHERE id NOT IN (
            SELECT DISTINCT source FROM %I.routing_edges 
            UNION 
            SELECT DISTINCT target FROM %I.routing_edges
        )
    $f$, staging_schema, staging_schema, staging_schema, staging_schema);
    
    GET DIAGNOSTICS orphaned_count = ROW_COUNT;
    
    -- Clean up orphaned edges (edges that point to non-existent nodes)
    EXECUTE format($f$
        DELETE FROM %I.routing_edges 
        WHERE source NOT IN (SELECT id FROM %I.routing_nodes) 
        OR target NOT IN (SELECT id FROM %I.routing_nodes)
    $f$, staging_schema, staging_schema, staging_schema, staging_schema);
    
    GET DIAGNOSTICS orphaned_edges_count = ROW_COUNT;
    
    RETURN QUERY SELECT 
        edge_count_var,
        true as success,
        format('Generated %s routing edges from %s nodes, cleaned up %s orphaned nodes and %s orphaned edges (v2, routable only, tolerance: %s m)', edge_count_var, node_count_var, orphaned_count, orphaned_edges_count, tolerance_meters) as message;
        
EXCEPTION WHEN OTHERS THEN
    RETURN QUERY SELECT 
        0, false, 
        format('Error during routing edges generation (v2): %s', SQLERRM) as message;
END;
$function$
;

CREATE OR REPLACE FUNCTION public.generate_routing_nodes_native(staging_schema text, intersection_tolerance_meters real DEFAULT 2.0)
 RETURNS TABLE(node_count integer, success boolean, message text)
 LANGUAGE plpgsql
AS $function$
DECLARE
    node_count_var integer := 0;
    tolerance_degrees real := intersection_tolerance_meters / 111000.0;
BEGIN
    EXECUTE format('DELETE FROM %I.routing_nodes', staging_schema);
    EXECUTE format($f$
        INSERT INTO %I.routing_nodes (id, node_uuid, lat, lng, elevation, node_type, connected_trails, created_at)
        WITH valid_trails AS (
            SELECT app_uuid, name, geometry
            FROM %I.trails 
            WHERE geometry IS NOT NULL 
            AND ST_IsValid(geometry)
            AND ST_Length(geometry) > 0
        ),
        trail_endpoints AS (
            SELECT 
                app_uuid,
                name,
                ST_StartPoint(geometry) as start_point,
                ST_EndPoint(geometry) as end_point,
                ST_Z(ST_StartPoint(geometry)) as start_elevation,
                ST_Z(ST_EndPoint(geometry)) as end_elevation
            FROM valid_trails
        ),
        all_endpoints AS (
            SELECT 
                app_uuid,
                name,
                start_point as point,
                start_elevation as elevation,
                'endpoint' as node_type,
                name as connected_trails
            FROM trail_endpoints
            UNION ALL
            SELECT 
                app_uuid,
                name,
                end_point as point,
                end_elevation as elevation,
                'endpoint' as node_type,
                name as connected_trails
            FROM trail_endpoints
        ),
        unique_nodes AS (
            SELECT DISTINCT
                point,
                elevation,
                node_type,
                connected_trails
            FROM all_endpoints
            WHERE point IS NOT NULL
        ),
        clustered_nodes AS (
            SELECT 
                point as clustered_point,
                elevation,
                node_type,
                connected_trails
            FROM unique_nodes
            WHERE point IS NOT NULL
        )
        SELECT 
            ROW_NUMBER() OVER (ORDER BY ST_X(clustered_point), ST_Y(clustered_point)) as id,
            gen_random_uuid() as node_uuid,
            ST_Y(clustered_point) as lat,
            ST_X(clustered_point) as lng,
            elevation,
            node_type,
            connected_trails,
            NOW() as created_at
        FROM clustered_nodes
        WHERE clustered_point IS NOT NULL
    $f$, staging_schema, staging_schema);
    GET DIAGNOSTICS node_count_var = ROW_COUNT;
    RETURN QUERY SELECT 
        node_count_var,
        true as success,
        format('Generated %s routing nodes (routable only, tolerance: %s m)', node_count_var, intersection_tolerance_meters) as message;
EXCEPTION WHEN OTHERS THEN
    RETURN QUERY SELECT 
        0, false, 
        format('Error during routing nodes generation: %s', SQLERRM) as message;
END;
$function$
;

CREATE OR REPLACE FUNCTION public.generate_routing_nodes_native_v2(staging_schema text, intersection_tolerance_meters real DEFAULT 2.0)
 RETURNS TABLE(node_count integer, success boolean, message text)
 LANGUAGE plpgsql
AS $function$
DECLARE
    node_count_var integer := 0;
    tolerance_degrees real := intersection_tolerance_meters / 111000.0;
BEGIN
    EXECUTE format('DELETE FROM %I.routing_nodes', staging_schema);
    EXECUTE format($f$
        INSERT INTO %I.routing_nodes (id, node_uuid, lat, lng, elevation, node_type, connected_trails, created_at)
        WITH valid_trails AS (
            SELECT app_uuid, name, geometry
            FROM %I.trails 
            WHERE geometry IS NOT NULL 
            AND ST_IsValid(geometry)
            AND ST_Length(geometry) > 0
        ),
        trail_endpoints AS (
            SELECT 
                app_uuid,
                name,
                ST_StartPoint(geometry) as start_point,
                ST_EndPoint(geometry) as end_point,
                ST_Z(ST_StartPoint(geometry)) as start_elevation,
                ST_Z(ST_EndPoint(geometry)) as end_elevation
            FROM valid_trails
        ),
        all_endpoints AS (
            SELECT 
                app_uuid,
                name,
                start_point as point,
                start_elevation as elevation,
                'endpoint' as node_type,
                name as connected_trails
            FROM trail_endpoints
            UNION ALL
            SELECT 
                app_uuid,
                name,
                end_point as point,
                end_elevation as elevation,
                'endpoint' as node_type,
                name as connected_trails
            FROM trail_endpoints
        ),
        unique_nodes AS (
            SELECT DISTINCT
                point,
                elevation,
                node_type,
                connected_trails
            FROM all_endpoints
            WHERE point IS NOT NULL
        ),
        clustered_nodes AS (
            SELECT 
                point as clustered_point,
                elevation,
                node_type,
                connected_trails
            FROM unique_nodes
            WHERE point IS NOT NULL
        )
        SELECT 
            ROW_NUMBER() OVER (ORDER BY ST_X(clustered_point), ST_Y(clustered_point)) as id,
            gen_random_uuid() as node_uuid,
            ST_Y(clustered_point) as lat,
            ST_X(clustered_point) as lng,
            elevation,
            node_type,
            connected_trails,
            NOW() as created_at
        FROM clustered_nodes
        WHERE clustered_point IS NOT NULL
    $f$, staging_schema, staging_schema);
    GET DIAGNOSTICS node_count_var = ROW_COUNT;
    RETURN QUERY SELECT 
        node_count_var,
        true as success,
        format('Generated %s routing nodes (v2, routable only, tolerance: %s m)', node_count_var, intersection_tolerance_meters) as message;
EXCEPTION WHEN OTHERS THEN
    RETURN QUERY SELECT 
        0, false, 
        format('Error during routing nodes generation (v2): %s', SQLERRM) as message;
END;
$function$
;

CREATE OR REPLACE FUNCTION public.generate_routing_nodes_native_v2_with_trail_ids(staging_schema text, intersection_tolerance_meters real DEFAULT 2.0)
 RETURNS TABLE(node_count integer, success boolean, message text)
 LANGUAGE plpgsql
AS $function$
DECLARE
    node_count_var integer := 0;
    tolerance_degrees real := intersection_tolerance_meters / 111000.0;
BEGIN
    -- Clear existing routing nodes
    EXECUTE format('DELETE FROM %I.routing_nodes', staging_schema);
    
    -- Generate routing nodes from actual trail endpoints and intersections with trail_ids
    EXECUTE format($f$
        INSERT INTO %I.routing_nodes (id, node_uuid, lat, lng, elevation, node_type, connected_trails, trail_ids, created_at)
        WITH valid_trails AS (
            SELECT app_uuid, name, geometry
            FROM %I.trails 
            WHERE geometry IS NOT NULL 
            AND ST_IsValid(geometry)
            AND ST_Length(geometry) > 0
        ),
        trail_endpoints AS (
            SELECT 
                app_uuid,
                name,
                ST_StartPoint(geometry) as start_point,
                ST_EndPoint(geometry) as end_point,
                ST_Z(ST_StartPoint(geometry)) as start_elevation,
                ST_Z(ST_EndPoint(geometry)) as end_elevation
            FROM valid_trails
        ),
        all_endpoints AS (
            SELECT 
                app_uuid,
                name,
                start_point as point,
                start_elevation as elevation,
                'endpoint' as node_type,
                name as connected_trails,
                ARRAY[app_uuid] as trail_ids
            FROM trail_endpoints
            UNION ALL
            SELECT 
                app_uuid,
                name,
                end_point as point,
                end_elevation as elevation,
                'endpoint' as node_type,
                name as connected_trails,
                ARRAY[app_uuid] as trail_ids
            FROM trail_endpoints
        ),
        intersection_points AS (
            -- Get intersection points from detect_trail_intersections function
            -- Convert integer trail IDs to text UUIDs by looking them up
            SELECT 
                ip.intersection_point as point,
                COALESCE(ST_Z(ip.intersection_point_3d), 0) as elevation,
                'intersection' as node_type,
                array_to_string(ip.connected_trail_names, ',') as connected_trails,
                array_agg(t.app_uuid) as trail_ids
            FROM detect_trail_intersections($1, 'trails', $2) ip
            JOIN %I.trails t ON t.id = ANY(ip.connected_trail_ids)
            WHERE array_length(ip.connected_trail_ids, 1) > 1
            GROUP BY ip.intersection_point, ip.intersection_point_3d, ip.connected_trail_names
        ),
        all_nodes AS (
            SELECT point, elevation, node_type, connected_trails, trail_ids
            FROM all_endpoints
            WHERE point IS NOT NULL
            UNION ALL
            SELECT point, elevation, node_type, connected_trails, trail_ids
            FROM intersection_points
            WHERE point IS NOT NULL
        ),
        unique_nodes AS (
            SELECT DISTINCT
                point,
                elevation,
                node_type,
                connected_trails,
                trail_ids
            FROM all_nodes
            WHERE point IS NOT NULL
        ),
        clustered_nodes AS (
            SELECT 
                point as clustered_point,
                elevation,
                node_type,
                connected_trails,
                trail_ids
            FROM unique_nodes
            WHERE point IS NOT NULL
        )
        SELECT 
            ROW_NUMBER() OVER (ORDER BY ST_X(clustered_point), ST_Y(clustered_point)) as id,
            gen_random_uuid() as node_uuid,
            ST_Y(clustered_point) as lat,
            ST_X(clustered_point) as lng,
            elevation,
            node_type,
            connected_trails,
            trail_ids,
            NOW() as created_at
        FROM clustered_nodes
        WHERE clustered_point IS NOT NULL
    $f$, staging_schema, staging_schema, staging_schema, staging_schema, staging_schema, staging_schema)
    USING staging_schema, intersection_tolerance_meters;
    
    GET DIAGNOSTICS node_count_var = ROW_COUNT;
    
    RETURN QUERY SELECT 
        node_count_var,
        true as success,
        format('Generated %s routing nodes with trail_ids (v2, routable only, tolerance: %s m)', node_count_var, intersection_tolerance_meters) as message;
        
EXCEPTION WHEN OTHERS THEN
    RETURN QUERY SELECT 
        0, false, 
        format('Error during routing nodes generation with trail_ids (v2): %s', SQLERRM) as message;
END;
$function$
;

CREATE OR REPLACE FUNCTION public.generate_simple_route_recommendations(staging_schema text, region_name text DEFAULT 'boulder'::text)
 RETURNS integer
 LANGUAGE plpgsql
AS $function$
DECLARE
    pattern record;
    routes_found integer := 0;
    total_routes integer := 0;
BEGIN
    RAISE NOTICE 'Starting simple route generation for region: %', region_name;
    EXECUTE format('
        CREATE TABLE IF NOT EXISTS %I.route_recommendations (
            id SERIAL PRIMARY KEY,
            route_uuid TEXT UNIQUE NOT NULL,
            region TEXT NOT NULL,
            input_distance_km REAL CHECK(input_distance_km > 0),
            input_elevation_gain REAL CHECK(input_elevation_gain >= 0),
            recommended_distance_km REAL CHECK(recommended_distance_km > 0),
            recommended_elevation_gain REAL CHECK(recommended_elevation_gain >= 0),
            route_type TEXT,
            route_shape TEXT,
            trail_count INTEGER,
            route_score INTEGER,
            route_path JSONB,
            route_edges JSONB,
            route_name TEXT,
            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        )
    ', staging_schema);
    EXECUTE format('
        CREATE TABLE IF NOT EXISTS %I.route_trails (
            id SERIAL PRIMARY KEY,
            route_uuid TEXT NOT NULL,
            trail_id TEXT NOT NULL,
            trail_name TEXT NOT NULL,
            segment_order INTEGER NOT NULL,
            segment_distance_km REAL CHECK(segment_distance_km > 0),
            segment_elevation_gain REAL CHECK(segment_elevation_gain >= 0),
            segment_elevation_loss REAL CHECK(segment_elevation_loss >= 0),
            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        )
    ', staging_schema);
    EXECUTE format('DELETE FROM %I.route_recommendations', staging_schema);
    EXECUTE format('DELETE FROM %I.route_trails', staging_schema);
    FOR pattern IN SELECT * FROM route_patterns WHERE pattern_name LIKE '%Loop%' OR pattern_name LIKE '%Out-and-Back%' ORDER BY target_distance_km LOOP
        RAISE NOTICE 'Processing pattern: % (%.1f km, %.0f m)', 
            pattern.pattern_name, pattern.target_distance_km, pattern.target_elevation_gain;
        EXECUTE format('
            INSERT INTO %I.route_recommendations (
                route_uuid, region, input_distance_km, input_elevation_gain,
                recommended_distance_km, recommended_elevation_gain, route_type,
                route_shape, trail_count, route_score, route_path, route_edges, route_name
            )
            SELECT 
                r.route_id,
                $1 as region,
                $2 as input_distance_km,
                $3 as input_elevation_gain,
                r.total_distance_km,
                r.total_elevation_gain,
                ''similar_distance'' as route_type,
                r.route_shape,
                r.trail_count,
                (r.similarity_score * 100)::integer as route_score,
                json_build_object(
                    ''type'', ''LineString'',
                    ''coordinates'', array_agg(
                        json_build_array(n.lng, n.lat, n.elevation)
                        ORDER BY array_position(r.route_path, n.id)
                    )
                )::jsonb as route_path,
                json_agg(r.route_edges)::jsonb as route_edges,
                ''Generated Route '' || r.route_id as route_name
            FROM find_simple_routes_with_logging($4, $2, $3, $5) r
            JOIN %I.routing_nodes n ON n.id = ANY(r.route_path)
            WHERE r.route_shape = $6
            GROUP BY r.route_id, r.total_distance_km, r.total_elevation_gain,
                     r.route_shape, r.trail_count, r.similarity_score, r.route_edges
        ', staging_schema, staging_schema)
        USING region_name, pattern.target_distance_km, pattern.target_elevation_gain, 
              staging_schema, pattern.tolerance_percent, pattern.route_shape;
        GET DIAGNOSTICS routes_found = ROW_COUNT;
        total_routes := total_routes + routes_found;
        RAISE NOTICE 'Found % routes for pattern %', routes_found, pattern.pattern_name;
    END LOOP;
    RAISE NOTICE 'Total routes generated: %', total_routes;
    RETURN total_routes;
END;
$function$
;

CREATE OR REPLACE FUNCTION public.geog_brin_inclusion_add_value(internal, internal, internal, internal)
 RETURNS boolean
 LANGUAGE c
 PARALLEL SAFE
AS '$libdir/postgis-3', $function$geog_brin_inclusion_add_value$function$
;

CREATE OR REPLACE FUNCTION public.geog_brin_inclusion_merge(internal, internal)
 RETURNS internal
 LANGUAGE c
 PARALLEL SAFE
AS '$libdir/postgis-3', $function$geog_brin_inclusion_merge$function$
;

CREATE OR REPLACE FUNCTION public.geography(geography, integer, boolean)
 RETURNS geography
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$geography_enforce_typmod$function$
;

CREATE OR REPLACE FUNCTION public.geography(bytea)
 RETURNS geography
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$geography_from_binary$function$
;

CREATE OR REPLACE FUNCTION public.geography(geometry)
 RETURNS geography
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$geography_from_geometry$function$
;

CREATE OR REPLACE FUNCTION public.geography_analyze(internal)
 RETURNS boolean
 LANGUAGE c
 STRICT
AS '$libdir/postgis-3', $function$gserialized_analyze_nd$function$
;

CREATE OR REPLACE FUNCTION public.geography_cmp(geography, geography)
 RETURNS integer
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$geography_cmp$function$
;

CREATE OR REPLACE FUNCTION public.geography_distance_knn(geography, geography)
 RETURNS double precision
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT COST 100
AS '$libdir/postgis-3', $function$geography_distance_knn$function$
;

CREATE OR REPLACE FUNCTION public.geography_eq(geography, geography)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$geography_eq$function$
;

CREATE OR REPLACE FUNCTION public.geography_ge(geography, geography)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$geography_ge$function$
;

CREATE OR REPLACE FUNCTION public.geography_gist_compress(internal)
 RETURNS internal
 LANGUAGE c
AS '$libdir/postgis-3', $function$gserialized_gist_compress$function$
;

CREATE OR REPLACE FUNCTION public.geography_gist_consistent(internal, geography, integer)
 RETURNS boolean
 LANGUAGE c
AS '$libdir/postgis-3', $function$gserialized_gist_consistent$function$
;

CREATE OR REPLACE FUNCTION public.geography_gist_decompress(internal)
 RETURNS internal
 LANGUAGE c
AS '$libdir/postgis-3', $function$gserialized_gist_decompress$function$
;

CREATE OR REPLACE FUNCTION public.geography_gist_distance(internal, geography, integer)
 RETURNS double precision
 LANGUAGE c
AS '$libdir/postgis-3', $function$gserialized_gist_geog_distance$function$
;

CREATE OR REPLACE FUNCTION public.geography_gist_penalty(internal, internal, internal)
 RETURNS internal
 LANGUAGE c
AS '$libdir/postgis-3', $function$gserialized_gist_penalty$function$
;

CREATE OR REPLACE FUNCTION public.geography_gist_picksplit(internal, internal)
 RETURNS internal
 LANGUAGE c
AS '$libdir/postgis-3', $function$gserialized_gist_picksplit$function$
;

CREATE OR REPLACE FUNCTION public.geography_gist_same(box2d, box2d, internal)
 RETURNS internal
 LANGUAGE c
AS '$libdir/postgis-3', $function$gserialized_gist_same$function$
;

CREATE OR REPLACE FUNCTION public.geography_gist_union(bytea, internal)
 RETURNS internal
 LANGUAGE c
AS '$libdir/postgis-3', $function$gserialized_gist_union$function$
;

CREATE OR REPLACE FUNCTION public.geography_gt(geography, geography)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$geography_gt$function$
;

CREATE OR REPLACE FUNCTION public.geography_in(cstring, oid, integer)
 RETURNS geography
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$geography_in$function$
;

CREATE OR REPLACE FUNCTION public.geography_le(geography, geography)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$geography_le$function$
;

CREATE OR REPLACE FUNCTION public.geography_lt(geography, geography)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$geography_lt$function$
;

CREATE OR REPLACE FUNCTION public.geography_out(geography)
 RETURNS cstring
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$geography_out$function$
;

CREATE OR REPLACE FUNCTION public.geography_overlaps(geography, geography)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_overlaps$function$
;

CREATE OR REPLACE FUNCTION public.geography_recv(internal, oid, integer)
 RETURNS geography
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$geography_recv$function$
;

CREATE OR REPLACE FUNCTION public.geography_send(geography)
 RETURNS bytea
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$geography_send$function$
;

CREATE OR REPLACE FUNCTION public.geography_spgist_choose_nd(internal, internal)
 RETURNS void
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_spgist_choose_nd$function$
;

CREATE OR REPLACE FUNCTION public.geography_spgist_compress_nd(internal)
 RETURNS internal
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_spgist_compress_nd$function$
;

CREATE OR REPLACE FUNCTION public.geography_spgist_config_nd(internal, internal)
 RETURNS void
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_spgist_config_nd$function$
;

CREATE OR REPLACE FUNCTION public.geography_spgist_inner_consistent_nd(internal, internal)
 RETURNS void
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_spgist_inner_consistent_nd$function$
;

CREATE OR REPLACE FUNCTION public.geography_spgist_leaf_consistent_nd(internal, internal)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_spgist_leaf_consistent_nd$function$
;

CREATE OR REPLACE FUNCTION public.geography_spgist_picksplit_nd(internal, internal)
 RETURNS void
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_spgist_picksplit_nd$function$
;

CREATE OR REPLACE FUNCTION public.geography_typmod_in(cstring[])
 RETURNS integer
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$geography_typmod_in$function$
;

CREATE OR REPLACE FUNCTION public.geography_typmod_out(integer)
 RETURNS cstring
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$postgis_typmod_out$function$
;

CREATE OR REPLACE FUNCTION public.geom2d_brin_inclusion_add_value(internal, internal, internal, internal)
 RETURNS boolean
 LANGUAGE c
 PARALLEL SAFE
AS '$libdir/postgis-3', $function$geom2d_brin_inclusion_add_value$function$
;

CREATE OR REPLACE FUNCTION public.geom2d_brin_inclusion_merge(internal, internal)
 RETURNS internal
 LANGUAGE c
 PARALLEL SAFE
AS '$libdir/postgis-3', $function$geom2d_brin_inclusion_merge$function$
;

CREATE OR REPLACE FUNCTION public.geom3d_brin_inclusion_add_value(internal, internal, internal, internal)
 RETURNS boolean
 LANGUAGE c
 PARALLEL SAFE
AS '$libdir/postgis-3', $function$geom3d_brin_inclusion_add_value$function$
;

CREATE OR REPLACE FUNCTION public.geom3d_brin_inclusion_merge(internal, internal)
 RETURNS internal
 LANGUAGE c
 PARALLEL SAFE
AS '$libdir/postgis-3', $function$geom3d_brin_inclusion_merge$function$
;

CREATE OR REPLACE FUNCTION public.geom4d_brin_inclusion_add_value(internal, internal, internal, internal)
 RETURNS boolean
 LANGUAGE c
 PARALLEL SAFE
AS '$libdir/postgis-3', $function$geom4d_brin_inclusion_add_value$function$
;

CREATE OR REPLACE FUNCTION public.geom4d_brin_inclusion_merge(internal, internal)
 RETURNS internal
 LANGUAGE c
 PARALLEL SAFE
AS '$libdir/postgis-3', $function$geom4d_brin_inclusion_merge$function$
;

CREATE OR REPLACE FUNCTION public.geometry(text)
 RETURNS geometry
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT COST 50
AS '$libdir/postgis-3', $function$parse_WKT_lwgeom$function$
;

CREATE OR REPLACE FUNCTION public.geometry(point)
 RETURNS geometry
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$point_to_geometry$function$
;

CREATE OR REPLACE FUNCTION public.geometry(geometry, integer, boolean)
 RETURNS geometry
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$geometry_enforce_typmod$function$
;

CREATE OR REPLACE FUNCTION public.geometry(geography)
 RETURNS geometry
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$geometry_from_geography$function$
;

CREATE OR REPLACE FUNCTION public.geometry(box2d)
 RETURNS geometry
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT COST 50
AS '$libdir/postgis-3', $function$BOX2D_to_LWGEOM$function$
;

CREATE OR REPLACE FUNCTION public.geometry(path)
 RETURNS geometry
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$path_to_geometry$function$
;

CREATE OR REPLACE FUNCTION public.geometry(polygon)
 RETURNS geometry
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$polygon_to_geometry$function$
;

CREATE OR REPLACE FUNCTION public.geometry(box3d)
 RETURNS geometry
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT COST 50
AS '$libdir/postgis-3', $function$BOX3D_to_LWGEOM$function$
;

CREATE OR REPLACE FUNCTION public.geometry(bytea)
 RETURNS geometry
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT COST 50
AS '$libdir/postgis-3', $function$LWGEOM_from_bytea$function$
;

CREATE OR REPLACE FUNCTION public.geometry_above(geom1 geometry, geom2 geometry)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_above_2d$function$
;

CREATE OR REPLACE FUNCTION public.geometry_analyze(internal)
 RETURNS boolean
 LANGUAGE c
 STRICT
AS '$libdir/postgis-3', $function$gserialized_analyze_nd$function$
;

CREATE OR REPLACE FUNCTION public.geometry_below(geom1 geometry, geom2 geometry)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_below_2d$function$
;

CREATE OR REPLACE FUNCTION public.geometry_cmp(geom1 geometry, geom2 geometry)
 RETURNS integer
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$lwgeom_cmp$function$
;

CREATE OR REPLACE FUNCTION public.geometry_contained_3d(geom1 geometry, geom2 geometry)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_contained_3d$function$
;

CREATE OR REPLACE FUNCTION public.geometry_contained_by_raster(geometry, raster)
 RETURNS boolean
 LANGUAGE sql
 IMMUTABLE PARALLEL SAFE STRICT
AS $function$select $1 OPERATOR(public.@) $2::public.geometry$function$
;

CREATE OR REPLACE FUNCTION public.geometry_contains(geom1 geometry, geom2 geometry)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_contains_2d$function$
;

CREATE OR REPLACE FUNCTION public.geometry_contains_3d(geom1 geometry, geom2 geometry)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_contains_3d$function$
;

CREATE OR REPLACE FUNCTION public.geometry_contains_nd(geometry, geometry)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_contains$function$
;

CREATE OR REPLACE FUNCTION public.geometry_distance_box(geom1 geometry, geom2 geometry)
 RETURNS double precision
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_distance_box_2d$function$
;

CREATE OR REPLACE FUNCTION public.geometry_distance_centroid(geom1 geometry, geom2 geometry)
 RETURNS double precision
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT COST 250
AS '$libdir/postgis-3', $function$ST_Distance$function$
;

CREATE OR REPLACE FUNCTION public.geometry_distance_centroid_nd(geometry, geometry)
 RETURNS double precision
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_distance_nd$function$
;

CREATE OR REPLACE FUNCTION public.geometry_distance_cpa(geometry, geometry)
 RETURNS double precision
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT COST 5000
AS '$libdir/postgis-3', $function$ST_DistanceCPA$function$
;

CREATE OR REPLACE FUNCTION public.geometry_eq(geom1 geometry, geom2 geometry)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$lwgeom_eq$function$
;

CREATE OR REPLACE FUNCTION public.geometry_ge(geom1 geometry, geom2 geometry)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$lwgeom_ge$function$
;

CREATE OR REPLACE FUNCTION public.geometry_gist_compress_2d(internal)
 RETURNS internal
 LANGUAGE c
 PARALLEL SAFE
AS '$libdir/postgis-3', $function$gserialized_gist_compress_2d$function$
;

CREATE OR REPLACE FUNCTION public.geometry_gist_compress_nd(internal)
 RETURNS internal
 LANGUAGE c
 PARALLEL SAFE
AS '$libdir/postgis-3', $function$gserialized_gist_compress$function$
;

CREATE OR REPLACE FUNCTION public.geometry_gist_consistent_2d(internal, geometry, integer)
 RETURNS boolean
 LANGUAGE c
 PARALLEL SAFE
AS '$libdir/postgis-3', $function$gserialized_gist_consistent_2d$function$
;

CREATE OR REPLACE FUNCTION public.geometry_gist_consistent_nd(internal, geometry, integer)
 RETURNS boolean
 LANGUAGE c
 PARALLEL SAFE
AS '$libdir/postgis-3', $function$gserialized_gist_consistent$function$
;

CREATE OR REPLACE FUNCTION public.geometry_gist_decompress_2d(internal)
 RETURNS internal
 LANGUAGE c
 PARALLEL SAFE
AS '$libdir/postgis-3', $function$gserialized_gist_decompress_2d$function$
;

CREATE OR REPLACE FUNCTION public.geometry_gist_decompress_nd(internal)
 RETURNS internal
 LANGUAGE c
 PARALLEL SAFE
AS '$libdir/postgis-3', $function$gserialized_gist_decompress$function$
;

CREATE OR REPLACE FUNCTION public.geometry_gist_distance_2d(internal, geometry, integer)
 RETURNS double precision
 LANGUAGE c
 PARALLEL SAFE
AS '$libdir/postgis-3', $function$gserialized_gist_distance_2d$function$
;

CREATE OR REPLACE FUNCTION public.geometry_gist_distance_nd(internal, geometry, integer)
 RETURNS double precision
 LANGUAGE c
 PARALLEL SAFE
AS '$libdir/postgis-3', $function$gserialized_gist_distance$function$
;

CREATE OR REPLACE FUNCTION public.geometry_gist_penalty_2d(internal, internal, internal)
 RETURNS internal
 LANGUAGE c
 PARALLEL SAFE
AS '$libdir/postgis-3', $function$gserialized_gist_penalty_2d$function$
;

CREATE OR REPLACE FUNCTION public.geometry_gist_penalty_nd(internal, internal, internal)
 RETURNS internal
 LANGUAGE c
 PARALLEL SAFE
AS '$libdir/postgis-3', $function$gserialized_gist_penalty$function$
;

CREATE OR REPLACE FUNCTION public.geometry_gist_picksplit_2d(internal, internal)
 RETURNS internal
 LANGUAGE c
 PARALLEL SAFE
AS '$libdir/postgis-3', $function$gserialized_gist_picksplit_2d$function$
;

CREATE OR REPLACE FUNCTION public.geometry_gist_picksplit_nd(internal, internal)
 RETURNS internal
 LANGUAGE c
 PARALLEL SAFE
AS '$libdir/postgis-3', $function$gserialized_gist_picksplit$function$
;

CREATE OR REPLACE FUNCTION public.geometry_gist_same_2d(geom1 geometry, geom2 geometry, internal)
 RETURNS internal
 LANGUAGE c
 PARALLEL SAFE
AS '$libdir/postgis-3', $function$gserialized_gist_same_2d$function$
;

CREATE OR REPLACE FUNCTION public.geometry_gist_same_nd(geometry, geometry, internal)
 RETURNS internal
 LANGUAGE c
 PARALLEL SAFE
AS '$libdir/postgis-3', $function$gserialized_gist_same$function$
;

CREATE OR REPLACE FUNCTION public.geometry_gist_sortsupport_2d(internal)
 RETURNS void
 LANGUAGE c
 STRICT
AS '$libdir/postgis-3', $function$gserialized_gist_sortsupport_2d$function$
;

CREATE OR REPLACE FUNCTION public.geometry_gist_union_2d(bytea, internal)
 RETURNS internal
 LANGUAGE c
 PARALLEL SAFE
AS '$libdir/postgis-3', $function$gserialized_gist_union_2d$function$
;

CREATE OR REPLACE FUNCTION public.geometry_gist_union_nd(bytea, internal)
 RETURNS internal
 LANGUAGE c
 PARALLEL SAFE
AS '$libdir/postgis-3', $function$gserialized_gist_union$function$
;

CREATE OR REPLACE FUNCTION public.geometry_gt(geom1 geometry, geom2 geometry)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$lwgeom_gt$function$
;

CREATE OR REPLACE FUNCTION public.geometry_hash(geometry)
 RETURNS integer
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$lwgeom_hash$function$
;

CREATE OR REPLACE FUNCTION public.geometry_in(cstring)
 RETURNS geometry
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$LWGEOM_in$function$
;

CREATE OR REPLACE FUNCTION public.geometry_le(geom1 geometry, geom2 geometry)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$lwgeom_le$function$
;

CREATE OR REPLACE FUNCTION public.geometry_left(geom1 geometry, geom2 geometry)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_left_2d$function$
;

CREATE OR REPLACE FUNCTION public.geometry_lt(geom1 geometry, geom2 geometry)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$lwgeom_lt$function$
;

CREATE OR REPLACE FUNCTION public.geometry_neq(geom1 geometry, geom2 geometry)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$lwgeom_neq$function$
;

CREATE OR REPLACE FUNCTION public.geometry_out(geometry)
 RETURNS cstring
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$LWGEOM_out$function$
;

CREATE OR REPLACE FUNCTION public.geometry_overabove(geom1 geometry, geom2 geometry)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_overabove_2d$function$
;

CREATE OR REPLACE FUNCTION public.geometry_overbelow(geom1 geometry, geom2 geometry)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_overbelow_2d$function$
;

CREATE OR REPLACE FUNCTION public.geometry_overlaps(geom1 geometry, geom2 geometry)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_overlaps_2d$function$
;

CREATE OR REPLACE FUNCTION public.geometry_overlaps_3d(geom1 geometry, geom2 geometry)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_overlaps_3d$function$
;

CREATE OR REPLACE FUNCTION public.geometry_overlaps_nd(geometry, geometry)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_overlaps$function$
;

CREATE OR REPLACE FUNCTION public.geometry_overleft(geom1 geometry, geom2 geometry)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_overleft_2d$function$
;

CREATE OR REPLACE FUNCTION public.geometry_overright(geom1 geometry, geom2 geometry)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_overright_2d$function$
;

CREATE OR REPLACE FUNCTION public.geometry_raster_contain(geometry, raster)
 RETURNS boolean
 LANGUAGE sql
 IMMUTABLE PARALLEL SAFE STRICT
AS $function$select $1 OPERATOR(public.~) $2::public.geometry$function$
;

CREATE OR REPLACE FUNCTION public.geometry_raster_overlap(geometry, raster)
 RETURNS boolean
 LANGUAGE sql
 IMMUTABLE PARALLEL SAFE STRICT
AS $function$select $1 OPERATOR(public.&&) $2::public.geometry$function$
;

CREATE OR REPLACE FUNCTION public.geometry_recv(internal)
 RETURNS geometry
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$LWGEOM_recv$function$
;

CREATE OR REPLACE FUNCTION public.geometry_right(geom1 geometry, geom2 geometry)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_right_2d$function$
;

CREATE OR REPLACE FUNCTION public.geometry_same(geom1 geometry, geom2 geometry)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_same_2d$function$
;

CREATE OR REPLACE FUNCTION public.geometry_same_3d(geom1 geometry, geom2 geometry)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_same_3d$function$
;

CREATE OR REPLACE FUNCTION public.geometry_same_nd(geometry, geometry)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_same$function$
;

CREATE OR REPLACE FUNCTION public.geometry_send(geometry)
 RETURNS bytea
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$LWGEOM_send$function$
;

CREATE OR REPLACE FUNCTION public.geometry_sortsupport(internal)
 RETURNS void
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$lwgeom_sortsupport$function$
;

CREATE OR REPLACE FUNCTION public.geometry_spgist_choose_2d(internal, internal)
 RETURNS void
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_spgist_choose_2d$function$
;

CREATE OR REPLACE FUNCTION public.geometry_spgist_choose_3d(internal, internal)
 RETURNS void
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_spgist_choose_3d$function$
;

CREATE OR REPLACE FUNCTION public.geometry_spgist_choose_nd(internal, internal)
 RETURNS void
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_spgist_choose_nd$function$
;

CREATE OR REPLACE FUNCTION public.geometry_spgist_compress_2d(internal)
 RETURNS internal
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_spgist_compress_2d$function$
;

CREATE OR REPLACE FUNCTION public.geometry_spgist_compress_3d(internal)
 RETURNS internal
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_spgist_compress_3d$function$
;

CREATE OR REPLACE FUNCTION public.geometry_spgist_compress_nd(internal)
 RETURNS internal
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_spgist_compress_nd$function$
;

CREATE OR REPLACE FUNCTION public.geometry_spgist_config_2d(internal, internal)
 RETURNS void
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_spgist_config_2d$function$
;

CREATE OR REPLACE FUNCTION public.geometry_spgist_config_3d(internal, internal)
 RETURNS void
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_spgist_config_3d$function$
;

CREATE OR REPLACE FUNCTION public.geometry_spgist_config_nd(internal, internal)
 RETURNS void
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_spgist_config_nd$function$
;

CREATE OR REPLACE FUNCTION public.geometry_spgist_inner_consistent_2d(internal, internal)
 RETURNS void
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_spgist_inner_consistent_2d$function$
;

CREATE OR REPLACE FUNCTION public.geometry_spgist_inner_consistent_3d(internal, internal)
 RETURNS void
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_spgist_inner_consistent_3d$function$
;

CREATE OR REPLACE FUNCTION public.geometry_spgist_inner_consistent_nd(internal, internal)
 RETURNS void
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_spgist_inner_consistent_nd$function$
;

CREATE OR REPLACE FUNCTION public.geometry_spgist_leaf_consistent_2d(internal, internal)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_spgist_leaf_consistent_2d$function$
;

CREATE OR REPLACE FUNCTION public.geometry_spgist_leaf_consistent_3d(internal, internal)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_spgist_leaf_consistent_3d$function$
;

CREATE OR REPLACE FUNCTION public.geometry_spgist_leaf_consistent_nd(internal, internal)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_spgist_leaf_consistent_nd$function$
;

CREATE OR REPLACE FUNCTION public.geometry_spgist_picksplit_2d(internal, internal)
 RETURNS void
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_spgist_picksplit_2d$function$
;

CREATE OR REPLACE FUNCTION public.geometry_spgist_picksplit_3d(internal, internal)
 RETURNS void
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_spgist_picksplit_3d$function$
;

CREATE OR REPLACE FUNCTION public.geometry_spgist_picksplit_nd(internal, internal)
 RETURNS void
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_spgist_picksplit_nd$function$
;

CREATE OR REPLACE FUNCTION public.geometry_typmod_in(cstring[])
 RETURNS integer
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$geometry_typmod_in$function$
;

CREATE OR REPLACE FUNCTION public.geometry_typmod_out(integer)
 RETURNS cstring
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$postgis_typmod_out$function$
;

CREATE OR REPLACE FUNCTION public.geometry_within(geom1 geometry, geom2 geometry)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_within_2d$function$
;

CREATE OR REPLACE FUNCTION public.geometry_within_nd(geometry, geometry)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_within$function$
;

CREATE OR REPLACE FUNCTION public.geometrytype(geography)
 RETURNS text
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$LWGEOM_getTYPE$function$
;

CREATE OR REPLACE FUNCTION public.geometrytype(geometry)
 RETURNS text
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$LWGEOM_getTYPE$function$
;

CREATE OR REPLACE FUNCTION public.geomfromewkb(bytea)
 RETURNS geometry
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT COST 50
AS '$libdir/postgis-3', $function$LWGEOMFromEWKB$function$
;

CREATE OR REPLACE FUNCTION public.geomfromewkt(text)
 RETURNS geometry
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT COST 50
AS '$libdir/postgis-3', $function$parse_WKT_lwgeom$function$
;

CREATE OR REPLACE FUNCTION public.get_batch_size()
 RETURNS integer
 LANGUAGE plpgsql
AS $function$
BEGIN
    RETURN (get_carthorse_config() ->> 'batch_size')::integer;
END;
$function$
;

CREATE OR REPLACE FUNCTION public.get_carthorse_config()
 RETURNS json
 LANGUAGE plpgsql
AS $function$
BEGIN
    RETURN json_build_object(
        'intersection_tolerance', 2,
        'edge_tolerance', 2,
        'simplify_tolerance', 0.001,
        'batch_size', 1000,
        'timeout_ms', 30000,
        'min_trail_length_meters', 1,
        'max_trail_length_meters', 100000,
        'min_elevation_meters', 0,
        'max_elevation_meters', 9000,
        'min_coordinate_points', 2,
        'max_coordinate_points', 10000,
        'max_routes_per_bin', 10,
        'min_route_score', 0.3,
        'min_route_distance_km', 1,
        'max_route_distance_km', 20,
        'min_elevation_gain_meters', 10,
        'max_elevation_gain_meters', 5000,
        'distance_weight', 0.5,
        'elevation_weight', 0.3,
        'quality_weight', 0.3,
        'steepness_weight', 2,
        'routing_distance_weight', 0.5
    );
END;
$function$
;

CREATE OR REPLACE FUNCTION public.get_cost_weights()
 RETURNS json
 LANGUAGE plpgsql
AS $function$
BEGIN
    RETURN json_build_object(
        'steepness_weight', (get_carthorse_config() ->> 'steepness_weight')::float,
        'distance_weight', (get_carthorse_config() ->> 'routing_distance_weight')::float
    );
END;
$function$
;

CREATE OR REPLACE FUNCTION public.get_edge_tolerance()
 RETURNS double precision
 LANGUAGE plpgsql
AS $function$
BEGIN
    RETURN (get_carthorse_config() ->> 'edge_tolerance')::float;
END;
$function$
;

CREATE OR REPLACE FUNCTION public.get_elevation_gain_limits()
 RETURNS json
 LANGUAGE plpgsql
AS $function$
BEGIN
    RETURN json_build_object(
        'min_meters', (get_carthorse_config() ->> 'min_elevation_gain_meters')::float,
        'max_meters', (get_carthorse_config() ->> 'max_elevation_gain_meters')::float
    );
END;
$function$
;

CREATE OR REPLACE FUNCTION public.get_intersection_stats(staging_schema text)
 RETURNS TABLE(total_nodes integer, intersection_nodes integer, endpoint_nodes integer, total_edges integer, node_to_trail_ratio double precision, processing_time_ms integer)
 LANGUAGE plpgsql
AS $function$
DECLARE
    start_time timestamp;
    end_time timestamp;
    trail_count integer;
BEGIN
    start_time := clock_timestamp();
    EXECUTE format('SELECT COUNT(*) FROM %I.trails', staging_schema) INTO trail_count;
    RETURN QUERY EXECUTE format('
        SELECT 
            (SELECT COUNT(*) FROM %I.routing_nodes) as total_nodes,
            (SELECT COUNT(*) FROM %I.routing_nodes WHERE node_type = ''intersection'') as intersection_nodes,
            (SELECT COUNT(*) FROM %I.routing_nodes WHERE node_type = ''endpoint'') as endpoint_nodes,
            (SELECT COUNT(*) FROM %I.routing_edges) as total_edges,
            CASE 
                WHEN $1 > 0 THEN (SELECT COUNT(*) FROM %I.routing_nodes)::float / $1
                ELSE 0
            END as node_to_trail_ratio,
            EXTRACT(EPOCH FROM (clock_timestamp() - $2::timestamp)) * 1000 as processing_time_ms
    ', staging_schema, staging_schema, staging_schema, staging_schema, staging_schema)
    USING trail_count, start_time;
    end_time := clock_timestamp();
END;
$function$
;

CREATE OR REPLACE FUNCTION public.get_intersection_tolerance()
 RETURNS double precision
 LANGUAGE plpgsql
AS $function$
BEGIN
    RETURN (get_carthorse_config() ->> 'intersection_tolerance')::float;
END;
$function$
;

CREATE OR REPLACE FUNCTION public.get_max_routes_per_bin()
 RETURNS integer
 LANGUAGE plpgsql
AS $function$
BEGIN
    RETURN 10; -- Default max routes per bin
END;
$function$
;

CREATE OR REPLACE FUNCTION public.get_min_route_score()
 RETURNS double precision
 LANGUAGE plpgsql
AS $function$
BEGIN
    RETURN 0.3; -- Default minimum score
END;
$function$
;

CREATE OR REPLACE FUNCTION public.get_proj4_from_srid(integer)
 RETURNS text
 LANGUAGE plpgsql
 IMMUTABLE PARALLEL SAFE STRICT
AS $function$
	BEGIN
	RETURN proj4text::text FROM public.spatial_ref_sys WHERE srid= $1;
	END;
	$function$
;

CREATE OR REPLACE FUNCTION public.get_route_distance_limits()
 RETURNS json
 LANGUAGE plpgsql
AS $function$
BEGIN
    RETURN json_build_object(
        'min_km', (get_carthorse_config() ->> 'min_route_distance_km')::float,
        'max_km', (get_carthorse_config() ->> 'max_route_distance_km')::float
    );
END;
$function$
;

CREATE OR REPLACE FUNCTION public.get_route_patterns()
 RETURNS TABLE(pattern_name text, target_distance_km double precision, target_elevation_gain double precision, route_shape text, tolerance_percent double precision)
 LANGUAGE plpgsql
AS $function$
BEGIN
    RETURN QUERY SELECT 
        rp.pattern_name,
        rp.target_distance_km,
        rp.target_elevation_gain,
        rp.route_shape,
        rp.tolerance_percent
    FROM route_patterns rp
    ORDER BY rp.target_distance_km, rp.target_elevation_gain;
END;
$function$
;

CREATE OR REPLACE FUNCTION public.get_scoring_weights()
 RETURNS json
 LANGUAGE plpgsql
AS $function$
BEGIN
    RETURN json_build_object(
        'distance_weight', (get_carthorse_config() ->> 'distance_weight')::float,
        'elevation_weight', (get_carthorse_config() ->> 'elevation_weight')::float,
        'quality_weight', (get_carthorse_config() ->> 'quality_weight')::float
    );
END;
$function$
;

CREATE OR REPLACE FUNCTION public.get_simplify_tolerance()
 RETURNS double precision
 LANGUAGE plpgsql
AS $function$
BEGIN
    RETURN (get_carthorse_config() ->> 'simplify_tolerance')::float;
END;
$function$
;

CREATE OR REPLACE FUNCTION public.get_timeout_ms()
 RETURNS integer
 LANGUAGE plpgsql
AS $function$
BEGIN
    RETURN (get_carthorse_config() ->> 'timeout_ms')::integer;
END;
$function$
;

CREATE OR REPLACE FUNCTION public.get_trails_with_geojson(p_region text DEFAULT NULL::text, p_limit integer DEFAULT 100)
 RETURNS TABLE(id integer, app_uuid text, name text, region text, length_km real, elevation_gain real, geojson text)
 LANGUAGE plpgsql
AS $function$
BEGIN
    RETURN QUERY
    SELECT 
        t.id,
        t.app_uuid,
        t.name,
        t.region,
        t.length_km,
        t.elevation_gain,
        COALESCE(t.geojson_cached, ST_AsGeoJSON(t.geometry, 6, 0)) as geojson
    FROM trails t
    WHERE (p_region IS NULL OR t.region = p_region)
    ORDER BY t.name
    LIMIT p_limit;
END;
$function$
;

CREATE OR REPLACE FUNCTION public.gidx_in(cstring)
 RETURNS gidx
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gidx_in$function$
;

CREATE OR REPLACE FUNCTION public.gidx_out(gidx)
 RETURNS cstring
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gidx_out$function$
;

CREATE OR REPLACE FUNCTION public.gserialized_gist_joinsel_2d(internal, oid, internal, smallint)
 RETURNS double precision
 LANGUAGE c
 PARALLEL SAFE
AS '$libdir/postgis-3', $function$gserialized_gist_joinsel_2d$function$
;

CREATE OR REPLACE FUNCTION public.gserialized_gist_joinsel_nd(internal, oid, internal, smallint)
 RETURNS double precision
 LANGUAGE c
 PARALLEL SAFE
AS '$libdir/postgis-3', $function$gserialized_gist_joinsel_nd$function$
;

CREATE OR REPLACE FUNCTION public.gserialized_gist_sel_2d(internal, oid, internal, integer)
 RETURNS double precision
 LANGUAGE c
 PARALLEL SAFE
AS '$libdir/postgis-3', $function$gserialized_gist_sel_2d$function$
;

CREATE OR REPLACE FUNCTION public.gserialized_gist_sel_nd(internal, oid, internal, integer)
 RETURNS double precision
 LANGUAGE c
 PARALLEL SAFE
AS '$libdir/postgis-3', $function$gserialized_gist_sel_nd$function$
;

CREATE OR REPLACE FUNCTION public.is_contained_2d(geometry, box2df)
 RETURNS boolean
 LANGUAGE sql
 IMMUTABLE PARALLEL SAFE STRICT COST 1
AS $function$SELECT $2 OPERATOR(public.~) $1;$function$
;

CREATE OR REPLACE FUNCTION public.is_contained_2d(box2df, box2df)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_contains_box2df_box2df_2d$function$
;

CREATE OR REPLACE FUNCTION public.is_contained_2d(box2df, geometry)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_within_box2df_geom_2d$function$
;

CREATE OR REPLACE FUNCTION public.json(geometry)
 RETURNS json
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT COST 250
AS '$libdir/postgis-3', $function$geometry_to_json$function$
;

CREATE OR REPLACE FUNCTION public.jsonb(geometry)
 RETURNS jsonb
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT COST 250
AS '$libdir/postgis-3', $function$geometry_to_jsonb$function$
;

CREATE OR REPLACE FUNCTION public.levenshtein(text, text)
 RETURNS integer
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/fuzzystrmatch', $function$levenshtein$function$
;

CREATE OR REPLACE FUNCTION public.levenshtein(text, text, integer, integer, integer)
 RETURNS integer
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/fuzzystrmatch', $function$levenshtein_with_costs$function$
;

CREATE OR REPLACE FUNCTION public.levenshtein_less_equal(text, text, integer, integer, integer, integer)
 RETURNS integer
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/fuzzystrmatch', $function$levenshtein_less_equal_with_costs$function$
;

CREATE OR REPLACE FUNCTION public.levenshtein_less_equal(text, text, integer)
 RETURNS integer
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/fuzzystrmatch', $function$levenshtein_less_equal$function$
;

CREATE OR REPLACE FUNCTION public.metaphone(text, integer)
 RETURNS text
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/fuzzystrmatch', $function$metaphone$function$
;

CREATE OR REPLACE FUNCTION public.overlaps_2d(geometry, box2df)
 RETURNS boolean
 LANGUAGE sql
 IMMUTABLE PARALLEL SAFE STRICT COST 1
AS $function$SELECT $2 OPERATOR(public.&&) $1;$function$
;

CREATE OR REPLACE FUNCTION public.overlaps_2d(box2df, box2df)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_contains_box2df_box2df_2d$function$
;

CREATE OR REPLACE FUNCTION public.overlaps_2d(box2df, geometry)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_overlaps_box2df_geom_2d$function$
;

CREATE OR REPLACE FUNCTION public.overlaps_geog(gidx, geography)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE STRICT
AS '$libdir/postgis-3', $function$gserialized_gidx_geog_overlaps$function$
;

CREATE OR REPLACE FUNCTION public.overlaps_geog(gidx, gidx)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE STRICT
AS '$libdir/postgis-3', $function$gserialized_gidx_gidx_overlaps$function$
;

CREATE OR REPLACE FUNCTION public.overlaps_geog(geography, gidx)
 RETURNS boolean
 LANGUAGE sql
 IMMUTABLE STRICT
AS $function$SELECT $2 OPERATOR(public.&&) $1;$function$
;

CREATE OR REPLACE FUNCTION public.overlaps_nd(gidx, geometry)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_gidx_geom_overlaps$function$
;

CREATE OR REPLACE FUNCTION public.overlaps_nd(gidx, gidx)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$gserialized_gidx_gidx_overlaps$function$
;

CREATE OR REPLACE FUNCTION public.overlaps_nd(geometry, gidx)
 RETURNS boolean
 LANGUAGE sql
 IMMUTABLE PARALLEL SAFE STRICT COST 1
AS $function$SELECT $2 OPERATOR(public.&&&) $1;$function$
;

CREATE OR REPLACE FUNCTION public.path(geometry)
 RETURNS path
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$geometry_to_path$function$
;

CREATE OR REPLACE FUNCTION public.pgis_asflatgeobuf_finalfn(internal)
 RETURNS bytea
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE COST 250
AS '$libdir/postgis-3', $function$pgis_asflatgeobuf_finalfn$function$
;

CREATE OR REPLACE FUNCTION public.pgis_asflatgeobuf_transfn(internal, anyelement)
 RETURNS internal
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE COST 50
AS '$libdir/postgis-3', $function$pgis_asflatgeobuf_transfn$function$
;

CREATE OR REPLACE FUNCTION public.pgis_asflatgeobuf_transfn(internal, anyelement, boolean)
 RETURNS internal
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE COST 50
AS '$libdir/postgis-3', $function$pgis_asflatgeobuf_transfn$function$
;

CREATE OR REPLACE FUNCTION public.pgis_asflatgeobuf_transfn(internal, anyelement, boolean, text)
 RETURNS internal
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE COST 50
AS '$libdir/postgis-3', $function$pgis_asflatgeobuf_transfn$function$
;

CREATE OR REPLACE FUNCTION public.pgis_asgeobuf_finalfn(internal)
 RETURNS bytea
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE COST 250
AS '$libdir/postgis-3', $function$pgis_asgeobuf_finalfn$function$
;

CREATE OR REPLACE FUNCTION public.pgis_asgeobuf_transfn(internal, anyelement, text)
 RETURNS internal
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE COST 50
AS '$libdir/postgis-3', $function$pgis_asgeobuf_transfn$function$
;

CREATE OR REPLACE FUNCTION public.pgis_asgeobuf_transfn(internal, anyelement)
 RETURNS internal
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE COST 50
AS '$libdir/postgis-3', $function$pgis_asgeobuf_transfn$function$
;

CREATE OR REPLACE FUNCTION public.pgis_asmvt_combinefn(internal, internal)
 RETURNS internal
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE COST 250
AS '$libdir/postgis-3', $function$pgis_asmvt_combinefn$function$
;

CREATE OR REPLACE FUNCTION public.pgis_asmvt_deserialfn(bytea, internal)
 RETURNS internal
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE COST 250
AS '$libdir/postgis-3', $function$pgis_asmvt_deserialfn$function$
;

CREATE OR REPLACE FUNCTION public.pgis_asmvt_finalfn(internal)
 RETURNS bytea
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE COST 250
AS '$libdir/postgis-3', $function$pgis_asmvt_finalfn$function$
;

CREATE OR REPLACE FUNCTION public.pgis_asmvt_serialfn(internal)
 RETURNS bytea
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE COST 250
AS '$libdir/postgis-3', $function$pgis_asmvt_serialfn$function$
;

CREATE OR REPLACE FUNCTION public.pgis_asmvt_transfn(internal, anyelement, text, integer, text, text)
 RETURNS internal
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE COST 250
AS '$libdir/postgis-3', $function$pgis_asmvt_transfn$function$
;

CREATE OR REPLACE FUNCTION public.pgis_asmvt_transfn(internal, anyelement, text, integer)
 RETURNS internal
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE COST 250
AS '$libdir/postgis-3', $function$pgis_asmvt_transfn$function$
;

CREATE OR REPLACE FUNCTION public.pgis_asmvt_transfn(internal, anyelement, text, integer, text)
 RETURNS internal
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE COST 250
AS '$libdir/postgis-3', $function$pgis_asmvt_transfn$function$
;

CREATE OR REPLACE FUNCTION public.pgis_asmvt_transfn(internal, anyelement, text)
 RETURNS internal
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE COST 250
AS '$libdir/postgis-3', $function$pgis_asmvt_transfn$function$
;

CREATE OR REPLACE FUNCTION public.pgis_asmvt_transfn(internal, anyelement)
 RETURNS internal
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE COST 250
AS '$libdir/postgis-3', $function$pgis_asmvt_transfn$function$
;

CREATE OR REPLACE FUNCTION public.pgis_geometry_accum_transfn(internal, geometry)
 RETURNS internal
 LANGUAGE c
 PARALLEL SAFE COST 50
AS '$libdir/postgis-3', $function$pgis_geometry_accum_transfn$function$
;

CREATE OR REPLACE FUNCTION public.pgis_geometry_accum_transfn(internal, geometry, double precision, integer)
 RETURNS internal
 LANGUAGE c
 PARALLEL SAFE COST 50
AS '$libdir/postgis-3', $function$pgis_geometry_accum_transfn$function$
;

CREATE OR REPLACE FUNCTION public.pgis_geometry_accum_transfn(internal, geometry, double precision)
 RETURNS internal
 LANGUAGE c
 PARALLEL SAFE COST 50
AS '$libdir/postgis-3', $function$pgis_geometry_accum_transfn$function$
;

CREATE OR REPLACE FUNCTION public.pgis_geometry_clusterintersecting_finalfn(internal)
 RETURNS geometry[]
 LANGUAGE c
 PARALLEL SAFE COST 250
AS '$libdir/postgis-3', $function$pgis_geometry_clusterintersecting_finalfn$function$
;

CREATE OR REPLACE FUNCTION public.pgis_geometry_clusterwithin_finalfn(internal)
 RETURNS geometry[]
 LANGUAGE c
 PARALLEL SAFE COST 250
AS '$libdir/postgis-3', $function$pgis_geometry_clusterwithin_finalfn$function$
;

CREATE OR REPLACE FUNCTION public.pgis_geometry_collect_finalfn(internal)
 RETURNS geometry
 LANGUAGE c
 PARALLEL SAFE COST 250
AS '$libdir/postgis-3', $function$pgis_geometry_collect_finalfn$function$
;

CREATE OR REPLACE FUNCTION public.pgis_geometry_coverageunion_finalfn(internal)
 RETURNS geometry
 LANGUAGE c
 PARALLEL SAFE COST 250
AS '$libdir/postgis-3', $function$pgis_geometry_coverageunion_finalfn$function$
;

CREATE OR REPLACE FUNCTION public.pgis_geometry_makeline_finalfn(internal)
 RETURNS geometry
 LANGUAGE c
 PARALLEL SAFE COST 250
AS '$libdir/postgis-3', $function$pgis_geometry_makeline_finalfn$function$
;

CREATE OR REPLACE FUNCTION public.pgis_geometry_polygonize_finalfn(internal)
 RETURNS geometry
 LANGUAGE c
 PARALLEL SAFE COST 250
AS '$libdir/postgis-3', $function$pgis_geometry_polygonize_finalfn$function$
;

CREATE OR REPLACE FUNCTION public.pgis_geometry_union_parallel_combinefn(internal, internal)
 RETURNS internal
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE
AS '$libdir/postgis-3', $function$pgis_geometry_union_parallel_combinefn$function$
;

CREATE OR REPLACE FUNCTION public.pgis_geometry_union_parallel_deserialfn(bytea, internal)
 RETURNS internal
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$pgis_geometry_union_parallel_deserialfn$function$
;

CREATE OR REPLACE FUNCTION public.pgis_geometry_union_parallel_finalfn(internal)
 RETURNS geometry
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT COST 5000
AS '$libdir/postgis-3', $function$pgis_geometry_union_parallel_finalfn$function$
;

CREATE OR REPLACE FUNCTION public.pgis_geometry_union_parallel_serialfn(internal)
 RETURNS bytea
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$pgis_geometry_union_parallel_serialfn$function$
;

CREATE OR REPLACE FUNCTION public.pgis_geometry_union_parallel_transfn(internal, geometry, double precision)
 RETURNS internal
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE COST 50
AS '$libdir/postgis-3', $function$pgis_geometry_union_parallel_transfn$function$
;

CREATE OR REPLACE FUNCTION public.pgis_geometry_union_parallel_transfn(internal, geometry)
 RETURNS internal
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE
AS '$libdir/postgis-3', $function$pgis_geometry_union_parallel_transfn$function$
;

CREATE OR REPLACE FUNCTION public.pgr_alphashape(geometry, alpha double precision DEFAULT 0)
 RETURNS geometry
 LANGUAGE plpgsql
 STRICT
AS $function$
DECLARE
geom      geometry;
delauny_query   TEXT;
BEGIN
    RAISE WARNING 'pgr_alphashape(geometry,double precision) deprecated function on v3.8.0';
    delauny_query = format($$
        WITH
        original AS (
            SELECT %1$L::geometry AS geom
        ),
        delauny AS (
            SELECT (ST_Dump(ST_DelaunayTriangles(geom, 0 , 0))).*
                FROM original
        ),
        delauny_info AS (
            SELECT delauny.path[1] AS id,
            (ST_DumpPoints(delauny.geom)).path[2] as seq,
            (ST_DumpPoints(delauny.geom)).geom
            FROM delauny
        )
        SELECT
            id,
            seq AS source,
            1 AS cost,
            ST_X(geom)::FLOAT AS x1,
            ST_Y(geom)::FLOAT AS y1,
            0::FLOAT AS x2,
            0::FLOAT AS y2
        FROM delauny_info WHERE seq != 4;
        $$, $1);
    WITH a AS (SELECT 'GEOMETRYCOLLECTION(' || string_agg(textgeom,',') || ')' as geome
        FROM _pgr_alphaShape(delauny_query, $2))
    SELECT ST_GeomFromText(geome) FROM a
    INTO geom;
    RETURN geom;
END
$function$
;

-- Function: pgr_alphashape
-- Comment: pgr_alphaShape deprecated function on v3.8.0
-- 
CREATE OR REPLACE FUNCTION public.pgr_analyzegraph(text, double precision, the_geom text DEFAULT 'the_geom'::text, id text DEFAULT 'id'::text, source text DEFAULT 'source'::text, target text DEFAULT 'target'::text, rows_where text DEFAULT 'true'::text)
 RETURNS character varying
 LANGUAGE plpgsql
 STRICT
AS $function$
DECLARE
    edge_table TEXT := $1;
    tolerance TEXT := $2;
    points record;
    seg record;
    naming record;
    sridinfo record;
    srid INTEGER;
    ecnt INTEGER;
    vertname TEXT;
    sname TEXT;
    tname TEXT;
    vname TEXT;
    idname TEXT;
    sourcename TEXT;
    targetname TEXT;
    sourcetype TEXT;
    targettype TEXT;
    geotype TEXT;
    gname TEXT;
    tabName TEXT;
    flag boolean ;
    query TEXT;
    selectionquery TEXT;
    i INTEGER;
    tot INTEGER;
    NumIsolated INTEGER;
    numdeadends INTEGER;
    numgaps INTEGER;
    NumCrossing INTEGER;
    numRings INTEGER;
    debuglevel TEXT;
BEGIN
  RAISE WARNING 'pgr_analyzegraph(text,double precision,text,text,text,text,text) deprecated function on v3.8.0';
  RAISE NOTICE 'PROCESSING:';
  RAISE NOTICE 'pgr_analyzeGraph(''%'',%,''%'',''%'',''%'',''%'',''%'')',edge_table,tolerance,the_geom,id,source,target,rows_where;
  RAISE NOTICE 'Performing checks, please wait ...';
  EXECUTE 'show client_min_messages' INTO debuglevel;
  BEGIN
    RAISE DEBUG 'Checking % exists',edge_table;
    EXECUTE 'select * FROM _pgr_getTableName('||quote_literal(edge_table)||',2)' INTO naming;
    sname=naming.sname;
    tname=naming.tname;
    tabname=sname||'.'||tname;
    vname=tname||'_vertices_pgr';
    vertname= sname||'.'||vname;
    rows_where = ' AND ('||rows_where||')';
    RAISE DEBUG '     --> OK';
  END;
  BEGIN
       RAISE DEBUG 'Checking Vertices table';
       EXECUTE 'select * FROM  _pgr_checkVertTab('||quote_literal(vertname) ||', ''{"id","cnt","chk"}''::TEXT[])' INTO naming;
       EXECUTE 'UPDATE '||_pgr_quote_ident(vertname)||' SET cnt=0 ,chk=0';
       RAISE DEBUG '     --> OK';
       EXCEPTION WHEN raise_exception THEN
          RAISE NOTICE 'ERROR: something went wrong checking the vertices table';
          RETURN 'FAIL';
  END;
  BEGIN
       RAISE DEBUG 'Checking column names in edge table';
       SELECT _pgr_getColumnName INTO idname     FROM _pgr_getColumnName(sname, tname,id,2);
       SELECT _pgr_getColumnName INTO sourcename FROM _pgr_getColumnName(sname, tname,source,2);
       SELECT _pgr_getColumnName INTO targetname FROM _pgr_getColumnName(sname, tname,target,2);
       SELECT _pgr_getColumnName INTO gname      FROM _pgr_getColumnName(sname, tname,the_geom,2);
       perform _pgr_onError( sourcename IN (targetname,idname,gname) OR  targetname IN (idname,gname) OR idname=gname, 2,
                       'pgr_analyzeGraph',  'Two columns share the same name', 'Parameter names for id,the_geom,source and target  must be different',
                       'Column names are OK');
        RAISE DEBUG '     --> OK';
       EXCEPTION WHEN raise_exception THEN
          RAISE NOTICE 'ERROR: something went wrong checking the column names';
          RETURN 'FAIL';
  END;
  BEGIN
       RAISE DEBUG 'Checking column types in edge table';
       SELECT _pgr_getColumnType INTO sourcetype FROM _pgr_getColumnType(sname,tname,sourcename,1);
       SELECT _pgr_getColumnType INTO targettype FROM _pgr_getColumnType(sname,tname,targetname,1);
       perform _pgr_onError(sourcetype NOT in('integer','smallint','bigint') , 2,
                       'pgr_analyzeGraph',  'Wrong type of Column '|| sourcename, ' Expected type of '|| sourcename || ' is integer, smallint or bigint but '||sourcetype||' was found',
                       'Type of Column '|| sourcename || ' is ' || sourcetype);
       perform _pgr_onError(targettype NOT in('integer','smallint','bigint') , 2,
                       'pgr_analyzeGraph',  'Wrong type of Column '|| targetname, ' Expected type of '|| targetname || ' is integer, smallint or bigint but '||targettype||' was found',
                       'Type of Column '|| targetname || ' is ' || targettype);
       RAISE DEBUG '     --> OK';
       EXCEPTION WHEN raise_exception THEN
          RAISE NOTICE 'ERROR: something went wrong checking the column types';
          RETURN 'FAIL';
   END;
   BEGIN
       RAISE DEBUG 'Checking SRID of geometry column';
         query= 'SELECT ST_SRID(' || quote_ident(gname) || ') AS srid '
            || ' FROM ' || _pgr_quote_ident(tabname)
            || ' WHERE ' || quote_ident(gname)
            || ' IS NOT NULL LIMIT 1';
         EXECUTE QUERY INTO sridinfo;
         perform _pgr_onError( sridinfo IS NULL OR sridinfo.srid IS NULL,2,
                 'Can not determine the srid of the geometry '|| gname ||' in table '||tabname, 'Check the geometry of column '||gname,
                 'SRID of '||gname||' is '||sridinfo.srid);
         IF sridinfo IS NULL OR sridinfo.srid IS NULL THEN
             RAISE NOTICE ' Can not determine the srid of the geometry "%" in table %', the_geom,tabname;
             RETURN 'FAIL';
         END IF;
         srid := sridinfo.srid;
         RAISE DEBUG '     --> OK';
         EXCEPTION WHEN OTHERS THEN
             RAISE NOTICE 'Got %', SQLERRM;--issue 210,211,213
             RAISE NOTICE 'ERROR: something went wrong when checking for SRID of % in table %', the_geom,tabname;
             RETURN 'FAIL';
    END;
    BEGIN
       RAISE DEBUG 'Checking  indices in edge table';
       perform _pgr_createIndex(tabname , idname , 'btree');
       perform _pgr_createIndex(tabname , sourcename , 'btree');
       perform _pgr_createIndex(tabname , targetname , 'btree');
       perform _pgr_createIndex(tabname , gname , 'gist');
       gname=quote_ident(gname);
       sourcename=quote_ident(sourcename);
       targetname=quote_ident(targetname);
       idname=quote_ident(idname);
       RAISE DEBUG '     --> OK';
       EXCEPTION WHEN raise_exception THEN
          RAISE NOTICE 'ERROR: something went wrong checking indices';
          RETURN 'FAIL';
    END;
    BEGIN
        query='select count(*) from '||_pgr_quote_ident(tabname)||' WHERE true  '||rows_where;
        EXECUTE query INTO ecnt;
        RAISE DEBUG '-->Rows WHERE condition: OK';
        RAISE DEBUG '     --> OK';
         EXCEPTION WHEN OTHERS THEN
            RAISE NOTICE 'Got %', SQLERRM;  --issue 210,211,213
            RAISE NOTICE 'ERROR: Condition is not correct. Please execute the following query to test your condition';
            RAISE NOTICE '%',query;
            RETURN 'FAIL';
    END;
    selectionquery ='with
           selectedRows as( (select '||sourcename||' AS id FROM '||_pgr_quote_ident(tabname)||' WHERE true '||rows_where||')
                           UNION
                           (select '||targetname||' AS id FROM '||_pgr_quote_ident(tabname)||' WHERE true '||rows_where||'))';
   BEGIN
       RAISE NOTICE 'Analyzing for dead ends. Please wait...';
       query= 'with countingsource AS (select a.'||sourcename||' AS id,count(*) AS cnts
               FROM (select * FROM '||_pgr_quote_ident(tabname)||' WHERE true '||rows_where||' ) a  GROUP BY a.'||sourcename||')
                     ,countingtarget AS (select a.'||targetname||' AS id,count(*) AS cntt
                    FROM (select * FROM '||_pgr_quote_ident(tabname)||' WHERE true '||rows_where||' ) a  GROUP BY a.'||targetname||')
                   ,totalcount AS (select id,case when cnts is NULL AND cntt is NULL then 0
                                                   when cnts is NULL then cntt
                                                   when cntt is NULL then cnts
                                                   else cnts+cntt end as totcnt
                                   FROM ('||_pgr_quote_ident(vertname)||' AS a left
                                   join countingsource AS t using(id) ) left join countingtarget using(id))
               UPDATE '||_pgr_quote_ident(vertname)||' AS a set cnt=totcnt FROM totalcount AS b WHERE a.id=b.id';
       RAISE DEBUG '%',query;
       EXECUTE query;
       query=selectionquery||'
              select count(*)  FROM '||_pgr_quote_ident(vertname)||' WHERE cnt=1 AND id IN (select id FROM selectedRows)';
       RAISE DEBUG '%',query;
       EXECUTE query  INTO numdeadends;
       RAISE DEBUG '     --> OK';
       EXCEPTION WHEN raise_exception THEN
          RAISE NOTICE 'Got %', SQLERRM;  --issue 210,211,213
          RAISE NOTICE 'ERROR: something went wrong when analizing for dead ends';
          RETURN 'FAIL';
   END;
    BEGIN
          RAISE NOTICE 'Analyzing for gaps. Please wait...';
          query = 'with
                   buffer AS (select id,st_buffer(the_geom,'||tolerance||') AS buff FROM '||_pgr_quote_ident(vertname)||' WHERE cnt=1)
                   ,veryclose AS (select b.id,st_crosses(a.'||gname||',b.buff) AS flag
                   FROM  (select * FROM '||_pgr_quote_ident(tabname)||' WHERE true '||rows_where||' ) AS a
                   join buffer AS b on (a.'||gname||'&&b.buff)
                   WHERE '||sourcename||'!=b.id AND '||targetname||'!=b.id )
                   UPDATE '||_pgr_quote_ident(vertname)||' set chk=1 WHERE id IN (select distinct id FROM veryclose WHERE flag=true)';
          RAISE DEBUG '%' ,query;
          EXECUTE query;
          GET DIAGNOSTICS  numgaps= ROW_COUNT;
          RAISE DEBUG '     --> OK';
          EXCEPTION WHEN raise_exception THEN
            RAISE NOTICE 'ERROR: something went wrong when Analyzing for gaps';
            RETURN 'FAIL';
    END;
    BEGIN
        RAISE NOTICE 'Analyzing for isolated edges. Please wait...';
        query=selectionquery|| ' select count(*) FROM (select * FROM '||_pgr_quote_ident(tabname)||' WHERE true '||rows_where||' )  AS a,
                                                 '||_pgr_quote_ident(vertname)||' AS b,
                                                 '||_pgr_quote_ident(vertname)||' AS c
                            WHERE b.id IN (select id FROM selectedRows) AND a.'||sourcename||' =b.id
                            AND b.cnt=1 AND a.'||targetname||' =c.id
                            AND c.cnt=1';
        RAISE DEBUG '%' ,query;
        EXECUTE query  INTO NumIsolated;
        RAISE DEBUG '     --> OK';
        EXCEPTION WHEN raise_exception THEN
            RAISE NOTICE 'ERROR: something went wrong when Analyzing for isolated edges';
            RETURN 'FAIL';
    END;
    BEGIN
        RAISE NOTICE 'Analyzing for ring geometries. Please wait...';
        EXECUTE 'select geometrytype('||gname||')  FROM '||_pgr_quote_ident(tabname) limit 1 INTO geotype;
        IF (geotype='MULTILINESTRING') THEN
            query ='select count(*)  FROM '||_pgr_quote_ident(tabname)||'
                                 WHERE true  '||rows_where||' AND st_isRing(st_linemerge('||gname||'))';
            RAISE DEBUG '%' ,query;
            EXECUTE query  INTO numRings;
        ELSE query ='select count(*)  FROM '||_pgr_quote_ident(tabname)||'
                                  WHERE true  '||rows_where||' AND st_isRing('||gname||')';
            RAISE DEBUG '%' ,query;
            EXECUTE query  INTO numRings;
        END IF;
        RAISE DEBUG '     --> OK';
        EXCEPTION WHEN raise_exception THEN
            RAISE NOTICE 'ERROR: something went wrong when Analyzing for ring geometries';
            RETURN 'FAIL';
    END;
    BEGIN
        RAISE NOTICE 'Analyzing for intersections. Please wait...';
        query = 'select count(*) FROM (select distinct case when a.'||idname||' < b.'||idname||' then a.'||idname||'
                                                        else b.'||idname||' end,
                                                   case when a.'||idname||' < b.'||idname||' then b.'||idname||'
                                                        else a.'||idname||' end
                                    FROM (select * FROM '||_pgr_quote_ident(tabname)||' WHERE true '||rows_where||') AS a
                                    JOIN (select * FROM '||_pgr_quote_ident(tabname)||' WHERE true '||rows_where||') AS b
                                    ON (a.'|| gname||' && b.'||gname||')
                                    WHERE a.'||idname||' != b.'||idname|| '
                                        AND (a.'||sourcename||' IN (b.'||sourcename||',b.'||targetname||')
                                              OR a.'||targetname||' IN (b.'||sourcename||',b.'||targetname||')) = false
                                        AND st_intersects(a.'||gname||', b.'||gname||')=true) AS d ';
        RAISE DEBUG '%' ,query;
        EXECUTE query  INTO numCrossing;
        RAISE DEBUG '     --> OK';
        EXCEPTION WHEN raise_exception THEN
            RAISE NOTICE 'ERROR: something went wrong when Analyzing for intersections';
            RETURN 'FAIL';
    END;
    RAISE NOTICE '            ANALYSIS RESULTS FOR SELECTED EDGES:';
    RAISE NOTICE '                  Isolated segments: %', NumIsolated;
    RAISE NOTICE '                          Dead ends: %', numdeadends;
    RAISE NOTICE 'Potential gaps found near dead ends: %', numgaps;
    RAISE NOTICE '             Intersections detected: %',numCrossing;
    RAISE NOTICE '                    Ring geometries: %',numRings;
    RETURN 'OK';
END;
$function$
;

-- Function: pgr_analyzegraph
-- Comment: pgr_analyzeGraph deprecated function on v3.8.0
-- 
CREATE OR REPLACE FUNCTION public.pgr_analyzeoneway(text, text[], text[], text[], text[], two_way_if_null boolean DEFAULT true, oneway text DEFAULT 'oneway'::text, source text DEFAULT 'source'::text, target text DEFAULT 'target'::text)
 RETURNS text
 LANGUAGE plpgsql
 STRICT
AS $function$
DECLARE
    edge_table TEXT := $1;
    s_in_rules TEXT[] := $2;
    s_out_rules TEXT[] := $3;
    t_in_rules TEXT[] := $4;
    t_out_rules TEXT[] := $5;
    rule TEXT;
    ecnt INTEGER;
    instr TEXT;
    naming record;
    sname TEXT;
    tname TEXT;
    tabname TEXT;
    vname TEXT;
    owname TEXT;
    sourcename TEXT;
    targetname TEXT;
    sourcetype TEXT;
    targettype TEXT;
    vertname TEXT;
    debuglevel TEXT;
BEGIN
  RAISE WARNING 'pgr_analyzeoneway(text,text[],text[],text[],text[],boolean,text,text,text) deprecated function on v3.8.0';
  RAISE NOTICE 'PROCESSING:';
  RAISE NOTICE 'pgr_analyzeOneway(''%'',''%'',''%'',''%'',''%'',''%'',''%'',''%'',%)',
		edge_table, s_in_rules , s_out_rules, t_in_rules, t_out_rules, oneway, source ,target,two_way_if_null ;
  EXECUTE 'show client_min_messages' INTO debuglevel;
  BEGIN
    RAISE DEBUG 'Checking % exists',edge_table;
    EXECUTE 'SELECT sname, tname FROM _pgr_getTableName('||quote_literal(edge_table)||',2)' INTO naming;
    sname=naming.sname;
    tname=naming.tname;
    tabname=sname||'.'||tname;
    vname=tname||'_vertices_pgr';
    vertname= sname||'.'||vname;
    RAISE DEBUG '     --> OK';
    EXCEPTION WHEN raise_exception THEN
      RAISE NOTICE 'ERROR: something went wrong checking the table name';
      RETURN 'FAIL';
  END;
  BEGIN
       RAISE DEBUG 'Checking Vertices table';
       EXECUTE 'SELECT sname, vname FROM  _pgr_checkVertTab('||quote_literal(vertname) ||', ''{"id","ein","eout"}''::TEXT[])' INTO naming;
       EXECUTE 'UPDATE '||_pgr_quote_ident(vertname)||' SET eout=0 ,ein=0';
       RAISE DEBUG '     --> OK';
       EXCEPTION WHEN raise_exception THEN
          RAISE NOTICE 'ERROR: something went wrong checking the vertices table';
          RETURN 'FAIL';
  END;
  BEGIN
       RAISE DEBUG 'Checking column names in edge table';
       SELECT _pgr_getColumnName INTO sourcename FROM _pgr_getColumnName(sname, tname,source,2);
       SELECT _pgr_getColumnName INTO targetname FROM _pgr_getColumnName(sname, tname,target,2);
       SELECT _pgr_getColumnName INTO owname FROM _pgr_getColumnName(sname, tname,oneway,2);
       perform _pgr_onError( sourcename IN (targetname,owname) or  targetname=owname, 2,
                       '_pgr_createToplogy',  'Two columns share the same name', 'Parameter names for oneway,source and target  must be different',
                       'Column names are OK');
       RAISE DEBUG '     --> OK';
       EXCEPTION WHEN raise_exception THEN
          RAISE NOTICE 'ERROR: something went wrong checking the column names';
          RETURN 'FAIL';
  END;
  BEGIN
       RAISE DEBUG 'Checking column types in edge table';
       SELECT _pgr_getColumnType INTO sourcetype FROM _pgr_getColumnType(sname,tname,sourcename,1);
       SELECT _pgr_getColumnType INTO targettype FROM _pgr_getColumnType(sname,tname,targetname,1);
       perform _pgr_onError(sourcetype NOT IN('integer','smallint','bigint') , 2,
                       '_pgr_createTopology',  'Wrong type of Column '|| sourcename, ' Expected type of '|| sourcename || ' is INTEGER,smallint OR BIGINT but '||sourcetype||' was found',
                       'Type of Column '|| sourcename || ' is ' || sourcetype);
       perform _pgr_onError(targettype NOT IN('integer','smallint','bigint') , 2,
                       '_pgr_createTopology',  'Wrong type of Column '|| targetname, ' Expected type of '|| targetname || ' is INTEGER,smallint OR BIGINTi but '||targettype||' was found',
                       'Type of Column '|| targetname || ' is ' || targettype);
       RAISE DEBUG '     --> OK';
       EXCEPTION WHEN raise_exception THEN
          RAISE NOTICE 'ERROR: something went wrong checking the column types';
          RETURN 'FAIL';
   END;
    RAISE NOTICE 'Analyzing graph for one way street errors.';
    rule := CASE WHEN two_way_if_null
            THEN owname || ' IS NULL OR '
            ELSE '' END;
    instr := '''' || array_to_string(s_in_rules, ''',''') || '''';
       EXECUTE 'UPDATE '||_pgr_quote_ident(vertname)||' a set ein=coalesce(ein,0)+b.cnt
      FROM (
         SELECT '|| sourcename ||', count(*) AS cnt
           FROM '|| tabname ||'
          WHERE '|| rule || owname ||' IN ('|| instr ||')
          GROUP BY '|| sourcename ||' ) b
     WHERE a.id=b.'|| sourcename;
    RAISE NOTICE 'Analysis 25%% complete ...';
    instr := '''' || array_to_string(t_in_rules, ''',''') || '''';
    EXECUTE 'UPDATE '||_pgr_quote_ident(vertname)||' a set ein=coalesce(ein,0)+b.cnt
        FROM (
         SELECT '|| targetname ||', count(*) AS cnt
           FROM '|| tabname ||'
          WHERE '|| rule || owname ||' IN ('|| instr ||')
          GROUP BY '|| targetname ||' ) b
        WHERE a.id=b.'|| targetname;
    RAISE NOTICE 'Analysis 50%% complete ...';
    instr := '''' || array_to_string(s_out_rules, ''',''') || '''';
    EXECUTE 'UPDATE '||_pgr_quote_ident(vertname)||' a set eout=coalesce(eout,0)+b.cnt
        FROM (
         SELECT '|| sourcename ||', count(*) AS cnt
           FROM '|| tabname ||'
          WHERE '|| rule || owname ||' IN ('|| instr ||')
          GROUP BY '|| sourcename ||' ) b
        WHERE a.id=b.'|| sourcename;
    RAISE NOTICE 'Analysis 75%% complete ...';
    instr := '''' || array_to_string(t_out_rules, ''',''') || '''';
    EXECUTE 'UPDATE '||_pgr_quote_ident(vertname)||' a set eout=coalesce(eout,0)+b.cnt
        FROM (
         SELECT '|| targetname ||', count(*) AS cnt
           FROM '|| tabname ||'
          WHERE '|| rule || owname ||' IN ('|| instr ||')
          GROUP BY '|| targetname ||' ) b
        WHERE a.id=b.'|| targetname;
    RAISE NOTICE 'Analysis 100%% complete ...';
    EXECUTE 'SELECT count(*)  FROM '||_pgr_quote_ident(vertname)||' WHERE ein=0 OR eout=0' INTO ecnt;
    RAISE NOTICE 'Found % potential problems in directionality' ,ecnt;
    RETURN 'OK';
END;
$function$
;

-- Function: pgr_analyzeoneway
-- Comment: pgr_analyzeOneWay deprecated function on v3.8.0
-- 
CREATE OR REPLACE FUNCTION public.pgr_articulationpoints(text, OUT node bigint)
 RETURNS SETOF bigint
 LANGUAGE sql
 STRICT
AS $function$
    SELECT node
    FROM _pgr_articulationPoints(_pgr_get_statement($1));
$function$
;

-- Function: pgr_articulationpoints
-- Comment: pgr_articulationPoints
- Undirected graph
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_articulationPoints.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_astar(text, bigint, bigint, directed boolean DEFAULT true, heuristic integer DEFAULT 5, factor double precision DEFAULT 1.0, epsilon double precision DEFAULT 1.0, OUT seq integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, path_seq, start_vid, end_vid, node, edge, cost, agg_cost
    FROM _pgr_aStar(_pgr_get_statement($1), ARRAY[$2]::BIGINT[],  ARRAY[$3]::BIGINT[], $4, $5, $6::FLOAT, $7::FLOAT);
$function$
;

-- Function: pgr_astar
-- Comment: pgr_aStar(One to One)
- Parameters:
  - edges SQL with columns: id, source, target, cost [,reverse_cost], x1, y1, x2, y2
  - From vertex identifier
  - To vertex identifier
- Optional Parameters:
  - directed := true
  - heuristic := 5
  - factor := 1
  - epsilon := 1
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_aStar.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_astar(text, text, directed boolean DEFAULT true, heuristic integer DEFAULT 5, factor double precision DEFAULT 1.0, epsilon double precision DEFAULT 1.0, OUT seq integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, path_seq, start_vid, end_vid, node, edge, cost, agg_cost
    FROM _pgr_aStar(_pgr_get_statement($1), _pgr_get_statement($2), $3, $4, $5::FLOAT, $6::FLOAT);
$function$
;

-- Function: pgr_astar
-- Comment: pgr_aStar(Combinations)
 - Parameters:
   - Edges SQL with columns: id, source, target, cost [,reverse_cost], x1, y1, x2, y2
   - Combinations SQL with columns: source, target
 - Optional Parameters:
   - directed := true
   - heuristic := 5
   - factor := 1
   - epsilon := 1
 - Documentation:
   - https://docs.pgrouting.org/latest/en/pgr_aStar.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_astar(text, anyarray, anyarray, directed boolean DEFAULT true, heuristic integer DEFAULT 5, factor double precision DEFAULT 1.0, epsilon double precision DEFAULT 1.0, OUT seq integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, path_seq, start_vid, end_vid, node, edge, cost, agg_cost
    FROM _pgr_aStar(_pgr_get_statement($1), $2::BIGINT[],  $3::BIGINT[], $4, $5, $6::FLOAT, $7::FLOAT);
$function$
;

-- Function: pgr_astar
-- Comment: pgr_aStar(Many to Many)
 - Parameters:
   - edges SQL with columns: id, source, target, cost [,reverse_cost], x1, y1, x2, y2
   - From ARRAY[vertices identifiers]
   - To ARRAY[vertices identifiers]
 - Optional Parameters:
   - directed := true
   - heuristic := 5
   - factor := 1
   - epsilon := 1
 - Documentation:
   - https://docs.pgrouting.org/latest/en/pgr_aStar.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_astar(text, bigint, anyarray, directed boolean DEFAULT true, heuristic integer DEFAULT 5, factor double precision DEFAULT 1.0, epsilon double precision DEFAULT 1.0, OUT seq integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, path_seq, start_vid, end_vid, node, edge, cost, agg_cost
    FROM _pgr_aStar(_pgr_get_statement($1), ARRAY[$2]::BIGINT[],  $3::BIGINT[], $4, $5, $6::FLOAT, $7::FLOAT);
$function$
;

-- Function: pgr_astar
-- Comment: pgr_aStar(One to Many)
- Parameters:
  - edges SQL with columns: id, source, target, cost [,reverse_cost], x1, y1, x2, y2
  - From vertex identifier
  - To ARRAY[vertices identifiers]
- Optional Parameters:
  - directed := true
  - heuristic := 5
  - factor := 1
  - epsilon := 1
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_aStar.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_astar(text, anyarray, bigint, directed boolean DEFAULT true, heuristic integer DEFAULT 5, factor double precision DEFAULT 1.0, epsilon double precision DEFAULT 1.0, OUT seq integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, path_seq, start_vid, end_vid, node, edge, cost, agg_cost
    FROM _pgr_aStar(_pgr_get_statement($1), $2::BIGINT[],  ARRAY[$3]::BIGINT[], $4, $5, $6::FLOAT, $7::FLOAT, normal:=false);
$function$
;

-- Function: pgr_astar
-- Comment: pgr_aStar(Many to One)
- Parameters:
  - edges SQL with columns: id, source, target, cost [,reverse_cost], x1, y1, x2, y2
  - From ARRAY[vertices identifiers]
  - To vertex identifier
- Optional Parameters:
  - directed := true
  - heuristic := 5
  - factor := 1
  - epsilon := 1
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_aStar.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_astarcost(text, anyarray, anyarray, directed boolean DEFAULT true, heuristic integer DEFAULT 5, factor double precision DEFAULT 1.0, epsilon double precision DEFAULT 1.0, OUT start_vid bigint, OUT end_vid bigint, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT a.start_vid, a.end_vid, a.agg_cost
    FROM _pgr_aStar(_pgr_get_statement($1), $2::BIGINT[],  $3::BIGINT[], $4, $5, $6::FLOAT, $7::FLOAT, true) AS a
    ORDER BY  a.start_vid, a.end_vid;
$function$
;

-- Function: pgr_astarcost
-- Comment: pgr_aStarCost(Many to Many)
 - Parameters:
   - edges SQL with columns: id, source, target, cost [,reverse_cost], x1, y1, x2, y2
   - From ARRAY[vertices identifiers]
   - To ARRAY[vertices identifiers]
 - Optional Parameters:
   - directed := true
   - heuristic := 5
   - factor := 1
   - epsilon := 1
 - Documentation:
   - https://docs.pgrouting.org/latest/en/pgr_aStarCost.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_astarcost(text, text, directed boolean DEFAULT true, heuristic integer DEFAULT 5, factor double precision DEFAULT 1.0, epsilon double precision DEFAULT 1.0, OUT start_vid bigint, OUT end_vid bigint, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT a.start_vid, a.end_vid, a.agg_cost
    FROM _pgr_aStar(_pgr_get_statement($1), _pgr_get_statement($2), $3, $4, $5::FLOAT, $6::FLOAT, true) AS a
    ORDER BY  a.start_vid, a.end_vid;
$function$
;

-- Function: pgr_astarcost
-- Comment: pgr_aStarCost(Combinations)
 - Parameters:
   - edges SQL with columns: id, source, target, cost [,reverse_cost], x1, y1, x2, y2
   - Combinations SQL with columns: source, target
 - Optional Parameters:
   - directed := true
   - heuristic := 5
   - factor := 1
   - epsilon := 1
 - Documentation:
   - https://docs.pgrouting.org/latest/en/pgr_aStarCost.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_astarcost(text, bigint, bigint, directed boolean DEFAULT true, heuristic integer DEFAULT 5, factor double precision DEFAULT 1.0, epsilon double precision DEFAULT 1.0, OUT start_vid bigint, OUT end_vid bigint, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT a.start_vid, a.end_vid, a.agg_cost
    FROM _pgr_aStar(_pgr_get_statement($1), ARRAY[$2]::BIGINT[],  ARRAY[$3]::BIGINT[], $4, $5, $6::FLOAT, $7::FLOAT, true) AS a
    ORDER BY  a.start_vid, a.end_vid;
$function$
;

-- Function: pgr_astarcost
-- Comment: pgr_aStarCost(One to One)
- Parameters:
  - edges SQL with columns: id, source, target, cost [,reverse_cost], x1, y1, x2, y2
  - From vertex identifier
  - To vertex identifier
- Optional Parameters:
  - directed := true
  - heuristic := 5
  - factor := 1
  - epsilon := 1
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_aStarCost.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_astarcost(text, bigint, anyarray, directed boolean DEFAULT true, heuristic integer DEFAULT 5, factor double precision DEFAULT 1.0, epsilon double precision DEFAULT 1.0, OUT start_vid bigint, OUT end_vid bigint, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT a.start_vid, a.end_vid, a.agg_cost
    FROM _pgr_aStar(_pgr_get_statement($1), ARRAY[$2]::BIGINT[],  $3::BIGINT[], $4, $5, $6::FLOAT, $7::FLOAT, true) AS a
    ORDER BY  a.start_vid, a.end_vid;
$function$
;

-- Function: pgr_astarcost
-- Comment: pgr_aStarCost(One to Many)
- Parameters:
  - edges SQL with columns: id, source, target, cost [,reverse_cost], x1, y1, x2, y2
  - From vertex identifier
  - To ARRAY[vertices identifiers]
- Optional Parameters:
  - directed := true
  - heuristic := 5
  - factor := 1
  - epsilon := 1
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_aStarCost.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_astarcost(text, anyarray, bigint, directed boolean DEFAULT true, heuristic integer DEFAULT 5, factor double precision DEFAULT 1.0, epsilon double precision DEFAULT 1.0, OUT start_vid bigint, OUT end_vid bigint, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT a.start_vid, a.end_vid, a.agg_cost
    FROM _pgr_aStar(_pgr_get_statement($1), $2::BIGINT[],  ARRAY[$3]::BIGINT[], $4, $5, $6::FLOAT, $7::FLOAT, true, normal:=false) AS a
    ORDER BY  a.start_vid, a.end_vid;
$function$
;

-- Function: pgr_astarcost
-- Comment: pgr_aStarCost(Many to One)
- Parameters:
  - edges SQL with columns: id, source, target, cost [,reverse_cost], x1, y1, x2, y2
  - From ARRAY[vertices identifiers]
  - To vertex identifier
- Optional Parameters:
  - directed := true
  - heuristic := 5
  - factor := 1
  - epsilon := 1
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_aStarCost.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_astarcostmatrix(text, anyarray, directed boolean DEFAULT true, heuristic integer DEFAULT 5, factor double precision DEFAULT 1.0, epsilon double precision DEFAULT 1.0, OUT start_vid bigint, OUT end_vid bigint, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
AS $function$
    SELECT a.start_vid, a.end_vid, a.agg_cost
    FROM _pgr_astar(_pgr_get_statement($1), $2, $2, $3, $4, $5::FLOAT, $6::FLOAT, true) a;
$function$
;

-- Function: pgr_astarcostmatrix
-- Comment: pgr_aStarCostMatrix
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost], x1, y1, x2, y2
    - ARRAY [vertices identifiers]
- Optional Parameters:
    - directed := true
    - heuristic := 5
    - factor := 1
    - epsilon := 1
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_aStarCostMatrix.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_bdastar(text, anyarray, bigint, directed boolean DEFAULT true, heuristic integer DEFAULT 5, factor numeric DEFAULT 1.0, epsilon numeric DEFAULT 1.0, OUT seq integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, path_seq, start_vid, end_vid, node, edge, cost, agg_cost
    FROM _pgr_bdAstar(_pgr_get_statement($1), $2::BIGINT[], ARRAY[$3]::BIGINT[], $4, $5, $6::FLOAT, $7::FLOAT, false);
$function$
;

-- Function: pgr_bdastar
-- Comment: pgr_bdAstar(Many to One)
- Parameters:
  - edges SQL with columns: id, source, target, cost [,reverse_cost], x1, y1, x2, y2
  - From ARRAY[vertices identifiers]
  - To vertex identifier
- Optional Parameters:
  - directed := true
  - heuristic := 5
  - factor := 1
  - epsilon := 1
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_bdAstar.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_bdastar(text, bigint, bigint, directed boolean DEFAULT true, heuristic integer DEFAULT 5, factor numeric DEFAULT 1.0, epsilon numeric DEFAULT 1.0, OUT seq integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, path_seq, start_vid, end_vid, node, edge, cost, agg_cost
    FROM _pgr_bdAstar(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], ARRAY[$3]::BIGINT[], $4, $5, $6::FLOAT, $7::FLOAT, false);
$function$
;

-- Function: pgr_bdastar
-- Comment: pgr_bdAstar(One to One)
- Parameters:
  - edges SQL with columns: id, source, target, cost [,reverse_cost], x1, y1, x2, y2
  - From vertex identifier
  - To vertex identifier
- Optional Parameters:
  - directed := true
  - heuristic := 5
  - factor := 1
  - epsilon := 1
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_bdAstar.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_bdastar(text, anyarray, anyarray, directed boolean DEFAULT true, heuristic integer DEFAULT 5, factor numeric DEFAULT 1.0, epsilon numeric DEFAULT 1.0, OUT seq integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, path_seq, start_vid, end_vid, node, edge, cost, agg_cost
    FROM _pgr_bdAstar(_pgr_get_statement($1), $2::BIGINT[], $3::BIGINT[], $4, $5, $6::FLOAT, $7::FLOAT, false);
$function$
;

-- Function: pgr_bdastar
-- Comment: pgr_bdAstar(Many to Many)
- Parameters:
  - edges SQL with columns: id, source, target, cost [,reverse_cost], x1, y1, x2, y2
  - From ARRAY[vertices identifiers]
  - To ARRAY[vertices identifiers]
- Optional Parameters:
  - directed := true
  - heuristic := 5
  - factor := 1
  - epsilon := 1
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_bdAstar.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_bdastar(text, text, directed boolean DEFAULT true, heuristic integer DEFAULT 5, factor numeric DEFAULT 1.0, epsilon numeric DEFAULT 1.0, OUT seq integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, path_seq, start_vid, end_vid, node, edge, cost, agg_cost
    FROM _pgr_bdAstar(_pgr_get_statement($1), _pgr_get_statement($2), $3, $4, $5::FLOAT, $6::FLOAT, false);
$function$
;

-- Function: pgr_bdastar
-- Comment: pgr_bdAstar(Combinations)
- Parameters:
  - Edges SQL with columns: id, source, target, cost [, reverse_cost], x1, y1, x2, y2
  - Combinations SQL with columns: source, target
- Optional Parameters:
  - directed := true
  - heuristic := 5
  - factor := 1
  - epsilon := 1
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_bdAstar.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_bdastar(text, bigint, anyarray, directed boolean DEFAULT true, heuristic integer DEFAULT 5, factor numeric DEFAULT 1.0, epsilon numeric DEFAULT 1.0, OUT seq integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, path_seq, start_vid, end_vid, node, edge, cost, agg_cost
    FROM _pgr_bdAstar(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], $3::BIGINT[], $4, $5, $6::FLOAT, $7::FLOAT, false);
$function$
;

-- Function: pgr_bdastar
-- Comment: pgr_bdAstar(One to Many)
- Parameters:
  - edges SQL with columns: id, source, target, cost [,reverse_cost], x1, y1, x2, y2
  - From vertex identifier
  - To ARRAY[vertices identifiers]
- Optional Parameters:
  - directed := true
  - heuristic := 5
  - factor := 1
  - epsilon := 1
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_bdAstar.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_bdastarcost(text, anyarray, bigint, directed boolean DEFAULT true, heuristic integer DEFAULT 5, factor numeric DEFAULT 1.0, epsilon numeric DEFAULT 1.0, OUT start_vid bigint, OUT end_vid bigint, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT a.start_vid, a.end_vid, a.agg_cost
    FROM _pgr_bdAstar(_pgr_get_statement($1), $2::BIGINT[], ARRAY[$3]::BIGINT[], $4, $5, $6::FLOAT, $7::FLOAT, true) AS a;
$function$
;

-- Function: pgr_bdastarcost
-- Comment: pgr_bdAstarCost(Many to One)
- Parameters:
  - edges SQL with columns: id, source, target, cost [,reverse_cost], x1, y1, x2, y2
  - From ARRAY[vertices identifiers]
  - To vertex identifier
- Optional Parameters:
  - directed := true
  - heuristic := 5
  - factor := 1
  - epsilon := 1
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_bdAstarCost.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_bdastarcost(text, text, directed boolean DEFAULT true, heuristic integer DEFAULT 5, factor numeric DEFAULT 1.0, epsilon numeric DEFAULT 1.0, OUT start_vid bigint, OUT end_vid bigint, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT a.start_vid, a.end_vid, a.agg_cost
    FROM _pgr_bdAstar(_pgr_get_statement($1), _pgr_get_statement($2), $3, $4, $5::FLOAT, $6::FLOAT, true) AS a;
$function$
;

-- Function: pgr_bdastarcost
-- Comment: pgr_bdAstarCost(Combinations)
- Parameters:
  - Edges SQL with columns: id, source, target, cost [, reverse_cost], x1, y1, x2, y2
  - Combinations SQL with columns: source, target
- Optional Parameters:
  - directed := true
  - heuristic := 5
  - factor := 1
  - epsilon := 1
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_bdAstarCost.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_bdastarcost(text, anyarray, anyarray, directed boolean DEFAULT true, heuristic integer DEFAULT 5, factor numeric DEFAULT 1.0, epsilon numeric DEFAULT 1.0, OUT start_vid bigint, OUT end_vid bigint, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT a.start_vid, a.end_vid, a.agg_cost
    FROM _pgr_bdAstar(_pgr_get_statement($1), $2::BIGINT[], $3::BIGINT[], $4, $5, $6::FLOAT, $7::FLOAT, true) AS a;
$function$
;

-- Function: pgr_bdastarcost
-- Comment: pgr_bdAstarCost(Many to Many)
- Parameters:
  - edges SQL with columns: id, source, target, cost [,reverse_cost], x1, y1, x2, y2
  - From ARRAY[vertices identifiers]
  - To ARRAY[vertices identifiers]
- Optional Parameters:
  - directed := true
  - heuristic := 5
  - factor := 1
  - epsilon := 1
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_bdAstarCost.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_bdastarcost(text, bigint, bigint, directed boolean DEFAULT true, heuristic integer DEFAULT 5, factor numeric DEFAULT 1.0, epsilon numeric DEFAULT 1.0, OUT start_vid bigint, OUT end_vid bigint, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT a.start_vid, a.end_vid, a.agg_cost
    FROM _pgr_bdAstar(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], ARRAY[$3]::BIGINT[], $4, $5, $6::FLOAT, $7::FLOAT, true) AS a;
$function$
;

-- Function: pgr_bdastarcost
-- Comment: pgr_bdAstarCost(One to One)
- Parameters:
  - edges SQL with columns: id, source, target, cost [,reverse_cost], x1, y1, x2, y2
  - From vertex identifier
  - To vertex identifier
- Optional Parameters:
  - directed := true
  - heuristic := 5
  - factor := 1
  - epsilon := 1
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_bdAstarCost.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_bdastarcost(text, bigint, anyarray, directed boolean DEFAULT true, heuristic integer DEFAULT 5, factor numeric DEFAULT 1.0, epsilon numeric DEFAULT 1.0, OUT start_vid bigint, OUT end_vid bigint, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT a.start_vid, a.end_vid, a.agg_cost
    FROM _pgr_bdAstar(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], $3::BIGINT[], $4, $5, $6::FLOAT, $7::FLOAT, true) AS a;
$function$
;

-- Function: pgr_bdastarcost
-- Comment: pgr_bdAstarCost(One to Many)
- Parameters:
  - edges SQL with columns: id, source, target, cost [,reverse_cost], x1, y1, x2, y2
  - From vertex identifier
  - To ARRAY[vertices identifiers]
- Optional Parameters:
  - directed := true
  - heuristic := 5
  - factor := 1
  - epsilon := 1
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_bdAstarCost.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_bdastarcostmatrix(text, anyarray, directed boolean DEFAULT true, heuristic integer DEFAULT 5, factor numeric DEFAULT 1.0, epsilon numeric DEFAULT 1.0, OUT start_vid bigint, OUT end_vid bigint, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
AS $function$
    SELECT a.start_vid, a.end_vid, a.agg_cost
    FROM _pgr_bdAstar(_pgr_get_statement($1), $2::BIGINT[], $2::BIGINT[], $3, $4, $5::FLOAT, $6::FLOAT, true) a;
$function$
;

-- Function: pgr_bdastarcostmatrix
-- Comment: pgr_bdAstarCostMatrix
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost], x1, y1, x2, y2
    - ARRAY [vertices identifiers]
- Optional Parameters:
    - directed := true
    - heuristic := 5
    - factor := 1
    - epsilon := 1
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_bdAstarCostMatrix.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_bddijkstra(text, anyarray, anyarray, directed boolean DEFAULT true, OUT seq integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, path_seq, start_vid, end_vid, node, edge, cost, agg_cost
    FROM _pgr_bdDijkstra(_pgr_get_statement($1), $2::BIGINT[], $3::BIGINT[], directed, false);
$function$
;

-- Function: pgr_bddijkstra
-- Comment: pgr_bdDijkstra(Many to Many)
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - From ARRAY[vertices identifiers]
  - To ARRAY[vertices identifiers]
- Optional Parameters
  - directed := true
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_bdDijkstra.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_bddijkstra(text, bigint, anyarray, directed boolean DEFAULT true, OUT seq integer, OUT path_seq integer, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, path_seq, end_vid, node, edge, cost, agg_cost
    FROM _pgr_bdDijkstra(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], $3::BIGINT[], $4, false);
$function$
;

-- Function: pgr_bddijkstra
-- Comment: pgr_bdDijkstra(One to Many)
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - From vertex identifier
  - To ARRAY[vertices identifiers]
- Optional Parameters
  - directed := true
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_bdDijkstra.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_bddijkstra(text, bigint, bigint, directed boolean DEFAULT true, OUT seq integer, OUT path_seq integer, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, path_seq, node, edge, cost, agg_cost
    FROM _pgr_bdDijkstra(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], ARRAY[$3]::BIGINT[], $4, false);
$function$
;

-- Function: pgr_bddijkstra
-- Comment: pgr_bdDijkstra(One to One)
- Parameters:
  - edges SQL with columns: id, source, target, cost [,reverse_cost]
  - From vertex identifier
  - To vertex identifier
- Optional Parameters:
  - directed := true
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_bdDijkstra.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_bddijkstra(text, anyarray, bigint, directed boolean DEFAULT true, OUT seq integer, OUT path_seq integer, OUT start_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, path_seq, start_vid, node, edge, cost, agg_cost
    FROM _pgr_bdDijkstra(_pgr_get_statement($1), $2::BIGINT[], ARRAY[$3]::BIGINT[], $4, false);
$function$
;

-- Function: pgr_bddijkstra
-- Comment: pgr_bdDijkstra(Many to One)
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - From ARRAY[vertices identifiers]
  - To vertex identifier
- Optional Parameters
  - directed := true
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_bdDijkstra.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_bddijkstra(text, text, directed boolean DEFAULT true, OUT seq integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, path_seq, start_vid, end_vid, node, edge, cost, agg_cost
    FROM _pgr_bdDijkstra(_pgr_get_statement($1), _pgr_get_statement($2), directed, false);
$function$
;

-- Function: pgr_bddijkstra
-- Comment: pgr_bdDijkstra(Combinations)
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - Combinations SQL with columns: source, target
- Optional Parameters
  - directed := true
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_bdDijkstra.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_bddijkstracost(text, bigint, anyarray, directed boolean DEFAULT true, OUT start_vid bigint, OUT end_vid bigint, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT a.start_vid, a.end_vid, a.agg_cost
    FROM _pgr_bdDijkstra(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], $3::BIGINT[], $4, true) as a;
$function$
;

-- Function: pgr_bddijkstracost
-- Comment: pgr_bdDijkstraCost(One to Many)
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - From vertex identifier
  - To ARRAY[vertices identifiers]
- Optional Parameters
  - directed := true
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_bdDijkstraCost.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_bddijkstracost(text, bigint, bigint, directed boolean DEFAULT true, OUT start_vid bigint, OUT end_vid bigint, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT a.start_vid, a.end_vid, a.agg_cost
    FROM _pgr_bdDijkstra(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], ARRAY[$3]::BIGINT[], $4, true) AS a;
$function$
;

-- Function: pgr_bddijkstracost
-- Comment: pgr_bdDijkstraCost(One to One)
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - From vertex identifier
  - To vertex identifier
- Optional Parameters
  - directed := true
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_bdDijkstraCost.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_bddijkstracost(text, anyarray, anyarray, directed boolean DEFAULT true, OUT start_vid bigint, OUT end_vid bigint, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT a.start_vid, a.end_vid, a.agg_cost
    FROM _pgr_bdDijkstra(_pgr_get_statement($1), $2::BIGINT[], $3::BIGINT[], directed, true) as a;
$function$
;

-- Function: pgr_bddijkstracost
-- Comment: pgr_bdDijkstraCost(Many to Many)
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - From ARRAY[vertices identifiers]
  - To ARRAY[vertices identifiers]
- Optional Parameters
  - directed := true
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_bdDijkstraCost.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_bddijkstracost(text, text, directed boolean DEFAULT true, OUT start_vid bigint, OUT end_vid bigint, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT a.start_vid, a.end_vid, a.agg_cost
    FROM _pgr_bdDijkstra(_pgr_get_statement($1), _pgr_get_statement($2), directed, true) as a;
$function$
;

-- Function: pgr_bddijkstracost
-- Comment: pgr_bdDijkstraCost(Combinations)
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - Combinations SQL with columns: source, target
- Optional Parameters
  - directed := true
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_bdDijkstraCost.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_bddijkstracost(text, anyarray, bigint, directed boolean DEFAULT true, OUT start_vid bigint, OUT end_vid bigint, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT a.start_vid, a.end_vid, a.agg_cost
    FROM _pgr_bdDijkstra(_pgr_get_statement($1), $2::BIGINT[], ARRAY[$3]::BIGINT[], $4, true) as a;
$function$
;

-- Function: pgr_bddijkstracost
-- Comment: pgr_bdDijkstraCost(Many to One)
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - From ARRAY[vertices identifiers]
  - To vertex identifier
- Optional Parameters
  - directed := true
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_bdDijkstraCost.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_bddijkstracostmatrix(text, anyarray, directed boolean DEFAULT true, OUT start_vid bigint, OUT end_vid bigint, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
AS $function$
    SELECT a.start_vid, a.end_vid, a.agg_cost
    FROM _pgr_bdDijkstra(_pgr_get_statement($1), $2::BIGINT[], $2::BIGINT[], $3, true) a;
$function$
;

-- Function: pgr_bddijkstracostmatrix
-- Comment: pgr_bdDijkstraCostMatrix
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
    - ARRAY [vertices identifiers]
- Optional Parameters
    - directed := true
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_bdDijkstraCostMatrix.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_bellmanford(text, bigint, bigint, directed boolean DEFAULT true, OUT seq integer, OUT path_seq integer, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT a.seq, a.path_seq, a.node, a.edge, a.cost, a.agg_cost
    FROM _pgr_bellmanFord(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], ARRAY[$3]::BIGINT[], directed, false) AS a;
$function$
;

-- Function: pgr_bellmanford
-- Comment: pgr_bellmanFord(One to One)
- EXPERIMENTAL
- Parameters:
  - edges SQL with columns: id, source, target, cost [,reverse_cost]
  - From vertex identifier
  - To vertex identifier
- Optional Parameters:
  - directed := true
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_bellmanFord.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_bellmanford(text, text, directed boolean DEFAULT true, OUT seq integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT a.seq, a.path_seq, a.start_vid, a.end_vid, a.node, a.edge, a.cost, a.agg_cost
    FROM _pgr_bellmanFord(_pgr_get_statement($1), _pgr_get_statement($2), directed, false ) AS a;
$function$
;

-- Function: pgr_bellmanford
-- Comment: pgr_bellmanFord(Combinations)
- EXPERIMENTAL
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - Combinations SQL with columns: source, target
- Optional Parameters
  - directed := true
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_bellmanFord.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_bellmanford(text, bigint, anyarray, directed boolean DEFAULT true, OUT seq integer, OUT path_seq integer, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT a.seq, a.path_seq, a.end_vid, a.node, a.edge, a.cost, a.agg_cost
    FROM _pgr_bellmanFord(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], $3::BIGINT[], directed, false) AS a;
$function$
;

-- Function: pgr_bellmanford
-- Comment: pgr_bellmanFord(One to Many)
- EXPERIMENTAL
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - From vertex identifier
  - To ARRAY[vertices identifiers]
- Optional Parameters
  - directed := true
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_bellmanFord.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_bellmanford(text, anyarray, anyarray, directed boolean DEFAULT true, OUT seq integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT a.seq, a.path_seq, a.start_vid, a.end_vid, a.node, a.edge, a.cost, a.agg_cost
    FROM _pgr_bellmanFord(_pgr_get_statement($1), $2::BIGINT[], $3::BIGINT[], directed, false ) AS a;
$function$
;

-- Function: pgr_bellmanford
-- Comment: pgr_bellmanFord(Many to Many)
- EXPERIMENTAL
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - From ARRAY[vertices identifiers]
  - To ARRAY[vertices identifiers]
- Optional Parameters
  - directed := true
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_bellmanFord.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_bellmanford(text, anyarray, bigint, directed boolean DEFAULT true, OUT seq integer, OUT path_seq integer, OUT start_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT a.seq, a.path_seq, a.start_vid, a.node, a.edge, a.cost, a.agg_cost
    FROM _pgr_bellmanFord(_pgr_get_statement($1), $2::BIGINT[], ARRAY[$3]::BIGINT[], directed, false) AS a;
$function$
;

-- Function: pgr_bellmanford
-- Comment: pgr_bellmanFord(Many to One)
- EXPERIMENTAL
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - From ARRAY[vertices identifiers]
  - To vertex identifier
- Optional Parameters
  - directed := true
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_bellmanFord.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_betweennesscentrality(text, directed boolean DEFAULT true, OUT vid bigint, OUT centrality double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT vid, centrality
    FROM _pgr_betweennesscentrality(_pgr_get_statement($1), $2);
$function$
;

-- Function: pgr_betweennesscentrality
-- Comment: pgr_betweennessCentrality
- EXPERIMENTAL
- Parameters:
    - edges SQL with columns: source, target, cost [,reverse_cost])
- Optional Parameters:
    - directed := true
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_centrality.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_biconnectedcomponents(text, OUT seq bigint, OUT component bigint, OUT edge bigint)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, component, edge
    FROM _pgr_biconnectedComponents(_pgr_get_statement($1)) ;
$function$
;

-- Function: pgr_biconnectedcomponents
-- Comment: pgr_biconnectedComponents
- Undirected graph
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_biconnectedComponents.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_binarybreadthfirstsearch(text, bigint, bigint, directed boolean DEFAULT true, OUT seq integer, OUT path_seq integer, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT a.seq, a.path_seq, a.node, a.edge, a.cost, a.agg_cost
    FROM _pgr_binaryBreadthFirstSearch(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], ARRAY[$3]::BIGINT[], $4) AS a;
$function$
;

-- Function: pgr_binarybreadthfirstsearch
-- Comment: pgr_binaryBreadthFirstSearch(One to One)
- EXPERIMENTAL
- Parameters:
   - Edges SQL with columns: id, source, target, cost [,reverse_cost]
   - From vertex identifier
   - To vertex identifier
- Optional Parameters
   - directed := true
- Documentation:
   - https://docs.pgrouting.org/latest/en/pgr_binaryBreadthFirstSearch.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_binarybreadthfirstsearch(text, anyarray, anyarray, directed boolean DEFAULT true, OUT seq integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT a.seq, a.path_seq, a.start_vid, a.end_vid, a.node, a.edge, a.cost, a.agg_cost
    FROM _pgr_binaryBreadthFirstSearch(_pgr_get_statement($1), $2::BIGINT[], $3::BIGINT[], $4) AS a;
$function$
;

-- Function: pgr_binarybreadthfirstsearch
-- Comment: pgr_binaryBreadthFirstSearch(Many to Many)
- EXPERIMENTAL
- Parameters:
   - Edges SQL with columns: id, source, target, cost [,reverse_cost]
   - From ARRAY[vertices identifiers]
   - To ARRAY[vertices identifiers]
- Optional Parameters
   - directed := true
- Documentation:
   - https://docs.pgrouting.org/latest/en/pgr_binaryBreadthFirstSearch.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_binarybreadthfirstsearch(text, anyarray, bigint, directed boolean DEFAULT true, OUT seq integer, OUT path_seq integer, OUT start_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT a.seq, a.path_seq, a.start_vid, a.node, a.edge, a.cost, a.agg_cost
    FROM _pgr_binaryBreadthFirstSearch(_pgr_get_statement($1), $2::BIGINT[], ARRAY[$3]::BIGINT[], $4) AS a;
$function$
;

-- Function: pgr_binarybreadthfirstsearch
-- Comment: pgr_binaryBreadthFirstSearch(Many to One)
- EXPERIMENTAL
- Parameters:
   - Edges SQL with columns: id, source, target, cost [,reverse_cost]
   - From ARRAY[vertices identifiers]
   - To vertex identifier
- Optional Parameters
   - directed := true
- Documentation:
   - https://docs.pgrouting.org/latest/en/pgr_binaryBreadthFirstSearch.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_binarybreadthfirstsearch(text, text, directed boolean DEFAULT true, OUT seq integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT a.seq, a.path_seq, a.start_vid, a.end_vid, a.node, a.edge, a.cost, a.agg_cost
    FROM _pgr_binaryBreadthFirstSearch(_pgr_get_statement($1), _pgr_get_statement($2), $3) AS a;
$function$
;

-- Function: pgr_binarybreadthfirstsearch
-- Comment: pgr_binaryBreadthFirstSearch(Combinations)
- EXPERIMENTAL
- Parameters:
   - Edges SQL with columns: id, source, target, cost [,reverse_cost]
   - Combinations SQL with columns: source, target
- Optional Parameters
   - directed := true
- Documentation:
   - https://docs.pgrouting.org/latest/en/pgr_binaryBreadthFirstSearch.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_binarybreadthfirstsearch(text, bigint, anyarray, directed boolean DEFAULT true, OUT seq integer, OUT path_seq integer, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT a.seq, a.path_seq, a.end_vid, a.node, a.edge, a.cost, a.agg_cost
    FROM _pgr_binaryBreadthFirstSearch(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], $3::BIGINT[], $4) AS a;
$function$
;

-- Function: pgr_binarybreadthfirstsearch
-- Comment: pgr_binaryBreadthFirstSearch(One to Many)
- EXPERIMENTAL
- Parameters:
   - Edges SQL with columns: id, source, target, cost [,reverse_cost]
   - From vertex identifier
   - To ARRAY[vertices identifiers]
- Optional Parameters
   - directed := true
- Documentation:
   - https://docs.pgrouting.org/latest/en/pgr_binaryBreadthFirstSearch.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_bipartite(text, OUT vertex_id bigint, OUT color_id bigint)
 RETURNS SETOF record
 LANGUAGE plpgsql
 STRICT
AS $function$
BEGIN
    RETURN QUERY
    SELECT node, color
    FROM _pgr_bipartite(_pgr_get_statement($1));
END;
$function$
;

-- Function: pgr_bipartite
-- Comment: pgr_bipartite
- EXPERIMENTAL
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_bipartite.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_boykovkolmogorov(text, bigint, anyarray, OUT seq integer, OUT edge bigint, OUT start_vid bigint, OUT end_vid bigint, OUT flow bigint, OUT residual_capacity bigint)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
        SELECT seq, edge_id, source, target, flow, residual_capacity
        FROM _pgr_maxflow(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], $3::BIGINT[], 2);
  $function$
;

-- Function: pgr_boykovkolmogorov
-- Comment: pgr_boykovKolmogorov(One to Many)
- Directed graph
- Parameters:
  - edges SQL with columns: id, source, target, capacity [,reverse_capacity]
  - from vertex
  - to ARRAY[vertices identifiers]
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_boykovKolmogorov.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_boykovkolmogorov(text, bigint, bigint, OUT seq integer, OUT edge bigint, OUT start_vid bigint, OUT end_vid bigint, OUT flow bigint, OUT residual_capacity bigint)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
        SELECT seq, edge_id, source, target, flow, residual_capacity
        FROM _pgr_maxflow(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], ARRAY[$3]::BIGINT[], 2);
  $function$
;

-- Function: pgr_boykovkolmogorov
-- Comment: pgr_boykovKolmogorov(One to One)
- Directed graph
- Parameters:
  - edges SQL with columns: id, source, target, capacity [,reverse_capacity]
  - from vertex
  - to vertex
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_boykovKolmogorov.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_boykovkolmogorov(text, text, OUT seq integer, OUT edge bigint, OUT start_vid bigint, OUT end_vid bigint, OUT flow bigint, OUT residual_capacity bigint)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
        SELECT seq, edge_id, source, target, flow, residual_capacity
        FROM _pgr_maxflow(_pgr_get_statement($1), _pgr_get_statement($2), 2);
  $function$
;

-- Function: pgr_boykovkolmogorov
-- Comment: pgr_boykovKolmogorov(Combinations)
 - Directed graph
 - Parameters:
   - Edges SQL with columns: id, source, target, capacity [,reverse_capacity]
   - Combinations SQL with columns: source, target
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_boykovKolmogorov.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_boykovkolmogorov(text, anyarray, anyarray, OUT seq integer, OUT edge bigint, OUT start_vid bigint, OUT end_vid bigint, OUT flow bigint, OUT residual_capacity bigint)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
        SELECT seq, edge_id, source, target, flow, residual_capacity
        FROM _pgr_maxflow(_pgr_get_statement($1), $2::BIGINT[], $3::BIGINT[], 2);
  $function$
;

-- Function: pgr_boykovkolmogorov
-- Comment: pgr_boykovKolmogorov(Many to Many)
 - Directed graph
 - Parameters:
   - edges SQL with columns: id, source, target, capacity [,reverse_capacity]
   - from ARRAY[vertices identifiers]
   - to ARRAY[vertices identifiers]
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_boykovKolmogorov.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_boykovkolmogorov(text, anyarray, bigint, OUT seq integer, OUT edge bigint, OUT start_vid bigint, OUT end_vid bigint, OUT flow bigint, OUT residual_capacity bigint)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
        SELECT seq, edge_id, source, target, flow, residual_capacity
        FROM _pgr_maxflow(_pgr_get_statement($1), $2::BIGINT[], ARRAY[$3]::BIGINT[], 2);
  $function$
;

-- Function: pgr_boykovkolmogorov
-- Comment: pgr_boykovKolmogorov(Many to One)
- Directed graph
- Parameters:
  - edges SQL with columns: id, source, target, capacity [,reverse_capacity]
  - from ARRAY[vertices identifiers]
  - to vertex
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_boykovKolmogorov.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_breadthfirstsearch(text, anyarray, max_depth bigint DEFAULT '9223372036854775807'::bigint, directed boolean DEFAULT true, OUT seq bigint, OUT depth bigint, OUT start_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE plpgsql
 STRICT
AS $function$
BEGIN
    IF $3 < 0 THEN
        RAISE EXCEPTION 'Negative value found on ''max_depth'''
        USING HINT = format('Value found: %s', $3);
    END IF;
    RETURN QUERY
    SELECT a.seq, a.depth, a.start_vid, a.node, a.edge, a.cost, a.agg_cost
    FROM _pgr_breadthFirstSearch(_pgr_get_statement($1), $2::BIGINT[], max_depth, directed) AS a;
END;
$function$
;

-- Function: pgr_breadthfirstsearch
-- Comment: pgr_breadthFirstSearch(Many to Depth)
- EXPERIMENTAL
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - From ARRAY[vertices identifiers]
- Optional Parameters
  - Maximum Depth := 9223372036854775807
  - directed := true
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_breadthFirstSearch.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_breadthfirstsearch(text, bigint, max_depth bigint DEFAULT '9223372036854775807'::bigint, directed boolean DEFAULT true, OUT seq bigint, OUT depth bigint, OUT start_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE plpgsql
 STRICT
AS $function$
BEGIN
    IF $3 < 0 THEN
        RAISE EXCEPTION 'Negative value found on ''max_depth'''
        USING HINT = format('Value found: %s', $3);
    END IF;
    RETURN QUERY
    SELECT a.seq, a.depth, a.start_vid, a.node, a.edge, a.cost, a.agg_cost
    FROM _pgr_breadthFirstSearch(_pgr_get_statement($1),  ARRAY[$2]::BIGINT[], max_depth, directed) AS a;
END;
$function$
;

-- Function: pgr_breadthfirstsearch
-- Comment: pgr_breadthFirstSearch(One to Depth)
- EXPERIMENTAL
- Parameters:
  - edges SQL with columns: id, source, target, cost [,reverse_cost]
  - From vertex identifier
- Optional Parameters:
  - Maximum Depth := 9223372036854775807
  - directed := true
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_breadthFirstSearch.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_bridges(text, OUT edge bigint)
 RETURNS SETOF bigint
 LANGUAGE sql
 STRICT
AS $function$
    SELECT edge
    FROM _pgr_bridges(_pgr_get_statement($1));
$function$
;

-- Function: pgr_bridges
-- Comment: pgr_bridges
- Undirected graph
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_bridges.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_chinesepostman(text, OUT seq integer, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, node, edge, cost, agg_cost
    FROM _pgr_chinesePostman(_pgr_get_statement($1), only_cost := false);
$function$
;

-- Function: pgr_chinesepostman
-- Comment: pgr_chinesePostman
- EXPERIMENTAL
- Directed graph
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_chinesePostman.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_chinesepostmancost(text)
 RETURNS double precision
 LANGUAGE sql
 STRICT
AS $function$
    SELECT cost
    FROM _pgr_chinesePostman(_pgr_get_statement($1), only_cost := true);
$function$
;

-- Function: pgr_chinesepostmancost
-- Comment: pgr_chinesePostmanCost
- EXPERIMENTAL
- Directed graph
- Parameters:
	- Edges SQL with columns: id, source, target, cost [,reverse_cost]
- Documentation:
	- https://docs.pgrouting.org/latest/en/pgr_chinesePostmanCost.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_connectedcomponents(text, OUT seq bigint, OUT component bigint, OUT node bigint)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, component, node
    FROM _pgr_connectedComponents(_pgr_get_statement($1));
$function$
;

-- Function: pgr_connectedcomponents
-- Comment: pgr_connectedComponents
- Undirected graph
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_connectedComponents.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_contraction(text, directed boolean DEFAULT true, methods integer[] DEFAULT ARRAY[1, 2], cycles integer DEFAULT 1, forbidden bigint[] DEFAULT ARRAY[]::bigint[], OUT type text, OUT id bigint, OUT contracted_vertices bigint[], OUT source bigint, OUT target bigint, OUT cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
  SELECT type, id, contracted_vertices, source, target, cost
  FROM _pgr_contraction(_pgr_get_statement($1), methods::BIGINT[], cycles, forbidden, directed);
$function$
;

-- Function: pgr_contraction
-- Comment: pgr_contraction
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
- Optional Parameters
    - directed := true
    - methods := ARRAY[1,2]
    - cycles := 1
    - forbidden := ARRAY[]::BIGINT[]
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_contraction.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_contraction(text, bigint[], max_cycles integer DEFAULT 1, forbidden_vertices bigint[] DEFAULT ARRAY[]::bigint[], directed boolean DEFAULT true, OUT type text, OUT id bigint, OUT contracted_vertices bigint[], OUT source bigint, OUT target bigint, OUT cost double precision)
 RETURNS SETOF record
 LANGUAGE plpgsql
 STRICT
AS $function$
BEGIN
    RAISE NOTICE 'Deprecated Signature pgr_contraction(text,bigint[],integer,integer[],bigint[],boolean) in v3.8.0';
    RETURN QUERY
    SELECT a.type, a.id, a.contracted_vertices, a.source, a.target, a.cost
    FROM _pgr_contraction(_pgr_get_statement($1), $2::BIGINT[],  $3, $4, $5) AS a;
END;
$function$
;

-- Function: pgr_contraction
-- Comment: pgr_contraction deprecated in 3.8.0
-- 
CREATE OR REPLACE FUNCTION public.pgr_contractiondeadend(text, directed boolean DEFAULT true, forbidden bigint[] DEFAULT ARRAY[]::bigint[], OUT type text, OUT id bigint, OUT contracted_vertices bigint[], OUT source bigint, OUT target bigint, OUT cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT type, id, contracted_vertices, source, target, cost
    FROM _pgr_contraction(_pgr_get_statement($1), ARRAY[1]::BIGINT[], 1, $3, $2);
$function$
;

-- Function: pgr_contractiondeadend
-- Comment: pgr_contractionDeadEnd
- PROPOSED
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
- Optional Parameters
    - directed := true
    - forbidden := ARRAY[]::BIGINT[]
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_contractionDeadEnd.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_contractionhierarchies(text, directed boolean DEFAULT true, forbidden bigint[] DEFAULT ARRAY[]::bigint[], OUT type text, OUT id bigint, OUT contracted_vertices bigint[], OUT source bigint, OUT target bigint, OUT cost double precision, OUT metric bigint, OUT vertex_order bigint)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT type, id, contracted_vertices, source, target, cost, metric, vertex_order
    FROM _pgr_contractionhierarchies(_pgr_get_statement($1), $3::BIGINT[], $2);
$function$
;

-- Function: pgr_contractionhierarchies
-- Comment: pgr_contractionHierarchies
- EXPERIMENTAL
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
- Optional Parameters
    - forbidden := ARRAY[]::BIGINT[]
    - directed := true
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_contractionHierarchies.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_contractionlinear(text, directed boolean DEFAULT true, forbidden bigint[] DEFAULT ARRAY[]::bigint[], OUT type text, OUT id bigint, OUT contracted_vertices bigint[], OUT source bigint, OUT target bigint, OUT cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT type, id, contracted_vertices, source, target, cost
    FROM _pgr_contraction(_pgr_get_statement($1), ARRAY[2]::BIGINT[], 1, $3, $2);
$function$
;

-- Function: pgr_contractionlinear
-- Comment: pgr_contractionLinear
- PROPOSED
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
- Optional Parameters
    - directed := true
    - forbidden := ARRAY[]::BIGINT[]
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_contractionLinear.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_createtopology(text, double precision, the_geom text DEFAULT 'the_geom'::text, id text DEFAULT 'id'::text, source text DEFAULT 'source'::text, target text DEFAULT 'target'::text, rows_where text DEFAULT 'true'::text, clean boolean DEFAULT false)
 RETURNS character varying
 LANGUAGE plpgsql
 STRICT
AS $function$
DECLARE
    edge_table TEXT := $1;
    tolerance FLOAT := $2;
    points record;
    sridinfo record;
    source_id BIGINT;
    target_id BIGINT;
    totcount BIGINT;
    rowcount BIGINT;
    srid INTEGER;
    sql TEXT;
    sname TEXT;
    tname TEXT;
    tabname TEXT;
    vname TEXT;
    vertname TEXT;
    gname TEXT;
    idname TEXT;
    sourcename TEXT;
    targetname TEXT;
    notincluded INTEGER;
    i INTEGER;
    naming record;
    info record;
    flag boolean;
    query TEXT;
    idtype TEXT;
    gtype TEXT;
    sourcetype TEXT;
    targettype TEXT;
    debuglevel TEXT;
    dummyRec record;
    fnName TEXT;
    err bool;
    msgKind int;
    emptied BOOLEAN;
BEGIN
    msgKind = 1; -- notice
    RAISE WARNING 'pgr_createtopology(text,double precision,text,text,text,text,text,boolean) deprecated function on v3.8.0';
    fnName = 'pgr_createTopology';
    RAISE notice 'PROCESSING:';
    RAISE notice 'pgr_createTopology(''%'', %, ''%'', ''%'', ''%'', ''%'', rows_where := ''%'', clean := %)',edge_table,tolerance,the_geom,id,source,target,rows_where, clean;
    EXECUTE 'show client_min_messages' INTO debuglevel;
    RAISE notice 'Performing checks, please wait .....';
        EXECUTE 'SELECT sname, tname FROM _pgr_getTableName('|| quote_literal(edge_table)
                                                  || ',2,' || quote_literal(fnName) ||' )' INTO naming;
        sname=naming.sname;
        tname=naming.tname;
        tabname=sname||'.'||tname;
        vname=tname||'_vertices_pgr';
        vertname= sname||'.'||vname;
        rows_where = ' AND ('||rows_where||')';
      RAISE DEBUG '     --> OK';
      RAISE debug 'Checking column names in edge table';
        SELECT _pgr_getColumnName INTO idname     FROM _pgr_getColumnName(sname, tname,id,2,fnName);
        SELECT _pgr_getColumnName INTO sourcename FROM _pgr_getColumnName(sname, tname,source,2,fnName);
        SELECT _pgr_getColumnName INTO targetname FROM _pgr_getColumnName(sname, tname,target,2,fnName);
        SELECT _pgr_getColumnName INTO gname      FROM _pgr_getColumnName(sname, tname,the_geom,2,fnName);
        err = sourcename in (targetname,idname,gname) OR  targetname in (idname,gname) OR idname=gname;
        perform _pgr_onError( err, 2, fnName,
               'Two columns share the same name', 'Parameter names for id,the_geom,source and target  must be different',
	       'Column names are OK');
      RAISE DEBUG '     --> OK';
      RAISE debug 'Checking column types in edge table';
        SELECT _pgr_getColumnType INTO sourcetype FROM _pgr_getColumnType(sname,tname,sourcename,1, fnName);
        SELECT _pgr_getColumnType INTO targettype FROM _pgr_getColumnType(sname,tname,targetname,1, fnName);
        SELECT _pgr_getColumnType INTO idtype FROM _pgr_getColumnType(sname,tname,idname,1, fnName);
        err = idtype NOT in('integer','smallint','bigint');
        perform _pgr_onError(err, 2, fnName,
	       'Wrong type of Column id:'|| idname, ' Expected type of '|| idname || ' is integer,smallint or bigint but '||idtype||' was found');
        err = sourcetype NOT in('integer','smallint','bigint');
        perform _pgr_onError(err, 2, fnName,
	       'Wrong type of Column source:'|| sourcename, ' Expected type of '|| sourcename || ' is integer,smallint or bigint but '||sourcetype||' was found');
        err = targettype NOT in('integer','smallint','bigint');
        perform _pgr_onError(err, 2, fnName,
	       'Wrong type of Column target:'|| targetname, ' Expected type of '|| targetname || ' is integer,smallint or bigint but '||targettype||' was found');
      RAISE DEBUG '     --> OK';
      RAISE debug 'Checking SRID of geometry column';
         query= 'SELECT ST_SRID(' || quote_ident(gname) || ') AS srid '
            || ' FROM ' || _pgr_quote_ident(tabname)
            || ' WHERE ' || quote_ident(gname)
            || ' IS NOT NULL LIMIT 1';
         RAISE debug '%',query;
         EXECUTE query INTO sridinfo;
         err =  sridinfo IS NULL OR sridinfo.srid IS NULL;
         perform _pgr_onError(err, 2, fnName,
	     'Can not determine the srid of the geometry '|| gname ||' in table '||tabname, 'Check the geometry of column '||gname);
         srid := sridinfo.srid;
      RAISE DEBUG '     --> OK';
      RAISE debug 'Checking and creating indices in edge table';
        perform _pgr_createIndex(sname, tname , idname , 'btree'::TEXT);
        perform _pgr_createIndex(sname, tname , sourcename , 'btree'::TEXT);
        perform _pgr_createIndex(sname, tname , targetname , 'btree'::TEXT);
        perform _pgr_createIndex(sname, tname , gname , 'gist'::TEXT);
        gname=quote_ident(gname);
        idname=quote_ident(idname);
        sourcename=quote_ident(sourcename);
        targetname=quote_ident(targetname);
      RAISE DEBUG '     --> OK';
    BEGIN
        sql = 'SELECT '||idname ||','|| sourcename ||','|| targetname ||','|| gname || ' FROM '||_pgr_quote_ident(tabname)||' WHERE true'||rows_where ||' limit 1';
        EXECUTE sql INTO dummyRec;
        sql = 'SELECT count(*) FROM '||_pgr_quote_ident(tabname)||' WHERE (' || gname || ' IS NOT NULL AND '||
	    idname||' IS NOT NULL)=false '||rows_where;
        EXECUTE SQL  INTO notincluded;
        if clean then
            RAISE debug 'Cleaning previous Topology ';
               EXECUTE 'UPDATE ' || _pgr_quote_ident(tabname) ||
               ' SET '||sourcename||' = NULL,'||targetname||' = NULL';
        else
            RAISE debug 'Creating topology for edges with non assigned topology';
            if rows_where=' AND (true)' then
                rows_where=  ' AND ('||quote_ident(sourcename)||' is NULL OR '||quote_ident(targetname)||' is  NULL)';
            end if;
        end if;
        EXCEPTION WHEN OTHERS THEN
             RAISE NOTICE 'Got %', SQLERRM; -- issue 210,211
             RAISE NOTICE 'ERROR: Condition is not correct, please execute the following query to test your condition';
             RAISE NOTICE '%',sql;
             RETURN 'FAIL';
    END;
    BEGIN
         RAISE DEBUG 'initializing %',vertname;
         EXECUTE 'SELECT sname, tname FROM _pgr_getTableName('||quote_literal(vertname)
                                                  || ',0,' || quote_literal(fnName) ||' )' INTO naming;
         emptied = false;
         set client_min_messages  to warning;
         IF sname=naming.sname AND vname=naming.tname  THEN
            if clean then
                EXECUTE 'TRUNCATE TABLE '||_pgr_quote_ident(vertname)||' RESTART IDENTITY';
                EXECUTE 'SELECT DROPGEOMETRYCOLUMN('||quote_literal(sname)||','||quote_literal(vname)||','||quote_literal('the_geom')||')';
                emptied = true;
            end if;
         ELSE -- table doesn't exist
            EXECUTE 'CREATE TABLE '||_pgr_quote_ident(vertname)||' (id bigserial PRIMARY KEY,cnt integer,chk integer,ein integer,eout integer)';
            emptied = true;
         END IF;
         IF (emptied) THEN
             EXECUTE 'SELECT addGeometryColumn('||quote_literal(sname)||','||quote_literal(vname)||','||
	         quote_literal('the_geom')||','|| srid||', '||quote_literal('POINT')||', 2)';
             perform _pgr_createIndex(vertname , 'the_geom'::TEXT , 'gist'::TEXT);
         END IF;
         EXECUTE 'SELECT _pgr_checkVertTab FROM  _pgr_checkVertTab('||quote_literal(vertname) ||', ''{"id"}''::TEXT[])' INTO naming;
         EXECUTE 'set client_min_messages  to '|| debuglevel;
         RAISE DEBUG  '  ------>OK';
         EXCEPTION WHEN OTHERS THEN
             RAISE NOTICE 'Got %', SQLERRM; -- issue 210,211
             RAISE NOTICE 'ERROR: something went wrong when initializing the verties table';
             RETURN 'FAIL';
    END;
    RAISE notice 'Creating Topology, Please wait...';
        rowcount := 0;
        FOR points IN EXECUTE 'SELECT ' || idname || '::BIGINT AS id,'
            || ' _pgr_StartPoint(' || gname || ') AS source,'
            || ' _pgr_EndPoint('   || gname || ') AS target'
            || ' FROM '  || _pgr_quote_ident(tabname)
            || ' WHERE ' || gname || ' IS NOT NULL AND ' || idname||' IS NOT NULL '||rows_where
        LOOP
            rowcount := rowcount + 1;
            IF rowcount % 1000 = 0 THEN
                RAISE NOTICE '% edges processed', rowcount;
            END IF;
            source_id := _pgr_pointToId(points.source, tolerance,vertname,srid);
            target_id := _pgr_pointToId(points.target, tolerance,vertname,srid);
            BEGIN
                sql := 'UPDATE ' || _pgr_quote_ident(tabname) ||
                    ' SET '||sourcename||' = '|| source_id::TEXT || ','||targetname||' = ' || target_id::TEXT ||
                    ' WHERE ' || idname || ' =  ' || points.id::TEXT;
                IF sql IS NULL THEN
                    RAISE NOTICE 'WARNING: UPDATE % SET source = %, target = % WHERE % = % ', tabname, source_id::TEXT, target_id::TEXT, idname,  points.id::TEXT;
                ELSE
                    EXECUTE sql;
                END IF;
                EXCEPTION WHEN OTHERS THEN
                    RAISE NOTICE '%', SQLERRM;
                    RAISE NOTICE '%',sql;
                    RETURN 'FAIL';
            end;
        END LOOP;
        RAISE notice '-------------> TOPOLOGY CREATED FOR  % edges', rowcount;
        RAISE NOTICE 'Rows with NULL geometry or NULL id: %',notincluded;
        RAISE notice 'Vertices table for table % is: %',_pgr_quote_ident(tabname), _pgr_quote_ident(vertname);
        RAISE notice '----------------------------------------------';
    RETURN 'OK';
 EXCEPTION WHEN OTHERS THEN
   RAISE NOTICE 'Unexpected error %', SQLERRM; -- issue 210,211
   RETURN 'FAIL';
END;
$function$
;

-- Function: pgr_createtopology
-- Comment: pgr_createTopology deprecated function on v3.8.0
-- 
CREATE OR REPLACE FUNCTION public.pgr_createverticestable(text, the_geom text DEFAULT 'the_geom'::text, source text DEFAULT 'source'::text, target text DEFAULT 'target'::text, rows_where text DEFAULT 'true'::text)
 RETURNS text
 LANGUAGE plpgsql
 STRICT
AS $function$
DECLARE
    edge_table TEXT := $1;
    naming record;
    sridinfo record;
    sname TEXT;
    tname TEXT;
    tabname TEXT;
    vname TEXT;
    vertname TEXT;
    gname TEXT;
    sourcename TEXT;
    targetname TEXT;
    query TEXT;
    ecnt BIGINT;
    srid INTEGER;
    sourcetype TEXT;
    targettype TEXT;
    sql TEXT;
    totcount INTEGER;
    i INTEGER;
    notincluded INTEGER;
    included INTEGER;
    debuglevel TEXT;
    dummyRec record;
    fnName TEXT;
    err bool;
BEGIN
  fnName = 'pgr_createVerticesTable';
  RAISE WARNING 'pgr_createverticestable(text,text,text,text,text) deprecated function on v3.8.0';
  RAISE NOTICE 'PROCESSING:';
  RAISE NOTICE 'pgr_createVerticesTable(''%'',''%'',''%'',''%'',''%'')',edge_table,the_geom,source,target,rows_where;
  EXECUTE 'show client_min_messages' INTO debuglevel;
  RAISE NOTICE 'Performing checks, please wait .....';
  RAISE DEBUG 'Checking % exists',edge_table;
        EXECUTE 'select * from _pgr_getTableName('|| quote_literal(edge_table)
                                                  || ',2,' || quote_literal(fnName) ||' )' INTO naming;
    sname=naming.sname;
    tname=naming.tname;
    tabname=sname||'.'||tname;
    vname=tname||'_vertices_pgr';
    vertname= sname||'.'||vname;
    rows_where = ' AND ('||rows_where||')';
  RAISE DEBUG '--> Edge table exists: OK';
  RAISE DEBUG 'Checking column names';
    select * INTO sourcename FROM _pgr_getColumnName(sname, tname,source,2, fnName);
    select * INTO targetname FROM _pgr_getColumnName(sname, tname,target,2, fnName);
    select * INTO gname      FROM _pgr_getColumnName(sname, tname,the_geom,2, fnName);
    err = sourcename IN (targetname,gname) OR  targetname=gname;
    perform _pgr_onError(err, 2, fnName,
        'Two columns share the same name', 'Parameter names for the_geom,source and target  must be different');
  RAISE DEBUG '--> Column names: OK';
  RAISE DEBUG 'Checking column types in edge table';
    select * INTO sourcetype FROM _pgr_getColumnType(sname,tname,sourcename,1, fnName);
    select * INTO targettype FROM _pgr_getColumnType(sname,tname,targetname,1, fnName);
    err = sourcetype not in('integer','smallint','bigint');
    perform _pgr_onError(err, 2, fnName,
        'Wrong type of Column source: '|| sourcename, ' Expected type of '|| sourcename || ' is integer, smallint or bigint but '||sourcetype||' was found');
    err = targettype not in('integer','smallint','bigint');
    perform _pgr_onError(err, 2, fnName,
        'Wrong type of Column target: '|| targetname, ' Expected type of '|| targetname || ' is integer, smallint or bigint but '||targettype||' was found');
  RAISE DEBUG '-->Column types:OK';
  RAISE DEBUG 'Checking SRID of geometry column';
     query= 'SELECT ST_SRID(' || quote_ident(gname) || ') as srid '
        || ' FROM ' || _pgr_quote_ident(tabname)
        || ' WHERE ' || quote_ident(gname)
        || ' IS NOT NULL LIMIT 1';
     RAISE DEBUG '%',query;
     EXECUTE query INTO sridinfo;
     err =  sridinfo IS NULL OR sridinfo.srid IS NULL;
     perform _pgr_onError(err, 2, fnName,
         'Can not determine the srid of the geometry '|| gname ||' in table '||tabname, 'Check the geometry of column '||gname);
     srid := sridinfo.srid;
  RAISE DEBUG '     --> OK';
  RAISE DEBUG 'Checking and creating Indices';
     perform _pgr_createIndex(sname, tname , sourcename , 'btree'::TEXT);
     perform _pgr_createIndex(sname, tname , targetname , 'btree'::TEXT);
     perform _pgr_createIndex(sname, tname , gname , 'gist'::TEXT);
  RAISE DEBUG '-->Check and create indices: OK';
     gname=quote_ident(gname);
     sourcename=quote_ident(sourcename);
     targetname=quote_ident(targetname);
  BEGIN
  RAISE DEBUG 'Checking Condition';
    sql = 'select * from '||_pgr_quote_ident(tabname)||' WHERE true'||rows_where ||' limit 1';
    EXECUTE sql INTO dummyRec;
    sql = 'select count(*) from '||_pgr_quote_ident(tabname)||' WHERE (' || gname || ' IS NULL or '||
		sourcename||' is null or '||targetname||' is null)=true '||rows_where;
    RAISE DEBUG '%',sql;
    EXECUTE SQL  INTO notincluded;
    EXCEPTION WHEN OTHERS THEN
         RAISE NOTICE 'Got %', SQLERRM; -- issue 210,211
         RAISE NOTICE 'ERROR: Condition is not correct, please execute the following query to test your condition';
         RAISE NOTICE '%',sql;
         RETURN 'FAIL';
  END;
  BEGIN
     RAISE DEBUG 'initializing %',vertname;
       EXECUTE 'select * from _pgr_getTableName('||quote_literal(vertname)||',0)' INTO naming;
       IF sname=naming.sname  AND vname=naming.tname  THEN
           EXECUTE 'TRUNCATE TABLE '||_pgr_quote_ident(vertname)||' RESTART IDENTITY';
           EXECUTE 'SELECT DROPGEOMETRYCOLUMN('||quote_literal(sname)||','||quote_literal(vname)||','||quote_literal('the_geom')||')';
       ELSE
           set client_min_messages  to warning;
       	   EXECUTE 'CREATE TABLE '||_pgr_quote_ident(vertname)||' (id bigserial PRIMARY KEY,cnt INTEGER,chk INTEGER,ein INTEGER,eout INTEGER)';
       END IF;
       EXECUTE 'select addGeometryColumn('||quote_literal(sname)||','||quote_literal(vname)||','||
                quote_literal('the_geom')||','|| srid||', '||quote_literal('POINT')||', 2)';
       EXECUTE 'CREATE INDEX '||quote_ident(vname||'_the_geom_idx')||' ON '||_pgr_quote_ident(vertname)||'  USING GIST (the_geom)';
       EXECUTE 'set client_min_messages  to '|| debuglevel;
       RAISE DEBUG  '  ------>OK';
       EXCEPTION WHEN OTHERS THEN
         RAISE NOTICE 'Got %', SQLERRM; -- issue 210,211
         RAISE NOTICE 'ERROR: Initializing vertex table';
         RAISE NOTICE '%',sql;
         RETURN 'FAIL';
  END;
  BEGIN
       RAISE NOTICE 'Populating %, please wait...',vertname;
       sql= 'with
		lines as ((select distinct '||sourcename||' as id, _pgr_startpoint(st_linemerge('||gname||')) as the_geom from '||_pgr_quote_ident(tabname)||
		                  ' where ('|| gname || ' IS NULL
                                    OR '||sourcename||' is null
                                    OR '||targetname||' is null)=false
                                     '||rows_where||')
			UNION (select distinct '||targetname||' as id,_pgr_endpoint(st_linemerge('||gname||')) as the_geom from '||_pgr_quote_ident(tabname)||
			          ' where ('|| gname || ' IS NULL
                                    OR '||sourcename||' is null
                                    OR '||targetname||' is null)=false
                                     '||rows_where||'))
		,numberedLines as (select row_number() OVER (ORDER BY id) AS i,* from lines )
		,maxid as (select id,max(i) as maxi from numberedLines GROUP BY id)
		insert INTO '||_pgr_quote_ident(vertname)||'(id,the_geom)  (select id,the_geom  from numberedLines join maxid using(id) where i=maxi ORDER BY id)';
       RAISE DEBUG '%',sql;
       EXECUTE sql;
       GET DIAGNOSTICS totcount = ROW_COUNT;
       sql = 'select count(*) from '||_pgr_quote_ident(tabname)||' a, '||_pgr_quote_ident(vertname)||' b
            where '||sourcename||'=b.id AND '|| targetname||' IN (select id from '||_pgr_quote_ident(vertname)||')';
       RAISE DEBUG '%',sql;
       EXECUTE sql INTO included;
       EXECUTE 'select max(id) from '||_pgr_quote_ident(vertname) INTO ecnt;
       EXECUTE 'SELECT setval('||quote_literal(vertname||'_id_seq')||','||coalesce(ecnt,1)||' , false)';
       RAISE NOTICE '  ----->   VERTICES TABLE CREATED WITH  % VERTICES', totcount;
       RAISE NOTICE '                                       FOR   %  EDGES', included+notincluded;
       RAISE NOTICE '  Edges with NULL geometry,source or target: %',notincluded;
       RAISE NOTICE '                            Edges processed: %',included;
       RAISE NOTICE 'Vertices table for table % is: %',_pgr_quote_ident(tabname),_pgr_quote_ident(vertname);
       RAISE NOTICE '----------------------------------------------';
    END;
    RETURN 'OK';
 EXCEPTION WHEN OTHERS THEN
   RAISE NOTICE 'Unexpected error %', SQLERRM; -- issue 210,211
   RETURN 'FAIL';
END;
$function$
;

-- Function: pgr_createverticestable
-- Comment: pgr_createVerticesTable deprecated function on v3.8.0
-- 
CREATE OR REPLACE FUNCTION public.pgr_cuthillmckeeordering(text, OUT seq bigint, OUT node bigint)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, node
    FROM _pgr_cuthillMckeeOrdering(_pgr_get_statement($1));
$function$
;

-- Function: pgr_cuthillmckeeordering
-- Comment: pgr_cuthillMckeeOrdering
- EXPERIMENTAL
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_cuthillMckeeOrdering.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_dagshortestpath(text, bigint, bigint, OUT seq integer, OUT path_seq integer, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT a.seq, a.path_seq, a.node, a.edge, a.cost, a.agg_cost
    FROM _pgr_dagShortestPath(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], ARRAY[$3]::BIGINT[], true, false ) AS a;
$function$
;

-- Function: pgr_dagshortestpath
-- Comment: pgr_dagShortestPath(One to One)
- EXPERIMENTAL
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
    - From vertex identifier
    - To vertex identifier
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_dagShortestPath.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_dagshortestpath(text, anyarray, anyarray, OUT seq integer, OUT path_seq integer, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT a.seq, a.path_seq, a.node, a.edge, a.cost, a.agg_cost
    FROM _pgr_dagShortestPath(_pgr_get_statement($1), $2::BIGINT[], $3::BIGINT[], true, false ) AS a;
$function$
;

-- Function: pgr_dagshortestpath
-- Comment: pgr_dagShortestPath(Many to Many)
- EXPERIMENTAL
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - From ARRAY[vertices identifiers]
  - To ARRAY[vertices identifiers]
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_dagShortestPath.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_dagshortestpath(text, anyarray, bigint, OUT seq integer, OUT path_seq integer, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT a.seq, a.path_seq, a.node, a.edge, a.cost, a.agg_cost
    FROM _pgr_dagShortestPath(_pgr_get_statement($1), $2::BIGINT[], ARRAY[$3]::BIGINT[], true, false ) AS a;
$function$
;

-- Function: pgr_dagshortestpath
-- Comment: pgr_dagShortestPath(Many to One)
- EXPERIMENTAL
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - From ARRAY[vertices identifiers]
  - To vertex identifier
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_dagShortestPath.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_dagshortestpath(text, bigint, anyarray, OUT seq integer, OUT path_seq integer, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT a.seq, a.path_seq, a.node, a.edge, a.cost, a.agg_cost
    FROM _pgr_dagShortestPath(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], $3::BIGINT[], true, false ) AS a;
$function$
;

-- Function: pgr_dagshortestpath
-- Comment: pgr_dagShortestPath(One to Many)
- EXPERIMENTAL
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - From vertex identifier
  - To ARRAY[vertices identifiers]
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_dagShortestPath.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_dagshortestpath(text, text, OUT seq integer, OUT path_seq integer, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT a.seq, a.path_seq, a.node, a.edge, a.cost, a.agg_cost
    FROM _pgr_dagShortestPath(_pgr_get_statement($1), _pgr_get_statement($2), true, false ) AS a;
$function$
;

-- Function: pgr_dagshortestpath
-- Comment: pgr_dagShortestPath(Combinations)
- EXPERIMENTAL
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - Combinations SQL with columns: source, target
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_dagShortestPath.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_degree(text, dryrun boolean DEFAULT false, OUT node bigint, OUT degree bigint)
 RETURNS SETOF record
 LANGUAGE plpgsql
 STRICT
AS $function$
DECLARE
  edges_sql TEXT;
  has_id BOOLEAN;
  has_source BOOLEAN;
  has_target BOOLEAN;
  eids TEXT;
  query TEXT;
  sqlhint TEXT;
BEGIN
  BEGIN
    edges_sql := _pgr_checkQuery($1);
    has_id :=  _pgr_checkColumn(edges_sql, 'id', 'ANY-INTEGER', dryrun => $2);
    has_source :=  _pgr_checkColumn(edges_sql, 'source', 'ANY-INTEGER', dryrun => $2);
    has_target :=  _pgr_checkColumn(edges_sql, 'target', 'ANY-INTEGER', dryrun => $2);
    EXCEPTION WHEN OTHERS THEN
      GET STACKED DIAGNOSTICS sqlhint = PG_EXCEPTION_HINT;
      RAISE EXCEPTION '%', SQLERRM USING HINT = sqlhint, ERRCODE = SQLSTATE;
  END;
  query := format($q$
    WITH
    g_edges AS (
      %1$s
    ),
    g_vertices AS (
      SELECT source, id FROM g_edges
      UNION ALL
      SELECT target, id FROM g_edges
    ),
    totals AS (
      SELECT source AS node, count(*) AS degree
      FROM g_vertices
      GROUP BY node
    )
    SELECT node::BIGINT, degree::BIGINT
    FROM totals
    $q$, edges_sql);
  IF dryrun THEN
    RAISE NOTICE '%', query || ';';
  ELSE
    RETURN QUERY EXECUTE query;
  END IF;
END;
$function$
;

-- Function: pgr_degree
-- Comment: pgr_degree
- Parameters
- Edges SQL with columns: id
- Documentation:
- https://docs.pgrouting.org/latest/en/pgr_degree.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_degree(text, text, dryrun boolean DEFAULT false, OUT node bigint, OUT degree bigint)
 RETURNS SETOF record
 LANGUAGE plpgsql
 STRICT
AS $function$
DECLARE
  edges_sql TEXT;
  vertices_sql TEXT;
  has_in_edges BOOLEAN := TRUE;
  has_out_edges BOOLEAN := TRUE;
  eids TEXT;
  query TEXT;
  sqlhint TEXT;
BEGIN
  BEGIN
    edges_sql := _pgr_checkQuery($1);
    PERFORM _pgr_checkColumn(edges_sql, 'id', 'ANY-INTEGER', dryrun => $3);
    vertices_sql := _pgr_checkQuery($2);
    PERFORM _pgr_checkColumn(vertices_sql, 'id', 'ANY-INTEGER', dryrun => $3);
    EXCEPTION WHEN OTHERS THEN
      GET STACKED DIAGNOSTICS sqlhint = PG_EXCEPTION_HINT;
      RAISE EXCEPTION '%', SQLERRM USING HINT = sqlhint, ERRCODE = SQLSTATE;
  END;
  has_in_edges := _pgr_checkColumn(vertices_sql, 'in_edges', 'ANY-INTEGER[]', true, dryrun => $3);
  has_out_edges := _pgr_checkColumn(vertices_sql, 'out_edges', 'ANY-INTEGER[]', true, dryrun => $3);
  IF NOT has_in_edges AND NOT has_out_edges THEN
      RAISE EXCEPTION 'column "in_edges" does not exist' USING HINT = vertices_sql, ERRCODE = 42703;
  END IF;
  IF has_in_edges THEN
    eids = $$coalesce(in_edges::BIGINT[], '{}'::BIGINT[])$$;
  END IF;
  IF has_out_edges THEN
    IF has_in_edges THEN
      eids = E'\n          ' || eids
            || E'\n          ||\n          '
            || $$coalesce(out_edges::BIGINT[], '{}'::BIGINT[])$$;
    ELSE
      eids = $$coalesce(out_edges::BIGINT[], '{}'::BIGINT[])$$;
    END IF;
  ELSE
    IF NOT has_in_edges THEN
      RAISE EXCEPTION 'Missing column'
      USING HINT = 'Column "in_edges" and/or "out_edges" is missing in'||E'\n'||vertices_sql;
    END IF;
  END IF;
  query := format($q$
    WITH
    g_edges AS (
      $q$ || edges_sql || $q$
    ),
    all_vertices AS (
      $q$ || vertices_sql || $q$
    ),
    g_vertices AS (
      SELECT id,
        unnest(%s) AS eid
      FROM all_vertices
    ),
    totals AS (
      SELECT v.id, count(*)
      FROM g_vertices v
      JOIN g_edges e ON (v.eid = e.id) GROUP BY v.id
    )
    SELECT id::BIGINT, count::BIGINT FROM all_vertices JOIN totals USING (id)
    $q$, eids);
  IF dryrun THEN
    RAISE NOTICE '%', query || ';';
  ELSE
    RETURN QUERY EXECUTE query;
  END IF;
END;
$function$
;

-- Function: pgr_degree
-- Comment: pgr_degree
- Parameters
- Edges SQL with columns: id
- Vertices SQL with columns: id, in_edges, out_edges
- Documentation:
- https://docs.pgrouting.org/latest/en/pgr_degree.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_depthfirstsearch(text, anyarray, directed boolean DEFAULT true, max_depth bigint DEFAULT '9223372036854775807'::bigint, OUT seq bigint, OUT depth bigint, OUT start_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE plpgsql
 STRICT
AS $function$
BEGIN
    IF $4 < 0 THEN
        RAISE EXCEPTION 'Negative value found on ''max_depth'''
        USING HINT = format('Value found: %s', $4);
    END IF;
    RETURN QUERY
    SELECT a.seq, a.depth, a.start_vid, a.node, a.edge, a.cost, a.agg_cost
    FROM _pgr_depthFirstSearch(_pgr_get_statement($1), $2, directed, max_depth) AS a;
END;
$function$
;

-- Function: pgr_depthfirstsearch
-- Comment: pgr_depthFirstSearch(Multiple Vertices)
- PROPOSED
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
    - From ARRAY[root vertices identifiers]
- Optional parameters
    - directed := true
    - max_depth := 9223372036854775807
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_depthFirstSearch.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_depthfirstsearch(text, bigint, directed boolean DEFAULT true, max_depth bigint DEFAULT '9223372036854775807'::bigint, OUT seq bigint, OUT depth bigint, OUT start_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE plpgsql
 STRICT
AS $function$
BEGIN
    IF $4 < 0 THEN
        RAISE EXCEPTION 'Negative value found on ''max_depth'''
        USING HINT = format('Value found: %s', $4);
    END IF;
    RETURN QUERY
    SELECT a.seq, a.depth, a.start_vid, a.node, a.edge, a.cost, a.agg_cost
    FROM _pgr_depthFirstSearch(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], directed, max_depth) AS a;
END;
$function$
;

-- Function: pgr_depthfirstsearch
-- Comment: pgr_depthFirstSearch(Single Vertex)
- PROPOSED
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
    - From root vertex identifier
- Optional parameters
    - directed := true
    - max_depth := 9223372036854775807
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_depthFirstSearch.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_dijkstra(text, anyarray, anyarray, directed boolean DEFAULT true, OUT seq integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, path_seq, start_vid, end_vid, node, edge, cost, agg_cost
    FROM _pgr_dijkstra(_pgr_get_statement($1), $2::BIGINT[], $3::BIGINT[], $4, false, true, 0, false);
$function$
;

-- Function: pgr_dijkstra
-- Comment: pgr_dijkstra(Many to Many)
- Parameters:
   - Edges SQL with columns: id, source, target, cost [,reverse_cost]
   - From ARRAY[vertices identifiers]
   - To ARRAY[vertices identifiers]
- Optional Parameters
   - directed := true
- Documentation:
   - https://docs.pgrouting.org/latest/en/pgr_dijkstra.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_dijkstra(text, anyarray, bigint, directed boolean DEFAULT true, OUT seq integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, path_seq, start_vid, end_vid, node, edge, cost, agg_cost
    FROM _pgr_dijkstra(_pgr_get_statement($1), $2::BIGINT[], ARRAY[$3]::BIGINT[], $4, false, false, 0, false);
$function$
;

-- Function: pgr_dijkstra
-- Comment: pgr_dijkstra(Many to One)
- Parameters:
   - Edges SQL with columns: id, source, target, cost [,reverse_cost]
   - From ARRAY[vertices identifiers]
   - To vertex identifier
- Optional Parameters
   - directed := true
- Documentation:
   - https://docs.pgrouting.org/latest/en/pgr_dijkstra.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_dijkstra(text, bigint, anyarray, directed boolean DEFAULT true, OUT seq integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, path_seq, start_vid, end_vid, node, edge, cost, agg_cost
    FROM _pgr_dijkstra(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], $3::BIGINT[], $4, false, true, 0, false);
$function$
;

-- Function: pgr_dijkstra
-- Comment: pgr_dijkstra(One to Many)
- Parameters:
   - Edges SQL with columns: id, source, target, cost [,reverse_cost]
   - From vertex identifier
   - To ARRAY[vertices identifiers]
- Optional Parameters
   - directed := true
- Documentation:
   - https://docs.pgrouting.org/latest/en/pgr_dijkstra.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_dijkstra(text, text, directed boolean DEFAULT true, OUT seq integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, path_seq, start_vid, end_vid, node, edge, cost, agg_cost
    FROM _pgr_dijkstra(_pgr_get_statement($1), _pgr_get_statement($2), $3, false, 0, false);
$function$
;

-- Function: pgr_dijkstra
-- Comment: pgr_dijkstra(Combinations)
- Parameters:
   - Edges SQL with columns: id, source, target, cost [,reverse_cost]
   - Combinations SQL with columns: source, target
- Optional Parameters
   - directed := true
- Documentation:
   - https://docs.pgrouting.org/latest/en/pgr_dijkstra.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_dijkstra(text, bigint, bigint, directed boolean DEFAULT true, OUT seq integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, path_seq, start_vid, end_vid, node, edge, cost, agg_cost
    FROM _pgr_dijkstra(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], ARRAY[$3]::BIGINT[], $4, false, true, 0, false);
$function$
;

-- Function: pgr_dijkstra
-- Comment: pgr_dijkstra(One to One)
- Parameters:
   - Edges SQL with columns: id, source, target, cost [,reverse_cost]
   - From vertex identifier
   - To vertex identifier
- Optional Parameters
   - directed := true
- Documentation:
   - https://docs.pgrouting.org/latest/en/pgr_dijkstra.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_dijkstracost(text, anyarray, anyarray, directed boolean DEFAULT true, OUT start_vid bigint, OUT end_vid bigint, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT start_vid, end_vid, agg_cost
    FROM _pgr_dijkstra(_pgr_get_statement($1), $2::BIGINT[], $3::BIGINT[], $4, true, true, 0, false);
$function$
;

-- Function: pgr_dijkstracost
-- Comment: pgr_dijkstraCost(Many to Many)
- Parameters:
   - Edges SQL with columns: id, source, target, cost [,reverse_cost]
   - From ARRAY[vertices identifiers]
   - To ARRAY[vertices identifiers]
- Optional Parameters
   - directed := true
- Documentation:
   - https://docs.pgrouting.org/latest/en/pgr_dijkstraCost.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_dijkstracost(text, bigint, bigint, directed boolean DEFAULT true, OUT start_vid bigint, OUT end_vid bigint, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT start_vid, end_vid, agg_cost
    FROM _pgr_dijkstra(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], ARRAY[$3]::BIGINT[], $4, true, true, 0, false);
$function$
;

-- Function: pgr_dijkstracost
-- Comment: pgr_dijkstraCost(One to One)
- Parameters:
   - Edges SQL with columns: id, source, target, cost [,reverse_cost]
   - From vertex identifier
   - To vertex identifier
- Optional Parameters
   - directed := true
- Documentation:
   - https://docs.pgrouting.org/latest/en/pgr_dijkstraCost.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_dijkstracost(text, text, directed boolean DEFAULT true, OUT start_vid bigint, OUT end_vid bigint, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT start_vid, end_vid, agg_cost
    FROM _pgr_dijkstra(_pgr_get_statement($1), _pgr_get_statement($2), $3, true, 0, false);
$function$
;

-- Function: pgr_dijkstracost
-- Comment: pgr_dijkstraCost(Combinations SQL)
- Parameters:
   - Edges SQL with columns: id, source, target, cost [,reverse_cost]
   - Combinations SQL with columns: source, target
- Optional Parameters
   - directed := true
- Documentation:
   - https://docs.pgrouting.org/latest/en/pgr_dijkstraCost.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_dijkstracost(text, bigint, anyarray, directed boolean DEFAULT true, OUT start_vid bigint, OUT end_vid bigint, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT start_vid, end_vid, agg_cost
    FROM _pgr_dijkstra(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], $3::BIGINT[], $4, true, true, 0, false);
$function$
;

-- Function: pgr_dijkstracost
-- Comment: pgr_dijkstraCost(One to Many)
- Parameters:
   - Edges SQL with columns: id, source, target, cost [,reverse_cost]
   - From vertex identifier
   - To ARRAY[vertices identifiers]
- Optional Parameters
   - directed := true
- Documentation:
   - https://docs.pgrouting.org/latest/en/pgr_dijkstraCost.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_dijkstracost(text, anyarray, bigint, directed boolean DEFAULT true, OUT start_vid bigint, OUT end_vid bigint, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT start_vid, end_vid, agg_cost
    FROM _pgr_dijkstra(_pgr_get_statement($1), $2::BIGINT[], ARRAY[$3]::BIGINT[], $4, true, true, 0, false);
$function$
;

-- Function: pgr_dijkstracost
-- Comment: pgr_dijkstraCost(Many to One)
- Parameters:
   - Edges SQL with columns: id, source, target, cost [,reverse_cost]
   - From ARRAY[vertices identifiers]
   - To vertex identifier
- Optional Parameters
   - directed := true
- Documentation:
   - https://docs.pgrouting.org/latest/en/pgr_dijkstraCost.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_dijkstracostmatrix(text, anyarray, directed boolean DEFAULT true, OUT start_vid bigint, OUT end_vid bigint, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT a.start_vid, a.end_vid, a.agg_cost
    FROM _pgr_dijkstra(_pgr_get_statement($1), $2, $2, $3, true, true, 0, false) a;
$function$
;

-- Function: pgr_dijkstracostmatrix
-- Comment: pgr_dijkstraCostMatrix
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
    - ARRAY [vertices identifiers]
- Optional Parameters
    - directed := true
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_dijkstraCostMatrix.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_dijkstranear(text, text, directed boolean DEFAULT true, cap bigint DEFAULT 1, global boolean DEFAULT true, OUT seq integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, path_seq, start_vid, end_vid, node, edge, cost, agg_cost
    FROM _pgr_dijkstra(_pgr_get_statement($1), _pgr_get_statement($2), directed, false, cap, global);
$function$
;

-- Function: pgr_dijkstranear
-- Comment: pgr_dijkstraNear(Combinations)
- PROPOSED
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - Combinations SQL with columns: source, target
- Optional Parameters
  - directed => true
  - cap => 1 (nth found)
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_dijkstraNear.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_dijkstranear(text, bigint, anyarray, directed boolean DEFAULT true, cap bigint DEFAULT 1, OUT seq integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, path_seq, start_vid, end_vid, node, edge, cost, agg_cost
    FROM _pgr_dijkstra(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], $3::BIGINT[], directed, false, true, cap, false);
$function$
;

-- Function: pgr_dijkstranear
-- Comment: pgr_dijkstraNear(One to Many)
- PROPOSED
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - From vertex identifier
  - To ARRAY[vertices identifiers]
- Optional Parameters
  - directed => true
  - cap => 1 (nth found)
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_dijkstraNear.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_dijkstranear(text, anyarray, bigint, directed boolean DEFAULT true, cap bigint DEFAULT 1, OUT seq integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, path_seq, start_vid, end_vid, node, edge, cost, agg_cost
    FROM _pgr_dijkstra(_pgr_get_statement($1), $2::BIGINT[], ARRAY[$3]::BIGINT[], directed, false, false, cap, false);
$function$
;

-- Function: pgr_dijkstranear
-- Comment: pgr_dijkstraNear(Many to One)
- PROPOSED
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - From ARRAY[vertices identifiers]
  - To vertex identifier
- Optional Parameters
  - directed => true
  - cap => 1 (nth found)
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_dijkstraNear.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_dijkstranear(text, anyarray, anyarray, directed boolean DEFAULT true, cap bigint DEFAULT 1, global boolean DEFAULT true, OUT seq integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, path_seq, start_vid, end_vid, node, edge, cost, agg_cost
    FROM _pgr_dijkstra(_pgr_get_statement($1), $2::BIGINT[], $3::BIGINT[], directed, false, true, cap, global);
$function$
;

-- Function: pgr_dijkstranear
-- Comment: pgr_dijkstraNear(Many to Many)
- PROPOSED
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - From ARRAY[vertices identifiers]
  - To ARRAY[vertices identifiers]
- Optional Parameters
  - directed => true
  - cap => 1 (nth found)
- Documentation:
   - https://docs.pgrouting.org/latest/en/pgr_dijkstraNear.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_dijkstranearcost(text, anyarray, anyarray, directed boolean DEFAULT true, cap bigint DEFAULT 1, global boolean DEFAULT true, OUT start_vid bigint, OUT end_vid bigint, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT start_vid, end_vid, agg_cost
    FROM _pgr_dijkstra(_pgr_get_statement($1), $2::BIGINT[], $3::BIGINT[], directed, true, true, cap, global);
$function$
;

-- Function: pgr_dijkstranearcost
-- Comment: pgr_dijkstraNearCost(Many to Many)
- PROPOSED
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - From ARRAY[vertices identifiers]
  - To ARRAY[vertices identifiers]
- Optional Parameters
  - directed => true
  - cap => 1 (nth found)
- Documentation:
   - https://docs.pgrouting.org/latest/en/pgr_dijkstraNearCost.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_dijkstranearcost(text, text, directed boolean DEFAULT true, cap bigint DEFAULT 1, global boolean DEFAULT true, OUT start_vid bigint, OUT end_vid bigint, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT start_vid, end_vid, agg_cost
    FROM _pgr_dijkstra(_pgr_get_statement($1), _pgr_get_statement($2), directed, true, cap, global);
$function$
;

-- Function: pgr_dijkstranearcost
-- Comment: pgr_dijkstraNearCost(Combinations)
- PROPOSED
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - Combinations SQL with columns: source, target
- Optional Parameters
  - directed => true
  - cap => 1 (nth found)
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_dijkstraNearCost.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_dijkstranearcost(text, anyarray, bigint, directed boolean DEFAULT true, cap bigint DEFAULT 1, OUT start_vid bigint, OUT end_vid bigint, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT start_vid, end_vid, agg_cost
    FROM _pgr_dijkstra(_pgr_get_statement($1), $2::BIGINT[], ARRAY[$3]::BIGINT[], directed, true, false, cap, true);
$function$
;

-- Function: pgr_dijkstranearcost
-- Comment: pgr_dijkstraNearCost(Many to One)
- PROPOSED
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - From ARRAY[vertices identifiers]
  - To vertex identifier
- Optional Parameters
  - directed => true
  - cap => 1 (nth found)
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_dijkstraNearCost.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_dijkstranearcost(text, bigint, anyarray, directed boolean DEFAULT true, cap bigint DEFAULT 1, OUT start_vid bigint, OUT end_vid bigint, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT start_vid, end_vid, agg_cost
    FROM _pgr_dijkstra(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], $3::BIGINT[], directed, true, true, cap, true);
$function$
;

-- Function: pgr_dijkstranearcost
-- Comment: pgr_dijkstraNearCost(One to Many)
- PROPOSED
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - From vertex identifier
  - To ARRAY[vertices identifiers]
- Optional Parameters
  - directed => true
  - cap => 1 (nth found)
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_dijkstraNearCost.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_dijkstravia(text, anyarray, directed boolean DEFAULT true, strict boolean DEFAULT false, u_turn_on_edge boolean DEFAULT true, OUT seq integer, OUT path_id integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision, OUT route_agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, path_id, path_seq, start_vid, end_vid, node, edge, cost, agg_cost, route_agg_cost
    FROM _pgr_dijkstraVia(_pgr_get_statement($1), $2, $3 , $4, $5);
$function$
;

-- Function: pgr_dijkstravia
-- Comment: pgr_dijkstraVia
- PROPOSED
- Parameters:
   - Edges SQL with columns: id, source, target, cost [,reverse_cost]
   - ARRAY[via vertices identifiers]
- Optional Parameters
   - directed := true
   - strict := false
   - U_turn_on_edge := true
- Documentation:
   - https://docs.pgrouting.org/latest/en/pgr_dijkstraVia.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_drivingdistance(text, anyarray, double precision, directed boolean DEFAULT true, equicost boolean DEFAULT false, OUT seq bigint, OUT depth bigint, OUT start_vid bigint, OUT pred bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, depth, start_vid, pred, node, edge, cost, agg_cost
    FROM _pgr_drivingDistancev4(_pgr_get_statement($1), $2, $3, $4, $5);
$function$
;

-- Function: pgr_drivingdistance
-- Comment: pgr_drivingDistance(Multiple vertices)
- Parameters:
   - Edges SQL with columns: id, source, target, cost [,reverse_cost]
   - From ARRAY[vertices identifiers]
   - Distance from vertices identifiers
- Optional Parameters
   - directed := true
   - equicost := false
- Documentation:
   - https://docs.pgrouting.org/latest/en/pgr_drivingDistance.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_drivingdistance(text, bigint, double precision, directed boolean DEFAULT true, OUT seq bigint, OUT depth bigint, OUT start_vid bigint, OUT pred bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, depth, start_vid, pred, node, edge, cost, agg_cost
    FROM _pgr_drivingDistancev4(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], $3, $4, false);
$function$
;

-- Function: pgr_drivingdistance
-- Comment: pgr_drivingDistance(Single_vertex)
- Parameters:
   - Edges SQL with columns: id, source, target, cost [,reverse_cost]
   - From vertex identifier
   - Distance from vertex identifier
- Optional Parameters
   - directed := true
- Documentation:
   - https://docs.pgrouting.org/latest/en/pgr_drivingDistance.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_edgecoloring(text, OUT edge_id bigint, OUT color_id bigint)
 RETURNS SETOF record
 LANGUAGE plpgsql
 STRICT
AS $function$
BEGIN
    RETURN QUERY
    SELECT a.edge_id, a.color_id
    FROM _pgr_edgeColoring(_pgr_get_statement($1)) AS a;
END;
$function$
;

-- Function: pgr_edgecoloring
-- Comment: pgr_edgeColoring
- EXPERIMENTAL
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_edgeColoring.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_edgedisjointpaths(text, text, directed boolean DEFAULT true, OUT seq integer, OUT path_id integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, path_id, path_seq, start_vid, end_vid, node, edge, cost, agg_cost
    FROM _pgr_edgeDisjointPaths(_pgr_get_statement($1), _pgr_get_statement($2), $3)
  $function$
;

-- Function: pgr_edgedisjointpaths
-- Comment: pgr_edgeDisjointPaths(Combinations)
 - Parameters:
   - Edges SQL with columns: id, source, target, cost [,reverse_cost]
   - Combinations SQL with columns: source, target
- Optional Parameters
   - directed := true
- Documentation:
   - https://docs.pgrouting.org/latest/en/pgr_edgeDisjointPaths.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_edgedisjointpaths(text, anyarray, anyarray, directed boolean DEFAULT true, OUT seq integer, OUT path_id integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
  SELECT seq, path_id, path_seq, start_vid, end_vid, node, edge, cost, agg_cost
    FROM _pgr_edgeDisjointPaths(_pgr_get_statement($1), $2::BIGINT[], $3::BIGINT[], $4);
  $function$
;

-- Function: pgr_edgedisjointpaths
-- Comment: pgr_edgeDisjointPaths(Many to Many)
 - Parameters:
   - edges SQL with columns: id, source, target, cost [,reverse_cost]
   - From ARRAY[vertices identifiers]
   - to ARRAY[vertices identifiers]
- Optional Parameters
   - directed := true
- Documentation:
   - https://docs.pgrouting.org/latest/en/pgr_edgeDisjointPaths.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_edgedisjointpaths(text, anyarray, bigint, directed boolean DEFAULT true, OUT seq integer, OUT path_id integer, OUT path_seq integer, OUT start_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, path_id, path_seq, start_vid, node, edge, cost, agg_cost
    FROM _pgr_edgeDisjointPaths(_pgr_get_statement($1), $2::BIGINT[], ARRAY[$3]::BIGINT[], $4);
  $function$
;

-- Function: pgr_edgedisjointpaths
-- Comment: pgr_edgeDisjointPaths(Many to One)
 - Parameters:
   - edges SQL with columns: id, source, target, cost [,reverse_cost]
   - From ARRAY[vertices identifiers]
   - to vertex identifier
- Optional Parameters
   - directed := true
- Documentation:
   - https://docs.pgrouting.org/latest/en/pgr_edgeDisjointPaths.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_edgedisjointpaths(text, bigint, bigint, directed boolean DEFAULT true, OUT seq integer, OUT path_id integer, OUT path_seq integer, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, path_id, path_seq, node, edge, cost, agg_cost
    From _pgr_edgeDisjointPaths(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], ARRAY[$3]::BIGINT[], $4);
  $function$
;

-- Function: pgr_edgedisjointpaths
-- Comment: pgr_edgeDisjointPaths(One to One)
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - From vertex identifier
  - to vertex identifier
- Optional Parameters
   - directed := true
- Documentation:
   - https://docs.pgrouting.org/latest/en/pgr_edgeDisjointPaths.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_edgedisjointpaths(text, bigint, anyarray, directed boolean DEFAULT true, OUT seq integer, OUT path_id integer, OUT path_seq integer, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, path_id, path_seq, end_vid, node, edge, cost, agg_cost
    FROM _pgr_edgeDisjointPaths(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], $3::BIGINT[], $4);
  $function$
;

-- Function: pgr_edgedisjointpaths
-- Comment: pgr_edgeDisjointPaths(One to Many)
 - Parameters:
   - dges SQL with columns: id, source, target, cost [,reverse_cost]
   - From vertex identifier
   - to ARRAY[vertices identifiers]
- Optional Parameters
   - directed := true
- Documentation:
   - https://docs.pgrouting.org/latest/en/pgr_edgeDisjointPaths.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_edmondskarp(text, bigint, anyarray, OUT seq integer, OUT edge bigint, OUT start_vid bigint, OUT end_vid bigint, OUT flow bigint, OUT residual_capacity bigint)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
        SELECT seq, edge_id, source, target, flow, residual_capacity
        FROM _pgr_maxflow(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], $3::BIGINT[], 3);
  $function$
;

-- Function: pgr_edmondskarp
-- Comment: pgr_edmondsKarp(One to Many)
- Directed graph
- Parameters:
  - Edges SQL with columns: id, source, target, capacity [,reverse_capacity]
  - From vertex
  - to ARRAY[vertices identifiers]
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_edmondsKarp.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_edmondskarp(text, bigint, bigint, OUT seq integer, OUT edge bigint, OUT start_vid bigint, OUT end_vid bigint, OUT flow bigint, OUT residual_capacity bigint)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
        SELECT seq, edge_id, source, target, flow, residual_capacity
        FROM _pgr_maxflow(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], ARRAY[$3]::BIGINT[], 3);
  $function$
;

-- Function: pgr_edmondskarp
-- Comment: pgr_edmondsKarp(One to One)
- Directed graph
- Parameters:
   - Edges SQL with columns: id, source, target, capacity [,reverse_capacity]
   - From vertex
   - to vertex
- Documentation:
   - https://docs.pgrouting.org/latest/en/pgr_edmondsKarp.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_edmondskarp(text, text, OUT seq integer, OUT edge bigint, OUT start_vid bigint, OUT end_vid bigint, OUT flow bigint, OUT residual_capacity bigint)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
        SELECT seq, edge_id, source, target, flow, residual_capacity
        FROM _pgr_maxflow(_pgr_get_statement($1), _pgr_get_statement($2), 3);
  $function$
;

-- Function: pgr_edmondskarp
-- Comment: pgr_edmondsKarp(Combinations)
- Directed graph
- Parameters:
  - Edges SQL with columns: id, source, target, capacity [,reverse_capacity]
  - Combinations SQL with columns: source, target
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_edmondsKarp.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_edmondskarp(text, anyarray, bigint, OUT seq integer, OUT edge bigint, OUT start_vid bigint, OUT end_vid bigint, OUT flow bigint, OUT residual_capacity bigint)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
        SELECT seq, edge_id, source, target, flow, residual_capacity
        FROM _pgr_maxflow(_pgr_get_statement($1), $2::BIGINT[], ARRAY[$3]::BIGINT[], 3);
  $function$
;

-- Function: pgr_edmondskarp
-- Comment: pgr_edmondsKarp(Many to One)
- Directed graph
- Parameters:
  - Edges SQL with columns: id, source, target, capacity [,reverse_capacity]
  - From ARRAY[vertices identifiers]
  - to vertex
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_edmondsKarp.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_edmondskarp(text, anyarray, anyarray, OUT seq integer, OUT edge bigint, OUT start_vid bigint, OUT end_vid bigint, OUT flow bigint, OUT residual_capacity bigint)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
        SELECT seq, edge_id, source, target, flow, residual_capacity
        FROM _pgr_maxflow(_pgr_get_statement($1), $2::BIGINT[], $3::BIGINT[], 3);
  $function$
;

-- Function: pgr_edmondskarp
-- Comment: pgr_edmondsKarp(Many to Many)
- Directed graph
- Parameters:
  - Edges SQL with columns: id, source, target, capacity [,reverse_capacity]
  - From ARRAY[vertices identifiers]
  - to ARRAY[vertices identifiers]
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_edmondsKarp.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_edwardmoore(text, anyarray, bigint, directed boolean DEFAULT true, OUT seq integer, OUT path_seq integer, OUT start_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT a.seq, a.path_seq, a.start_vid, a.node, a.edge, a.cost, a.agg_cost
    FROM _pgr_edwardMoore(_pgr_get_statement($1), $2::BIGINT[], ARRAY[$3]::BIGINT[], $4) AS a;
$function$
;

-- Function: pgr_edwardmoore
-- Comment: pgr_edwardMoore(Many to One)
- EXPERIMENTAL
- Parameters:
   - Edges SQL with columns: id, source, target, cost [,reverse_cost]
   - From ARRAY[vertices identifiers]
   - To vertex identifier
- Optional Parameters
   - directed := true
- Documentation:
   - https://docs.pgrouting.org/latest/en/pgr_edwardMoore.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_edwardmoore(text, text, directed boolean DEFAULT true, OUT seq integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT a.seq, a.path_seq, a.start_vid, a.end_vid, a.node, a.edge, a.cost, a.agg_cost
    FROM _pgr_edwardMoore(_pgr_get_statement($1), _pgr_get_statement($2), $3) AS a;
$function$
;

-- Function: pgr_edwardmoore
-- Comment: pgr_edwardMoore(Combinations)
- EXPERIMENTAL
- Parameters:
   - Edges SQL with columns: id, source, target, cost [,reverse_cost]
   - Combinations SQL with columns: source, target
- Optional Parameters
   - directed := true
- Documentation:
   - https://docs.pgrouting.org/latest/en/pgr_edwardMoore.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_edwardmoore(text, bigint, bigint, directed boolean DEFAULT true, OUT seq integer, OUT path_seq integer, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT a.seq, a.path_seq, a.node, a.edge, a.cost, a.agg_cost
    FROM _pgr_edwardMoore(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], ARRAY[$3]::BIGINT[], $4) AS a;
$function$
;

-- Function: pgr_edwardmoore
-- Comment: pgr_edwardMoore(One to One)
- EXPERIMENTAL
- Parameters:
   - Edges SQL with columns: id, source, target, cost [,reverse_cost]
   - From vertex identifier
   - To vertex identifier
- Optional Parameters
   - directed := true
- Documentation:
   - https://docs.pgrouting.org/latest/en/pgr_edwardMoore.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_edwardmoore(text, bigint, anyarray, directed boolean DEFAULT true, OUT seq integer, OUT path_seq integer, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT a.seq, a.path_seq, a.end_vid, a.node, a.edge, a.cost, a.agg_cost
    FROM _pgr_edwardMoore(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], $3::BIGINT[], $4) AS a;
$function$
;

-- Function: pgr_edwardmoore
-- Comment: pgr_edwardMoore(One to Many)
- EXPERIMENTAL
- Parameters:
   - Edges SQL with columns: id, source, target, cost [,reverse_cost]
   - From vertex identifier
   - To ARRAY[vertices identifiers]
- Optional Parameters
   - directed := true
- Documentation:
   - https://docs.pgrouting.org/latest/en/pgr_edwardMoore.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_edwardmoore(text, anyarray, anyarray, directed boolean DEFAULT true, OUT seq integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT a.seq, a.path_seq, a.start_vid, a.end_vid, a.node, a.edge, a.cost, a.agg_cost
    FROM _pgr_edwardMoore(_pgr_get_statement($1), $2::BIGINT[], $3::BIGINT[], $4) AS a;
$function$
;

-- Function: pgr_edwardmoore
-- Comment: pgr_edwardMoore(Many to Many)
- EXPERIMENTAL
- Parameters:
   - Edges SQL with columns: id, source, target, cost [,reverse_cost]
   - From ARRAY[vertices identifiers]
   - To ARRAY[vertices identifiers]
- Optional Parameters
   - directed := true
- Documentation:
   - https://docs.pgrouting.org/latest/en/pgr_edwardMoore.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_extractvertices(text, dryrun boolean DEFAULT false, OUT id bigint, OUT in_edges bigint[], OUT out_edges bigint[], OUT x double precision, OUT y double precision, OUT geom geometry)
 RETURNS SETOF record
 LANGUAGE plpgsql
 STRICT
AS $function$
DECLARE
    edges_SQL TEXT;
    quoted TEXT;
    query TEXT;
    has_geom BOOLEAN := TRUE;
    has_st BOOLEAN := TRUE;
    has_source BOOLEAN := TRUE;
    has_target BOOLEAN := TRUE;
    has_points BOOLEAN := TRUE;
    has_start BOOLEAN := TRUE;
    has_end BOOLEAN := TRUE;
    has_id BOOLEAN := TRUE;
    rec RECORD;
    sqlhint TEXT;
BEGIN
  BEGIN
    edges_sql := _pgr_checkQuery($1);
    EXCEPTION WHEN OTHERS THEN
      GET STACKED DIAGNOSTICS sqlhint = PG_EXCEPTION_HINT;
      RAISE EXCEPTION '%', SQLERRM USING HINT = sqlhint, ERRCODE = SQLSTATE;
  END;
  has_id := _pgr_checkColumn(edges_sql, 'id', 'ANY-INTEGER', true, dryrun => $2);
  has_source := _pgr_checkColumn(edges_sql, 'source', 'ANY-INTEGER', true, dryrun => $2);
  has_target := _pgr_checkColumn(edges_sql, 'target', 'ANY-INTEGER', true, dryrun => $2);
  has_geom := _pgr_checkColumn(edges_sql, 'geom', 'geometry', true, dryrun => $2);
  has_start := _pgr_checkColumn(edges_sql, 'startpoint', 'geometry', true, dryrun => $2);
  has_end   := _pgr_checkColumn(edges_sql, 'endpoint', 'geometry', true, dryrun => $2);
  has_points := has_start AND has_end;
  has_st := has_source AND has_target;
  IF (NOT has_geom) THEN
    IF (has_target AND NOT has_source) THEN
        RAISE EXCEPTION 'column "source" does not exist' USING HINT = $1, ERRCODE = 42703;
    ELSIF (NOT has_target AND has_source) THEN
        RAISE EXCEPTION 'column "target" does not exist' USING HINT = $1, ERRCODE = 42703;
    ELSIF (has_start AND NOT has_end) THEN
      RAISE EXCEPTION 'column "endpoint" does not exist' USING HINT = $1, ERRCODE = 42703;
    ELSIF (NOT has_start AND has_end) THEN
      RAISE EXCEPTION 'column "startpoint" does not exist' USING HINT = $1, ERRCODE = 42703;
    ELSIF (NOT has_st AND NOT has_points AND NOT has_geom) THEN
      RAISE EXCEPTION 'column "geom" does not exist' USING HINT = $1, ERRCODE = 42703;
    END IF;
  END IF;
    IF has_geom AND has_id THEN
      query := $q$
        WITH
        main_sql AS (
          $q$ || edges_sql || $q$
        ),
        the_out AS (
          SELECT id::BIGINT AS out_edge, ST_StartPoint(geom) AS geom
          FROM main_sql
        ),
        agg_out AS (
          SELECT array_agg(out_edge ORDER BY out_edge) AS out_edges, ST_x(geom) AS x, ST_Y(geom) AS y, geom
          FROM the_out
          GROUP BY geom
        ),
        the_in AS (
          SELECT id::BIGINT AS in_edge, ST_EndPoint(geom) AS geom
          FROM main_sql
        ),
        agg_in AS (
          SELECT array_agg(in_edge ORDER BY in_edge) AS in_edges, ST_x(geom) AS x, ST_Y(geom) AS y, geom
          FROM the_in
          GROUP BY geom
        ),
        the_points AS (
          SELECT in_edges, out_edges, coalesce(agg_out.geom, agg_in.geom) AS geom
          FROM agg_out
          FULL OUTER JOIN agg_in USING (x, y)
        )
        SELECT row_number() over(ORDER BY ST_X(geom), ST_Y(geom)) AS id, in_edges, out_edges, ST_X(geom), ST_Y(geom), geom
        FROM the_points$q$;
    ELSIF has_geom AND NOT has_id THEN
      query := $q$
        WITH
        main_sql AS (
          $q$ || edges_sql || $q$
        ),
        sub_main AS (
          SELECT ST_StartPoint(geom) AS startpoint, ST_EndPoint(geom) AS endpoint
          FROM main_sql
        ),
        the_out AS (
          SELECT  DISTINCT ST_X(startpoint) AS x, ST_Y(startpoint) AS y, startpoint AS geom
          FROM sub_main
        ),
        the_in AS (
            SELECT DISTINCT ST_X(endpoint) AS x, ST_Y(endpoint) AS y, endpoint AS geom
          FROM sub_main
        ),
        the_points AS (
          SELECT x, y, coalesce(the_out.geom, the_in.geom) AS geom
          FROM the_out
          FULL OUTER JOIN the_in USING (x, y)
        )
        SELECT row_number() over(ORDER BY  ST_X(geom), ST_Y(geom)) AS id, NULL::BIGINT[], NULL::BIGINT[], x, y, geom
        FROM the_points$q$;
    ELSIF has_points AND has_id THEN
      query := $q$
        WITH
        main_sql AS (
          $q$ || edges_sql || $q$
        ),
        the_out AS (
          SELECT id::BIGINT AS out_edge, startpoint AS geom
          FROM main_sql
        ),
        agg_out AS (
          SELECT array_agg(out_edge ORDER BY out_edge) AS out_edges, ST_x(geom) AS x, ST_Y(geom) AS y, geom
          FROM the_out
          GROUP BY geom
        ),
        the_in AS (
          SELECT id::BIGINT AS in_edge, endpoint AS geom
          FROM main_sql
        ),
        agg_in AS (
          SELECT array_agg(in_edge ORDER BY in_edge) AS in_edges, ST_x(geom) AS x, ST_Y(geom) AS y, geom
          FROM the_in
          GROUP BY geom
        ),
        the_points AS (
          SELECT in_edges, out_edges, coalesce(agg_out.geom, agg_in.geom) AS geom
          FROM agg_out
          FULL OUTER JOIN agg_in USING (x, y)
        )
        SELECT row_number() over(ORDER BY  ST_X(geom), ST_Y(geom)) AS id, in_edges, out_edges, ST_X(geom), ST_Y(geom), geom
        FROM the_points$q$;
    ELSIF has_points AND NOT has_id THEN
      query := $q$
        WITH
        main_sql AS (
          $q$ || edges_sql || $q$
        ),
        the_out AS (
          SELECT DISTINCT ST_X(startpoint) AS x, ST_Y(startpoint) AS y, startpoint AS geom
          FROM main_sql
        ),
        the_in AS (
            SELECT DISTINCT ST_X(endpoint) AS x, ST_Y(endpoint) AS y, endpoint AS geom
          FROM main_sql
        ),
        the_points AS (
          SELECT x, y, coalesce(the_out.geom, the_in.geom) AS geom
          FROM the_out
          FULL OUTER JOIN the_in USING (x, y)
        )
        SELECT row_number() over(ORDER BY  ST_X(geom), ST_Y(geom)) AS id, NULL::BIGINT[], NULL::BIGINT[], x, y, geom
        FROM the_points$q$;
    ELSIF has_st AND has_id THEN
      query := $q$ WITH
        main_sql AS (
          $q$ || edges_sql || $q$
        ),
        agg_out AS (
          SELECT source AS vid, array_agg(id::BIGINT) AS out_edges
          FROM main_sql
          GROUP BY source
        ),
        agg_in AS (
          SELECT target AS vid, array_agg(id::BIGINT) AS in_edges
          FROM main_sql
          GROUP BY target
        ),
        the_points AS (
          SELECT vid, in_edges, out_edges
          FROM agg_out
          FULL OUTER JOIN agg_in USING (vid)
        )
        SELECT vid::BIGINT AS id, in_edges, out_edges, NULL::FLOAT, NULL::FLOAT, NULL::geometry
        FROM the_points$q$;
    ELSIF has_st AND NOT has_id THEN
      query := $q$
        WITH
        main_sql AS (
          $q$ || edges_sql || $q$
        ),
        the_points AS (
          SELECT source AS vid FROM main_sql
          UNION
          SELECT target FROM main_sql
        )
        SELECT DISTINCT vid::BIGINT AS id, NULL::BIGINT[], NULL::BIGINT[], NULL::FLOAT, NULL::FLOAT, NULL::geometry
        FROM the_points$q$;
    END IF;
    IF dryrun THEN
      RAISE NOTICE '%', query || ';';
    ELSE
      RETURN QUERY EXECUTE query;
    END IF;
END;
$function$
;

-- Function: pgr_extractvertices
-- Comment: pgr_extractVertices
- Parameters
  - Edges SQL with columns: [id,] startpoint, endpoint
        OR
  - Edges SQL with columns: [id,] source, target
        OR
  - Edges SQL with columns: [id,] geom
- Documentation:
- https://docs.pgrouting.org/latest/en/pgr_extractVertices.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_findcloseedges(text, geometry[], double precision, cap integer DEFAULT 1, dryrun boolean DEFAULT false, OUT edge_id bigint, OUT fraction double precision, OUT side character, OUT distance double precision, OUT geom geometry, OUT edge geometry)
 RETURNS SETOF record
 LANGUAGE plpgsql
 STRICT COST 5
AS $function$
DECLARE
  geom_arr geometry[] := $2;
  tolerance FLOAT := $3;
  cap INTEGER := $4;
  dryrun BOOLEAN := $5;
  edges_SQL TEXT;
  has_id BOOLEAN;
  has_geom BOOLEAN;
  ret_query TEXT;
  ret_query_end TEXT;

  sqlhint TEXT;

BEGIN

  IF (tolerance < 0) THEN
    RAISE EXCEPTION 'Invalid value for "tolerance"';
  END IF;

  IF (cap < 0) THEN
    RAISE EXCEPTION 'Invalid value for "cap"';
  END IF;

  BEGIN
    edges_sql := _pgr_checkQuery($1);
    has_id := _pgr_checkColumn(edges_sql, 'id', 'ANY-INTEGER', false, dryrun => dryrun);
    has_geom := _pgr_checkColumn(edges_sql, 'geom', 'geometry', false, dryrun => dryrun);
    EXCEPTION WHEN OTHERS THEN
      GET STACKED DIAGNOSTICS sqlhint = PG_EXCEPTION_HINT;
      RAISE EXCEPTION '%', SQLERRM USING HINT = sqlhint, ERRCODE = SQLSTATE;
  END;

  ret_query = format(
    $q$
WITH
edges_sql AS (%1$s),
point_sql AS (SELECT unnest(%2$L::geometry[]) AS point),
results AS (
  SELECT
    id::BIGINT AS edge_id,
    ST_LineLocatePoint(geom, point) AS fraction,
    CASE WHEN ST_Intersects(ST_Buffer(geom, %3$s, 'side=right endcap=flat'), point)
         THEN 'r'
         ELSE 'l' END::CHAR AS side,
    geom <-> point AS distance,
    point,
    $q$, edges_sql, geom_arr, tolerance);

  ret_query_end = format(
    $q$
  FROM  edges_sql, point_sql
  WHERE ST_DWithin(geom, point, %1$s)
  ORDER BY geom <-> point),
prepare_cap AS (
  SELECT row_number() OVER (PARTITION BY point ORDER BY point, distance) AS rn, *
  FROM results)
SELECT edge_id, fraction, side, distance, point, new_line
FROM prepare_cap
WHERE rn <= %2$s
    $q$, tolerance, cap);

    ret_query = ret_query
      || $q$ST_MakeLine(point, ST_ClosestPoint(geom, point)) AS new_line $q$
      || ret_query_end;

  IF dryrun THEN
    RAISE NOTICE '%', ret_query;
    RETURN;
  END IF;

  RETURN query EXECUTE ret_query;

END;
$function$
;

-- Function: pgr_findcloseedges
-- Comment: pgr_findCloseEdges(Many Points)
- Parameters:
  - Edges SQL with columns: id, geom
  - Array of POINT geometries
  - Maximum separation between geometries
- Optional Parameters
  - cap => 1: at most one answer
  - dryrun => false: do not output code
- Documentation:
   - https://docs.pgrouting.org/latest/en/pgr_findCloseEdges.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_findcloseedges(text, geometry, double precision, cap integer DEFAULT 1, dryrun boolean DEFAULT false, OUT edge_id bigint, OUT fraction double precision, OUT side character, OUT distance double precision, OUT geom geometry, OUT edge geometry)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT COST 5
AS $function$
  SELECT edge_id, fraction, side, distance, geom, edge
  FROM pgr_findCloseEdges($1, ARRAY[$2]::GEOMETRY[], $3, cap, dryrun);
$function$
;

-- Function: pgr_findcloseedges
-- Comment: pgr_findCloseEdges(One Point)
- Parameters:
  - Edges SQL with columns: id, geom
  - POINT geometry
  - Maximum separation between geometries
- Optional Parameters
  - cap => 1: at most one answer
  - dryrun => false: do not output code
- Documentation:
   - https://docs.pgrouting.org/latest/en/pgr_findCloseEdges.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_findcloseedges(text, geometry, double precision, cap integer, partial boolean, dryrun boolean, OUT edge_id bigint, OUT fraction double precision, OUT side character, OUT distance double precision, OUT geom geometry, OUT edge geometry)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT COST 5
AS $function$
  SELECT edge_id, fraction, side, distance, geom, edge
  FROM pgr_findCloseEdges($1, ARRAY[$2]::GEOMETRY[], $3, cap, dryrun);
$function$
;

-- Function: pgr_findcloseedges
-- Comment: pgr_findCloseEdges deprecated signature on v3.8.0
-- 
CREATE OR REPLACE FUNCTION public.pgr_findcloseedges(text, geometry[], double precision, cap integer, partial boolean, dryrun boolean, OUT edge_id bigint, OUT fraction double precision, OUT side character, OUT distance double precision, OUT geom geometry, OUT edge geometry)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT COST 5
AS $function$
  SELECT edge_id, fraction, side, distance, geom, edge
  FROM pgr_findCloseEdges($1, $2, $3, cap, dryrun);
$function$
;

-- Function: pgr_findcloseedges
-- Comment: pgr_findCloseEdges deprecated signature on v3.8.0
-- 
CREATE OR REPLACE FUNCTION public.pgr_floydwarshall(text, directed boolean DEFAULT true, OUT start_vid bigint, OUT end_vid bigint, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$

    SELECT start_vid, end_vid, agg_cost
    FROM _pgr_floydWarshall(_pgr_get_statement($1), $2);

$function$
;

-- Function: pgr_floydwarshall
-- Comment: pgr_floydWarshall
- Parameters:
    - edges SQL with columns: source, target, cost [,reverse_cost])
- Optional Parameters:
    - directed := true
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_floydWarshall.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_full_version(OUT version text, OUT build_type text, OUT compile_date text, OUT library text, OUT system text, OUT postgresql text, OUT compiler text, OUT boost text, OUT hash text)
 RETURNS record
 LANGUAGE sql
 IMMUTABLE
AS $function$
    SELECT pgr_version(),
        _pgr_build_type(),
        _pgr_compilation_date(),
        _pgr_lib_version(),
        _pgr_operating_system(),
        _pgr_pgsql_version(),
        _pgr_compiler_version(),
        _pgr_boost_version(),
        _pgr_git_hash()
$function$
;

-- Function: pgr_full_version
-- Comment: pgr_full_version
- Documentation
  - https://docs.pgrouting.org/latest/en/pgr_full_version.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_hawickcircuits(text, OUT seq integer, OUT path_id integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE plpgsql
 STRICT
AS $function$
BEGIN
    RETURN QUERY
    SELECT a.seq, a.path_id, a.path_seq, a.start_vid, a.end_vid, a.node, a.edge, a.cost, a.agg_cost
    FROM _pgr_hawickCircuits(_pgr_get_statement($1)) AS a;
END;
$function$
;

-- Function: pgr_hawickcircuits
-- Comment: pgr_hawickCircuits
- EXPERIMENTAL
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_hawickCircuits.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_isplanar(text)
 RETURNS boolean
 LANGUAGE sql
 STRICT
AS $function$
    SELECT _pgr_isPlanar(_pgr_get_statement($1));
$function$
;

-- Function: pgr_isplanar
-- Comment: pgr_isPlanar
- EXPERIMENTAL
- Undirected graph
- Parameters:
  - edges SQL with columns: id, source, target, cost [,reverse_cost]
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_isPlanar.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_johnson(text, directed boolean DEFAULT true, OUT start_vid bigint, OUT end_vid bigint, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$

    SELECT start_vid, end_vid, agg_cost
    FROM _pgr_johnson(_pgr_get_statement($1), $2);

$function$
;

-- Function: pgr_johnson
-- Comment: pgr_johnson
- Parameters:
    - edges SQL with columns: source, target, cost [,reverse_cost])
- Optional Parameters:
    - directed := true
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_johnson.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_kruskal(text, OUT edge bigint, OUT cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT edge, cost
    FROM _pgr_kruskalv4(_pgr_get_statement($1), ARRAY[0]::BIGINT[], '', -1, -1);
$function$
;

-- Function: pgr_kruskal
-- Comment: pgr_kruskal
- Undirected graph
- Parameters:
	- Edges SQL with columns: id, source, target, cost [,reverse_cost]
- Documentation:
	- https://docs.pgrouting.org/latest/en/pgr_kruskal.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_kruskalbfs(text, bigint, max_depth bigint DEFAULT '9223372036854775807'::bigint, OUT seq bigint, OUT depth bigint, OUT start_vid bigint, OUT pred bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, depth, start_vid, pred, node, edge, cost, agg_cost
    FROM _pgr_kruskalv4(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], 'BFS', $3, -1);
$function$
;

-- Function: pgr_kruskalbfs
-- Comment: pgr_kruskalBFS(Single Vertex)
- Undirected graph
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
    - From root vertex identifier
- Optional parameters
    - max_depth: default := 9223372036854775807
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_kruskalBFS.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_kruskalbfs(text, anyarray, max_depth bigint DEFAULT '9223372036854775807'::bigint, OUT seq bigint, OUT depth bigint, OUT start_vid bigint, OUT pred bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, depth, start_vid, pred, node, edge, cost, agg_cost
    FROM _pgr_kruskalv4(_pgr_get_statement($1), $2, 'BFS', $3, -1);
$function$
;

-- Function: pgr_kruskalbfs
-- Comment: pgr_kruskalBFS(multiple Vertices)
- Undirected graph
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
    - From ARRAY[root vertices identifiers]
- Optional parameters
    - max_depth: default := 9223372036854775807
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_kruskalBFS.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_kruskaldd(text, anyarray, double precision, OUT seq bigint, OUT depth bigint, OUT start_vid bigint, OUT pred bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, depth, start_vid, pred, node, edge, cost, agg_cost
    FROM _pgr_kruskalv4(_pgr_get_statement($1), $2, 'DD', -1, $3::FLOAT);
$function$
;

-- Function: pgr_kruskaldd
-- Comment: pgr_kruskalDD(Multiple Vertices)
- Undirected graph
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
    - From ARRAY[root vertices identifiers]
    - Distance
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_kruskalDD.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_kruskaldd(text, bigint, double precision, OUT seq bigint, OUT depth bigint, OUT start_vid bigint, OUT pred bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, depth, start_vid, pred, node, edge, cost, agg_cost
    FROM _pgr_kruskalv4(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], 'DD', -1, $3::FLOAT);
$function$
;

-- Function: pgr_kruskaldd
-- Comment: pgr_kruskalDD(Single Vertex)
- Undirected graph
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
    - From root vertex identifier
    - Distance
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_kruskalDD.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_kruskaldd(text, anyarray, numeric, OUT seq bigint, OUT depth bigint, OUT start_vid bigint, OUT pred bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, depth, start_vid, pred, node, edge, cost, agg_cost
    FROM _pgr_kruskalv4(_pgr_get_statement($1), $2, 'DD', -1, $3);
$function$
;

-- Function: pgr_kruskaldd
-- Comment: pgr_kruskalDD(Multiple Vertices)
- Undirected graph
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
    - From ARRAY[root vertices identifiers]
    - Distance
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_kruskalDD.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_kruskaldd(text, bigint, numeric, OUT seq bigint, OUT depth bigint, OUT start_vid bigint, OUT pred bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, depth, start_vid, pred, node, edge, cost, agg_cost
    FROM _pgr_kruskalv4(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], 'DD', -1, $3::FLOAT);
$function$
;

-- Function: pgr_kruskaldd
-- Comment: pgr_kruskalDD(Single Vertex)
- Undirected graph
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
    - From root vertex identifier
    - Distance
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_kruskalDD.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_kruskaldfs(text, anyarray, max_depth bigint DEFAULT '9223372036854775807'::bigint, OUT seq bigint, OUT depth bigint, OUT start_vid bigint, OUT pred bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, depth, start_vid, pred, node, edge, cost, agg_cost
    FROM _pgr_kruskalv4(_pgr_get_statement($1), $2, 'DFS', $3, -1);
$function$
;

-- Function: pgr_kruskaldfs
-- Comment: pgr_kruskalDFS(Multiple Vertices)
- Undirected graph
- Parameters:
  - edges SQL with columns: id, source, target, cost [,reverse_cost]
  - from ARRAY[root vertices identifiers]
- Optional parameters
  - max_depth: default 9223372036854775807
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_kruskalDFS.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_kruskaldfs(text, bigint, max_depth bigint DEFAULT '9223372036854775807'::bigint, OUT seq bigint, OUT depth bigint, OUT start_vid bigint, OUT pred bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, depth, start_vid, pred, node, edge, cost, agg_cost
    FROM _pgr_kruskalv4(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], 'DFS', $3, -1);
$function$
;

-- Function: pgr_kruskaldfs
-- Comment: pgr_kruskalDFS(Single Vertex)
- Undirected graph
- Parameters:
  - edges SQL with columns: id, source, target, cost [,reverse_cost]
  - from root vertex identifier
- Optional parameters
  - max_depth: default 9223372036854775807
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_kruskalDFS.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_ksp(text, anyarray, anyarray, integer, directed boolean DEFAULT true, heap_paths boolean DEFAULT false, OUT seq integer, OUT path_id integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, path_id, path_seq, start_vid, end_vid, node, edge, cost, agg_cost
    FROM  _pgr_ksp(_pgr_get_statement($1), $2::BIGINT[], $3::BIGINT[], $4, $5, $6, true);
$function$
;

-- Function: pgr_ksp
-- Comment: pgr_KSP(Many to Many)
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
    - From ARRAY[vertex identifier]
    - To ARRAY[vertex identifier]
    - K
- Optional Parameters
    - directed := true
    - heap_paths := false
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_KSP.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_ksp(text, text, integer, directed boolean DEFAULT true, heap_paths boolean DEFAULT false, OUT seq integer, OUT path_id integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, path_id, path_seq, start_vid, end_vid, node, edge, cost, agg_cost
    FROM  _pgr_ksp(_pgr_get_statement($1), _pgr_get_statement($2), $3, $4, $5);
$function$
;

-- Function: pgr_ksp
-- Comment: pgr_KSP(Combinations)
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
    - Combinations SQL with columns: source, target
    - K
- Optional Parameters
    - directed := true
    - heap_paths := false
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_KSP.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_ksp(text, anyarray, bigint, integer, directed boolean DEFAULT true, heap_paths boolean DEFAULT false, OUT seq integer, OUT path_id integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, path_id, path_seq, start_vid, end_vid, node, edge, cost, agg_cost
    FROM  _pgr_ksp(_pgr_get_statement($1), $2::BIGINT[], ARRAY[$3]::BIGINT[], $4, $5, $6, true);
$function$
;

-- Function: pgr_ksp
-- Comment: pgr_KSP(Many to One)
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
    - From ARRAY[vertex identifier]
    - To vertex identifier
    - K
- Optional Parameters
    - directed := true
    - heap_paths := false
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_KSP.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_ksp(text, bigint, anyarray, integer, directed boolean DEFAULT true, heap_paths boolean DEFAULT false, OUT seq integer, OUT path_id integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, path_id, path_seq, start_vid, end_vid, node, edge, cost, agg_cost
    FROM  _pgr_ksp(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], $3::BIGINT[], $4, $5, $6, true);
$function$
;

-- Function: pgr_ksp
-- Comment: pgr_KSP(One to Many)
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
    - From vertex identifier
    - To ARRAY[vertex identifier]
    - K
- Optional Parameters
    - directed := true
    - heap_paths := false
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_KSP.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_ksp(text, bigint, bigint, integer, directed boolean DEFAULT true, heap_paths boolean DEFAULT false, OUT seq integer, OUT path_id integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, path_id, path_seq, start_vid, end_vid, node, edge, cost, agg_cost
    FROM _pgr_ksp(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], ARRAY[$3]::BIGINT[], $4, $5, $6, true);
$function$
;

-- Function: pgr_ksp
-- Comment: pgr_KSP
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
    - From vertex identifier
    - To vertex identifier
    - K
- Optional Parameters
    - directed := true
    - heap_paths := false
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_KSP.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_lengauertarjandominatortree(text, bigint, OUT seq integer, OUT vertex_id bigint, OUT idom bigint)
 RETURNS SETOF record
 LANGUAGE plpgsql
 STRICT
AS $function$
BEGIN

    RETURN QUERY
    SELECT a.seq, vid, a.idom
    FROM _pgr_lengauerTarjanDominatorTree(_pgr_get_statement($1),$2) AS a;
END;
$function$
;

-- Function: pgr_lengauertarjandominatortree
-- Comment: pgr_lengauerTarjanDominatorTree
- EXPERIMENTAL
- Directed graph
- Parameters:
  - edges SQL with columns: id, source, target, cost [,reverse_cost]
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_lengauerTarjanDominatorTree.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_linegraph(text, directed boolean DEFAULT true, OUT seq integer, OUT source bigint, OUT target bigint, OUT cost double precision, OUT reverse_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, source, target, cost, reverse_cost
    FROM _pgr_lineGraph(_pgr_get_statement($1), $2)
$function$
;

-- Function: pgr_linegraph
-- Comment: pgr_lineGraph
- PROPOSED
- Parameters:
  - edges SQL with columns: id, source, target, cost [,reverse_cost]
- Optional Parameters:
  - directed := true
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_lineGraph.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_linegraphfull(text, OUT seq integer, OUT source bigint, OUT target bigint, OUT cost double precision, OUT edge bigint)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, source, target, cost, edge
    FROM _pgr_lineGraphFull(_pgr_get_statement($1))
$function$
;

-- Function: pgr_linegraphfull
-- Comment: pgr_lineGraphFull
- EXPERIMENTAL
- For Directed Graph
- Parameters:
  - edges SQL with columns: id, source, target, cost [,reverse_cost]
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_lineGraphFull.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_makeconnected(text, OUT seq bigint, OUT start_vid bigint, OUT end_vid bigint)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, start_vid, end_vid
    FROM _pgr_makeConnected(_pgr_get_statement($1));
$function$
;

-- Function: pgr_makeconnected
-- Comment: pgr_makeConnected
- EXPERIMENTAL
- Undirected graph
- Parameters:
  - edges SQL with columns: id, source, target, cost [,reverse_cost]
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_makeConnected.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_maxcardinalitymatch(text, OUT edge bigint)
 RETURNS SETOF bigint
 LANGUAGE sql
 STRICT
AS $function$
SELECT edge
FROM _pgr_maxCardinalityMatch(_pgr_get_statement($1), false)
$function$
;

-- Function: pgr_maxcardinalitymatch
-- Comment: pgr_maxCardinalityMatch
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_maxCardinalityMatch.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_maxcardinalitymatch(text, directed boolean, OUT seq integer, OUT edge bigint, OUT source bigint, OUT target bigint)
 RETURNS SETOF record
 LANGUAGE plpgsql
 STRICT
AS $function$
BEGIN
RAISE WARNING 'pgr_maxCardinalityMatch(text,boolean) deprecated signature on v3.4.0';
RETURN QUERY SELECT a.seq, a.edge, a.source, a.target
FROM _pgr_maxCardinalityMatch(_pgr_get_statement($1), $2) AS a;
END
$function$
;

-- Function: pgr_maxcardinalitymatch
-- Comment: pgr_maxCardinalityMatch deprecated signature on v3.4.0
- Documentation: https://docs.pgrouting.org/latest/en/pgr_maxCardinalityMatch.html
-- 
CREATE OR REPLACE FUNCTION public.pgr_maxflow(text, text)
 RETURNS bigint
 LANGUAGE sql
 STRICT
AS $function$
        SELECT flow
        FROM _pgr_maxflow(_pgr_get_statement($1), _pgr_get_statement($2), algorithm := 1, only_flow := true);
  $function$
;

-- Function: pgr_maxflow
-- Comment: pgr_maxFlow(Combinations)
- Directed graph
- Parameters:
  - Edges SQL with columns: id, source, target, capacity [,reverse_capacity]
  - Combinations SQL with columns: source, target
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_maxFlow.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_maxflow(text, bigint, anyarray)
 RETURNS bigint
 LANGUAGE sql
 STRICT
AS $function$
        SELECT flow
        FROM _pgr_maxflow(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], $3::BIGINT[], algorithm := 1, only_flow := true);
  $function$
;

-- Function: pgr_maxflow
-- Comment: pgr_maxFlow(One to Many)
- Directed graph
- Parameters:
  - edges SQL with columns: id, source, target, capacity [,reverse_capacity]
  - from vertex
  - to ARRAY[vertices identifiers]
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_maxFlow.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_maxflow(text, bigint, bigint)
 RETURNS bigint
 LANGUAGE sql
 STRICT
AS $function$
        SELECT flow
        FROM _pgr_maxflow(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], ARRAY[$3]::BIGINT[], algorithm := 1, only_flow := true);
  $function$
;

-- Function: pgr_maxflow
-- Comment: pgr_maxFlow(One to One)
- Directed graph
- Parameters:
  - edges SQL with columns: id, source, target, capacity [,reverse_capacity]
  - from vertex
  - to vertex
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_maxFlow.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_maxflow(text, anyarray, bigint)
 RETURNS bigint
 LANGUAGE sql
 STRICT
AS $function$
        SELECT flow
        FROM _pgr_maxflow(_pgr_get_statement($1), $2::BIGINT[], ARRAY[$3]::BIGINT[], algorithm := 1, only_flow := true);
  $function$
;

-- Function: pgr_maxflow
-- Comment: pgr_maxFlow(Many to One)
- Directed graph
- Parameters:
  - edges SQL with columns: id, source, target, capacity [,reverse_capacity]
  - from ARRAY[vertices identifiers]
  - to vertex
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_maxFlow.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_maxflow(text, anyarray, anyarray)
 RETURNS bigint
 LANGUAGE sql
 STRICT
AS $function$
        SELECT flow
        FROM _pgr_maxflow(_pgr_get_statement($1), $2::BIGINT[], $3::BIGINT[], algorithm := 1, only_flow := true);
  $function$
;

-- Function: pgr_maxflow
-- Comment: pgr_maxFlow(Many to Many)
- Directed graph
- Parameters:
  - edges SQL with columns: id, source, target, capacity [,reverse_capacity]
  - from ARRAY[vertices identifiers]
  - to ARRAY[vertices identifiers]
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_maxFlow.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_maxflowmincost(text, anyarray, bigint, OUT seq integer, OUT edge bigint, OUT source bigint, OUT target bigint, OUT flow bigint, OUT residual_capacity bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, edge, source, target, flow, residual_capacity, cost, agg_cost
    FROM _pgr_maxFlowMinCost(_pgr_get_statement($1), $2::BIGINT[], ARRAY[$3]::BIGINT[], only_cost := false);
$function$
;

-- Function: pgr_maxflowmincost
-- Comment: pgr_maxFlowMinCost(Many to One)
- EXPERIMENTAL
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - From ARRAY[vertices identifiers]vertex identifier
  - To vertex identifier
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_maxFlowMinCost.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_maxflowmincost(text, bigint, anyarray, OUT seq integer, OUT edge bigint, OUT source bigint, OUT target bigint, OUT flow bigint, OUT residual_capacity bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, edge, source, target, flow, residual_capacity, cost, agg_cost
    FROM _pgr_maxFlowMinCost(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], $3::BIGINT[], only_cost := false);
$function$
;

-- Function: pgr_maxflowmincost
-- Comment: pgr_maxFlowMinCost(One to Many)
- EXPERIMENTAL
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - From vertex identifier
  - To ARRAY[vertices identifiers]
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_maxFlowMinCost.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_maxflowmincost(text, text, OUT seq integer, OUT edge bigint, OUT source bigint, OUT target bigint, OUT flow bigint, OUT residual_capacity bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, edge, source, target, flow, residual_capacity, cost, agg_cost
    FROM _pgr_maxFlowMinCost(_pgr_get_statement($1), _pgr_get_statement($2), only_cost := false);
$function$
;

-- Function: pgr_maxflowmincost
-- Comment: pgr_maxFlowMinCost(Combinations)
- EXPERIMENTAL
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - Combinations SQL with columns: source, target
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_maxFlowMinCost.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_maxflowmincost(text, anyarray, anyarray, OUT seq integer, OUT edge bigint, OUT source bigint, OUT target bigint, OUT flow bigint, OUT residual_capacity bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, edge, source, target, flow, residual_capacity, cost, agg_cost
    FROM _pgr_maxFlowMinCost(_pgr_get_statement($1), $2::BIGINT[], $3::BIGINT[], only_cost := false);
$function$
;

-- Function: pgr_maxflowmincost
-- Comment: pgr_maxFlowMinCost(Many to Many)
- EXPERIMENTAL
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - From ARRAY[vertices identifiers]
  - To ARRAY[vertices identifiers]
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_maxFlowMinCost.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_maxflowmincost(text, bigint, bigint, OUT seq integer, OUT edge bigint, OUT source bigint, OUT target bigint, OUT flow bigint, OUT residual_capacity bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, edge, source, target, flow, residual_capacity, cost, agg_cost
    FROM _pgr_maxFlowMinCost(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], ARRAY[$3]::BIGINT[], only_cost := false);
$function$
;

-- Function: pgr_maxflowmincost
-- Comment: pgr_maxFlowMinCost(One to One)
- EXPERIMENTAL
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - From vertex identifier
  - To vertex identifier
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_maxFlowMinCost.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_maxflowmincost_cost(text, anyarray, anyarray)
 RETURNS double precision
 LANGUAGE sql
 STRICT
AS $function$
    SELECT cost
    FROM _pgr_maxFlowMinCost(_pgr_get_statement($1), $2::BIGINT[], $3::BIGINT[], only_cost := true);
$function$
;

-- Function: pgr_maxflowmincost_cost
-- Comment: pgr_maxFlowMinCost_Cost (Many to Many)
- EXPERIMENTAL
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - From ARRAY[vertices identifiers]
  - To ARRAY[vertices identifiers]
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_maxFlowMinCost_Cost.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_maxflowmincost_cost(text, anyarray, bigint)
 RETURNS double precision
 LANGUAGE sql
 STRICT
AS $function$
    SELECT cost
    FROM _pgr_maxFlowMinCost(_pgr_get_statement($1), $2::BIGINT[], ARRAY[$3]::BIGINT[], only_cost := true);
$function$
;

-- Function: pgr_maxflowmincost_cost
-- Comment: pgr_maxFlowMinCost_Cost (Many to One)
- EXPERIMENTAL
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - From ARRAY[vertices identifiers]
  - To vertex identifier
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_maxFlowMinCost_Cost.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_maxflowmincost_cost(text, bigint, bigint)
 RETURNS double precision
 LANGUAGE sql
 STRICT
AS $function$
    SELECT cost
    FROM _pgr_maxFlowMinCost(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], ARRAY[$3]::BIGINT[], only_cost := true);
$function$
;

-- Function: pgr_maxflowmincost_cost
-- Comment: pgr_maxFlowMinCost_Cost (One to One)
- EXPERIMENTAL
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - From vertex identifier
  - To vertex identifier
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_maxFlowMinCost_Cost.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_maxflowmincost_cost(text, bigint, anyarray)
 RETURNS double precision
 LANGUAGE sql
 STRICT
AS $function$
    SELECT cost
    FROM _pgr_maxFlowMinCost(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], $3::BIGINT[], only_cost := true);
$function$
;

-- Function: pgr_maxflowmincost_cost
-- Comment: pgr_maxFlowMinCost_Cost(One to Many)
- EXPERIMENTAL
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - From vertex identifier
  - To ARRAY[vertices identifiers]
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_maxFlowMinCost_Cost.html
  
-- 
CREATE OR REPLACE FUNCTION public.pgr_maxflowmincost_cost(text, text)
 RETURNS double precision
 LANGUAGE sql
 STRICT
AS $function$
    SELECT cost
    FROM _pgr_maxFlowMinCost(_pgr_get_statement($1), _pgr_get_statement($2), only_cost := true);
$function$
;

-- Function: pgr_maxflowmincost_cost
-- Comment: pgr_maxFlowMinCost_Cost (Combinations)
- EXPERIMENTAL
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - Combinations SQL with columns: source, target
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_maxFlowMinCost_Cost.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_nodenetwork(text, double precision, id text DEFAULT 'id'::text, the_geom text DEFAULT 'the_geom'::text, table_ending text DEFAULT 'noded'::text, rows_where text DEFAULT ''::text, outall boolean DEFAULT false)
 RETURNS text
 LANGUAGE plpgsql
 STRICT
AS $function$
DECLARE
  
  sname TEXT;  -- schema of tables
  tname TEXT;  -- in table name
  oname TEXT;  -- out table name

  sridinfo record;
  splits BIGINT := 0;
  touched BIGINT := 0;
  untouched BIGINT := 0;
  geomtype TEXT;
  debuglevel TEXT;
  rows_where_out TEXT;

  the_query TEXT;
  the_out_query TEXT;
  the_table TEXT[];
  sqlhint TEXT;
  out_table_exists BOOLEAN;

BEGIN
  RAISE WARNING 'pgr_nodenetwork(text,double precision,text,text,text,text,boolean) deprecated function on v3.8.0';
  RAISE NOTICE 'PROCESSING:';
  RAISE NOTICE 'id: %', id;
  RAISE NOTICE 'the_geom: %', the_geom;
  RAISE NOTICE 'table_ending: %', table_ending;
  RAISE NOTICE 'rows_where: %', rows_where;
  RAISE NOTICE 'outall: %', outall;
  RAISE NOTICE 'pgr_nodeNetwork(''%'', %, ''%'', ''%'', ''%'', ''%'',  %)',
    $1, $2, id,  the_geom, table_ending, rows_where, outall;
  RAISE NOTICE 'Performing checks, please wait .....';
  EXECUTE 'SHOW client_min_messages' INTO debuglevel;

  the_table := parse_ident($1);

  IF array_length(the_table,1) = 1 THEN
    the_table[2] := the_table[1];
    the_table[1] := (SELECT current_schema);
  END IF;

  sname := the_table[1];
  tname := the_table[2];
  oname := the_table[2] || '_' || table_ending;

  rows_where_out = CASE WHEN length(rows_where) > 2 AND NOT outall THEN ' AND (' || rows_where || ')' ELSE '' END;
  rows_where = CASE WHEN length(rows_where) > 2 THEN rows_where ELSE 'true' END;

  -- building query
  BEGIN
    the_query := format(
      $$
      SELECT %s AS id, %s AS the_geom, ST_SRID(%s) AS srid FROM %I.%I WHERE (%s)
      $$,
      id, the_geom, the_geom, sname, tname, rows_where);
    RAISE DEBUG 'Checking: %',the_query;
    the_query := _pgr_checkQuery(the_query);

    EXECUTE format($$SELECT geometrytype(%s) FROM %I.%I limit 1$$, the_geom, sname, tname) INTO geomtype;
    IF geomtype IS NULL THEN
      RAISE WARNING '-------> Table %.% must contain invalid geometries',sname, tname;
      RETURN 'FAIL';
    END IF;

    EXCEPTION WHEN OTHERS THEN
      GET STACKED DIAGNOSTICS sqlhint = PG_EXCEPTION_HINT;
      RAISE EXCEPTION '%', SQLERRM USING HINT = sqlhint, ERRCODE = SQLSTATE;
  END;

  -- checking query columns
  BEGIN
    RAISE DEBUG 'Checking %', $1;

    IF NOT _pgr_checkColumn(the_query, 'id', 'ANY-INTEGER', true) THEN
      RAISE NOTICE  'ERROR: id column "%"  NOT found IN %.%', id, sname, tname;
      RETURN 'FAIL';
    END IF;

    IF NOT _pgr_checkColumn(the_query, 'the_geom', 'geometry', true) THEN
      RAISE NOTICE  'ERROR: the_geom  column "%"  NOT found IN %.%', the_geom, sname, tname;
      RETURN 'FAIL';
    END IF;

    EXECUTE the_query || ' LIMIT 1' INTO sridinfo;

    IF sridinfo IS NULL OR sridinfo.srid IS NULL THEN
      RAISE NOTICE 'ERROR: Can NOT determine the srid of the geometry "%" IN table %.%', the_geom, sname, tname;
      RETURN 'FAIL';
    END IF;
    RAISE DEBUG '  -----> SRID found %', sridinfo.srid;
    EXCEPTION WHEN OTHERS THEN
      RAISE NOTICE 'ERROR: Can NOT determine the srid of the geometry "%" IN table %.%', the_geom, sname, tname;
      RETURN 'FAIL';
  END;

---------------
  -- building query to check if table_noded exists
  BEGIN
    the_out_query := format(
      $$
      SELECT id, old_id, sub_id, source, target, %s FROM %I.%I LIMIT 1
      $$,
      the_geom, sname, oname);

    the_out_query := _pgr_checkQuery(the_out_query);
    out_table_exists := true;

    EXCEPTION WHEN OTHERS THEN
      out_table_exists := false;
  END;

---------------
  BEGIN
    RAISE DEBUG 'initializing %.%', sname, oname;
    IF out_table_exists THEN
      EXECUTE format(
        $$TRUNCATE TABLE %I.%I RESTART IDENTITY$$,
        sname, oname);
    ELSE
      SET client_min_messages TO warning;
      EXECUTE format('CREATE TABLE %I.%I (
        id bigserial PRIMARY KEY,
        old_id BIGINT,
        sub_id INTEGER,
        source BIGINT,
        target BIGINT)',
        sname, oname);
      RAISE DEBUG '  ------> Create geometry column of type %', geomtype;
      EXECUTE format($$
        SELECT addGeometryColumn('%I', '%I', '%I', %s, %L, 2)$$,
        sname, oname, the_geom, sridinfo.srid, geomtype);
      EXECUTE 'SET client_min_messages TO '|| debuglevel;
      RAISE DEBUG '  ------>OK';
    END IF;
  END;
----------------

  RAISE NOTICE 'Processing, please wait .....';


  EXECUTE format(
    $$
      INSERT INTO %2$I.%3$I (old_id, sub_id, %4$I)
      SELECT id, sub_id, geom FROM pgr_separateCrossing(replace('%1$s', 'AS the_geom', 'AS geom'), %5$s)
      UNION
      SELECT id, sub_id, geom FROM pgr_separateTouching(replace('%1$s', 'AS the_geom', 'AS geom'), %5$s)
    $$,
    the_query, sname, oname, the_geom, $2);

  GET DIAGNOSTICS splits = ROW_COUNT;

  EXECUTE format(
    $$
    WITH diff AS (SELECT DISTINCT old_id FROM %I.%I)
    SELECT count(*) FROM diff
    $$,
    sname, oname) INTO touched;

  -- here, it misses all original line that did not need to be cut by intersection points: these lines
  -- are already clean
  -- inserts them in the final result: all lines which gid is not in the res table.
  EXECUTE format(
    $$
      INSERT INTO %2$I.%3$I (old_id , sub_id, %5$I) (
        WITH
        original AS (%1$s),
        used AS (SELECT DISTINCT old_id FROM %2$I.%3$I)
        SELECT id, 1 AS sub_id, the_geom
        FROM original
        WHERE id NOT IN (SELECT old_id FROM used) %4$s)
    $$,
  the_query, sname, oname, rows_where_out, the_geom);
  GET DIAGNOSTICS untouched = ROW_COUNT;

  RAISE NOTICE '  Split Edges: %', touched;
  RAISE NOTICE ' Untouched Edges: %', untouched;
  RAISE NOTICE '     Total original Edges: %', touched+untouched;
  RAISE NOTICE ' Edges generated: %', splits;
  RAISE NOTICE ' Untouched Edges: %',untouched;
  RAISE NOTICE '       Total New segments: %', splits+untouched;
  RAISE NOTICE ' New Table: %.%', sname, oname;
  RAISE NOTICE '----------------------------------';

  RETURN 'OK';
END;
$function$
;

-- Function: pgr_nodenetwork
-- Comment: pgr_nodeNetwork deprecated function on v3.8.0
-- 
CREATE OR REPLACE FUNCTION public.pgr_pickdeliver(text, text, text, factor double precision DEFAULT 1, max_cycles integer DEFAULT 10, initial_sol integer DEFAULT 4, OUT seq integer, OUT vehicle_seq integer, OUT vehicle_id bigint, OUT stop_seq integer, OUT stop_type integer, OUT stop_id bigint, OUT order_id bigint, OUT cargo double precision, OUT travel_time double precision, OUT arrival_time double precision, OUT wait_time double precision, OUT service_time double precision, OUT departure_time double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, vehicle_seq, vehicle_id, stop_seq, stop_type, stop_id, order_id, cargo, travel_time, arrival_time,
           wait_time, service_time, departure_time
    FROM _pgr_pickDeliver(_pgr_get_statement($1), _pgr_get_statement($2), $3, $4, $5);
$function$
;

-- Function: pgr_pickdeliver
-- Comment: pgr_pickDeliver
 - EXPERIMENTAL
 - Parameters:
   - orders SQL with columns:
     - id, demand, p_node_id, p_open, p_close, d_node_id, d_open, d_close
     - optional columns:
        - p_service := 0
        - d_service := 0
   - vehicles SQL with columns:
     - id, capacity, start_open, start_close
     - optional columns:
        - speed := 1
        - start_service := 0
        - end_open := start_open
        - end_close := start_close
        - end_service := 0
   - Matrix
     - start_vid
     - end_vid
     - agg_cost
 - Optional Parameters:
   - factor: default := 1
   - max_cycles: default := 10
   - initial_sol: default := 4
- Documentation:
   - https://docs.pgrouting.org/latest/en/pgr_pickDeliver.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_pickdelivereuclidean(text, text, factor double precision DEFAULT 1, max_cycles integer DEFAULT 10, initial_sol integer DEFAULT 4, OUT seq integer, OUT vehicle_seq integer, OUT vehicle_id bigint, OUT stop_seq integer, OUT stop_type integer, OUT order_id bigint, OUT cargo double precision, OUT travel_time double precision, OUT arrival_time double precision, OUT wait_time double precision, OUT service_time double precision, OUT departure_time double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, vehicle_seq, vehicle_id, stop_seq, stop_type, order_id, cargo, travel_time, arrival_time,
           wait_time, service_time, departure_time
    FROM _pgr_pickDeliverEuclidean(_pgr_get_statement($1), _pgr_get_statement($2), $3, $4, $5);
$function$
;

-- Function: pgr_pickdelivereuclidean
-- Comment: pgr_pickDeliverEuclidean
 - EXPERIMENTAL
 - Parameters:
   - orders SQL with columns:
     - id, demand, p_x, p_t, d_x, d_y, p_open, p_close, d_open, d_close
     - optional columns:
       - p_service := 0
       - d_service := 0
   - vehicles SQL with columns:
     - id, start_x, start_y, capacity, start_open, start_close
     - optional columns:
       - speed := 1
       - start_service := 0
       - end_x := start_x
       - end_y := start_y
       - end_open := start_open
       - end_close := start_close
       - end_service := 0
 - Optional Parameters:
   - factor: default := 1
   - max_cycles: default := 10
   - initial_sol: default := 4
- Documentation:
   - https://docs.pgrouting.org/latest/en/pgr_pickDeliver.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_prim(text, OUT edge bigint, OUT cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT edge, cost
    FROM _pgr_primv4(_pgr_get_statement($1), ARRAY[0]::BIGINT[], '', -1, -1);
$function$
;

-- Function: pgr_prim
-- Comment: pgr_prim
- Undirected graph
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_prim.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_primbfs(text, bigint, max_depth bigint DEFAULT '9223372036854775807'::bigint, OUT seq bigint, OUT depth bigint, OUT start_vid bigint, OUT pred bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, depth, start_vid, pred, node, edge, cost, agg_cost
    FROM _pgr_primv4(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], 'BFS', $3, -1);
$function$
;

-- Function: pgr_primbfs
-- Comment: pgr_primBFS(Single Vertex)
- Undirected graph
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
    - From root vertex identifier
- Optional parameters
    - max_depth := 9223372036854775807
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_primBFS.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_primbfs(text, anyarray, max_depth bigint DEFAULT '9223372036854775807'::bigint, OUT seq bigint, OUT depth bigint, OUT start_vid bigint, OUT pred bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, depth, start_vid, pred, node, edge, cost, agg_cost
    FROM _pgr_primv4(_pgr_get_statement($1), $2, 'BFS', $3, -1);
$function$
;

-- Function: pgr_primbfs
-- Comment: pgr_primBFS(multiple Vertices)
- Undirected graph
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
    - From ARRAY[root vertices identifiers]
- Optional parameters
    - max_depth := 9223372036854775807
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_primBFS.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_primdd(text, anyarray, double precision, OUT seq bigint, OUT depth bigint, OUT start_vid bigint, OUT pred bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, depth, start_vid, pred, node, edge, cost, agg_cost
    FROM _pgr_primv4(_pgr_get_statement($1), $2, 'DD', -1, $3::FLOAT);
$function$
;

-- Function: pgr_primdd
-- Comment: pgr_primDD(Multiple Vertices)
- Undirected graph
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
    - From ARRAY[root vertices identifiers]
    - Distance
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_primDD.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_primdd(text, bigint, numeric, OUT seq bigint, OUT depth bigint, OUT start_vid bigint, OUT pred bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, depth, start_vid, pred, node, edge, cost, agg_cost
    FROM _pgr_primv4(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], 'DD', -1, $3::FLOAT);
$function$
;

-- Function: pgr_primdd
-- Comment: pgr_primDD(Single Vertex)
- Undirected graph
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
    - From root vertex identifier
    - Distance
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_primDD.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_primdd(text, anyarray, numeric, OUT seq bigint, OUT depth bigint, OUT start_vid bigint, OUT pred bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, depth, start_vid, pred, node, edge, cost, agg_cost
    FROM _pgr_primv4(_pgr_get_statement($1), $2, 'DD', -1, $3);
$function$
;

-- Function: pgr_primdd
-- Comment: pgr_primDD(Multiple Vertices)
- Undirected graph
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
    - From ARRAY[root vertices identifiers]
    - Distance
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_primDD.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_primdd(text, bigint, double precision, OUT seq bigint, OUT depth bigint, OUT start_vid bigint, OUT pred bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, depth, start_vid, pred, node, edge, cost, agg_cost
    FROM _pgr_primv4(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], 'DD', -1, $3::FLOAT);
$function$
;

-- Function: pgr_primdd
-- Comment: pgr_primDD(Single Vertex)
- Undirected graph
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
    - From root vertex identifier
    - Distance
- DocumentatiEdgeson:
    - https://docs.pgrouting.org/latest/en/pgr_primDD.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_primdfs(text, anyarray, max_depth bigint DEFAULT '9223372036854775807'::bigint, OUT seq bigint, OUT depth bigint, OUT start_vid bigint, OUT pred bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, depth, start_vid, pred, node, edge, cost, agg_cost
    FROM _pgr_primv4(_pgr_get_statement($1), $2, 'DFS', $3, -1);
$function$
;

-- Function: pgr_primdfs
-- Comment: pgr_primDFS(Multiple Vertices)
- Undirected graph
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
    - From ARRAY[root vertices identifiers]
- Optional parameters
    - max_depth := 9223372036854775807
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_primDFS.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_primdfs(text, bigint, max_depth bigint DEFAULT '9223372036854775807'::bigint, OUT seq bigint, OUT depth bigint, OUT start_vid bigint, OUT pred bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, depth, start_vid, pred, node, edge, cost, agg_cost
    FROM _pgr_primv4(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], 'DFS', $3, -1);
$function$
;

-- Function: pgr_primdfs
-- Comment: pgr_primDFS(Single Vertex)
- Undirected graph
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
    - From root vertex identifier
- Optional parameters
    - max_depth := 9223372036854775807
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_primDFS.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_pushrelabel(text, text, OUT seq integer, OUT edge bigint, OUT start_vid bigint, OUT end_vid bigint, OUT flow bigint, OUT residual_capacity bigint)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
        SELECT seq, edge_id, source, target, flow, residual_capacity
        FROM _pgr_maxflow(_pgr_get_statement($1), _pgr_get_statement($2), 1);
  $function$
;

-- Function: pgr_pushrelabel
-- Comment: pgr_pushRelabel(Combinations)
- Directed graph
- Parameters:
  - Edges SQL with columns: id, source, target, capacity [,reverse_capacity]
  - Combinations SQL with columns: source, target
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_pushRelabel.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_pushrelabel(text, bigint, anyarray, OUT seq integer, OUT edge bigint, OUT start_vid bigint, OUT end_vid bigint, OUT flow bigint, OUT residual_capacity bigint)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
        SELECT seq, edge_id, source, target, flow, residual_capacity
        FROM _pgr_maxflow(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], $3::BIGINT[], 1);
  $function$
;

-- Function: pgr_pushrelabel
-- Comment: pgr_pushRelabel(One to Many)
- Directed graph
- Parameters:
  - Edges SQL with columns: id, source, target, capacity [,reverse_capacity]
  - From vertex identifie
  - To ARRAY[vertices identifiers]
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_pushRelabel.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_pushrelabel(text, bigint, bigint, OUT seq integer, OUT edge bigint, OUT start_vid bigint, OUT end_vid bigint, OUT flow bigint, OUT residual_capacity bigint)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
        SELECT seq, edge_id, source, target, flow, residual_capacity
        FROM _pgr_maxflow(_pgr_get_statement($1), ARRAY[$2]::BIGINT[], ARRAY[$3]::BIGINT[], 1);
  $function$
;

-- Function: pgr_pushrelabel
-- Comment: pgr_pushRelabel(One to One)
- Directed graph
- Parameters:
  - Edges SQL with columns: id, source, target, capacity [,reverse_capacity]
  - From vertex identifier
  - To vertex identifier
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_pushRelabel.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_pushrelabel(text, anyarray, bigint, OUT seq integer, OUT edge bigint, OUT start_vid bigint, OUT end_vid bigint, OUT flow bigint, OUT residual_capacity bigint)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
        SELECT seq, edge_id, source, target, flow, residual_capacity
        FROM _pgr_maxflow(_pgr_get_statement($1), $2::BIGINT[], ARRAY[$3]::BIGINT[], 1);
  $function$
;

-- Function: pgr_pushrelabel
-- Comment: pgr_pushRelabel(Many to One)
- Directed graph
- Parameters:
  - Edges SQL with columns: id, source, target, capacity [,reverse_capacity]
  - From ARRAY[vertices identifiers]
  - To vertex identifie
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_pushRelabel.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_pushrelabel(text, anyarray, anyarray, OUT seq integer, OUT edge bigint, OUT start_vid bigint, OUT end_vid bigint, OUT flow bigint, OUT residual_capacity bigint)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
        SELECT seq, edge_id, source, target, flow, residual_capacity
        FROM _pgr_maxflow(_pgr_get_statement($1), $2::BIGINT[], $3::BIGINT[], 1);
  $function$
;

-- Function: pgr_pushrelabel
-- Comment: pgr_pushRelabel(Many to Many)
- Directed graph
- Parameters:
  - Edges SQL with columns: id, source, target, capacity [,reverse_capacity]
  - From ARRAY[vertices identifiers]
  - To ARRAY[vertices identifiers]
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_pushRelabel.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_separatecrossing(text, tolerance double precision DEFAULT 0.01, dryrun boolean DEFAULT false, OUT seq integer, OUT id bigint, OUT sub_id integer, OUT geom geometry)
 RETURNS SETOF record
 LANGUAGE plpgsql
 STRICT
AS $function$
DECLARE
  edges_sql TEXT := $1;

  the_query TEXT;
  sqlhint TEXT;
  has_geom BOOLEAN;
  has_id BOOLEAN;
BEGIN

  IF tolerance <= 0 THEN
    RAISE EXCEPTION $$'tolerance' must be a positive number (given %)$$, tolerance
      USING ERRCODE = '22023'; -- invalid_parameter_value
  END IF;

  BEGIN
    edges_sql := _pgr_checkQuery($1);
    EXCEPTION WHEN OTHERS THEN
      GET STACKED DIAGNOSTICS sqlhint = PG_EXCEPTION_HINT;
      RAISE EXCEPTION '%', SQLERRM USING HINT = sqlhint, ERRCODE = SQLSTATE;
  END;

  has_id := _pgr_checkColumn(edges_sql, 'id', 'ANY-INTEGER', false, dryrun);
  has_geom := _pgr_checkColumn(edges_sql, 'geom', 'geometry', false, dryrun);

  IF NOT has_id OR NOT has_geom THEN
    RAISE EXCEPTION $$'id' or 'geom' are missing$$ USING HINT = edges_sql;
  END IF;

  the_query := format(
    $$
    WITH
        edges_table AS (
          %s
        ),

    get_crossings AS (
      SELECT e1.id id1, e2.id id2, e1.geom AS g1, e2.geom AS g2, ST_Intersection(e1.geom, e2.geom) AS point
      FROM edges_table e1, edges_table e2
      WHERE e1.id < e2.id AND ST_Crosses(e1.geom, e2.geom)
    ),

    crossings AS (
      SELECT id1, g1, point FROM get_crossings
      UNION
      SELECT id2, g2, point FROM get_crossings
    ),

    blades AS (
      SELECT id1, g1, ST_UnaryUnion(ST_Collect(point)) AS blade
      FROM crossings
      GROUP BY id1, g1
    ),

    collection AS (
      SELECT id1, (st_dump(st_split(st_snap(g1, blade, %2$s), blade))).*
      FROM blades
    )

    SELECT row_number() over()::INTEGER AS seq, id1::BIGINT, path[1], geom
    FROM collection;
    $$,

    edges_sql, tolerance);

    IF dryrun THEN
      RAISE NOTICE '%', the_query || ';';
    ELSE
      RETURN QUERY EXECUTE the_query;
    END IF;

END;
$function$
;

-- Function: pgr_separatecrossing
-- Comment: pgr_separateCrossing
- Parameters
  - Edges SQL with columns: id, geom
- Optional parameters
  - tolerance => 0.01
  - dryrun => true
- DOCUMENTATION:
  - https://docs.pgrouting.org/latest/en/pgr_separateCrossing.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_separatetouching(text, tolerance double precision DEFAULT 0.01, dryrun boolean DEFAULT false, OUT seq integer, OUT id bigint, OUT sub_id integer, OUT geom geometry)
 RETURNS SETOF record
 LANGUAGE plpgsql
 STRICT
AS $function$
DECLARE
  edges_sql TEXT := $1;

  the_query TEXT;
  sqlhint TEXT;
  has_geom BOOLEAN;
  has_id BOOLEAN;
BEGIN

  BEGIN
    edges_sql := _pgr_checkQuery($1);
    EXCEPTION WHEN OTHERS THEN
      GET STACKED DIAGNOSTICS sqlhint = PG_EXCEPTION_HINT;
      RAISE EXCEPTION '%', SQLERRM USING HINT = sqlhint, ERRCODE = SQLSTATE;
  END;

  has_id := _pgr_checkColumn(edges_sql, 'id', 'ANY-INTEGER', true, dryrun => $3);
  has_geom := _pgr_checkColumn(edges_sql, 'geom', 'geometry', true, dryrun => $3);

  the_query := format($$
    WITH
    edges_table AS (
      %s
    ),

    get_touching AS (
      SELECT e1.id id1, e2.id id2, ST_Snap(e1.geom, e2.geom, %2$s) AS geom, e1.geom AS g1, e2.geom AS g2
      FROM edges_table e1, edges_table e2
      WHERE e1.id != e2.id AND ST_DWithin(e1.geom, e2.geom, %2$s) AND NOT(
        ST_StartPoint(e1.geom) = ST_StartPoint(e2.geom) OR ST_StartPoint(e1.geom) = ST_EndPoint(e2.geom)
        OR ST_EndPoint(e1.geom) = ST_StartPoint(e2.geom) OR ST_EndPoint(e1.geom) = ST_EndPoint(e2.geom))
    ),

    touchings AS (
      SELECT  id1, g1, g2, st_intersection(geom, g2) AS point
      FROM get_touching
      WHERE  NOT (geom = g1) OR
         (ST_touches(g1, g2) AND NOT
            (ST_Intersection(geom, g2) = ST_StartPoint(g1)
             OR ST_Intersection(geom, g2) = ST_EndPoint(g1)))
    ),

    blades AS (
      SELECT id1, g1, ST_UnaryUnion(ST_Collect(point)) AS blade
      FROM touchings
      GROUP BY id1, g1
    ),

    collection AS (
      SELECT id1, (st_dump(st_split(st_snap(g1, blade, %2$s), blade))).*
      FROM blades
    )

    SELECT row_number() over()::INTEGER AS seq, id1::BIGINT, path[1], geom
    FROM collection;
    $$,

    edges_sql, tolerance);

    IF dryrun THEN
      RAISE NOTICE '%', the_query || ';';
    ELSE
      RETURN QUERY EXECUTE the_query;
    END IF;

END;
$function$
;

-- Function: pgr_separatetouching
-- Comment: pgr_separateTouching
- Parameters
  - Edges SQL with columns: id, geom
- Optional parameters
  - tolerance => 0.01
  - dryrun => true
- DOCUMENTATION:
  - https://docs.pgrouting.org/latest/en/pgr_separateTouching.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_sequentialvertexcoloring(text, OUT vertex_id bigint, OUT color_id bigint)
 RETURNS SETOF record
 LANGUAGE plpgsql
 STRICT
AS $function$
BEGIN
    RETURN QUERY
    SELECT a.vertex_id, a.color_id
    FROM _pgr_sequentialVertexColoring(_pgr_get_statement($1)) AS a;
END;
$function$
;

-- Function: pgr_sequentialvertexcoloring
-- Comment: pgr_sequentialVertexColoring
- PROPOSED
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_sequentialVertexColoring.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_stoerwagner(text, OUT seq integer, OUT edge bigint, OUT cost double precision, OUT mincut double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, edge, cost, mincut
    FROM _pgr_stoerWagner(_pgr_get_statement($1));
$function$
;

-- Function: pgr_stoerwagner
-- Comment: pgr_stoerWagner
- EXPERIMENTAL
- Undirected graph
- Parameters:
  - edges SQL with columns: id, source, target, cost [,reverse_cost]
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_stoerWagner.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_strongcomponents(text, OUT seq bigint, OUT component bigint, OUT node bigint)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, component, node
    FROM _pgr_strongComponents(_pgr_get_statement($1));
$function$
;

-- Function: pgr_strongcomponents
-- Comment: pgr_strongComponents
- Directed graph
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_strongComponents.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_topologicalsort(text, OUT seq integer, OUT sorted_v bigint)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, sorted_v
    FROM _pgr_topologicalSort(_pgr_get_statement($1));
$function$
;

-- Function: pgr_topologicalsort
-- Comment: pgr_topologicalSort
- EXPERIMENTAL
- Directed graph
- Parameters:
  - edges SQL with columns: id, source, target, cost [,reverse_cost]
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_topologicalSort.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_transitiveclosure(text, OUT seq integer, OUT vid bigint, OUT target_array bigint[])
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, vid, target_array
    FROM _pgr_transitiveClosure(_pgr_get_statement($1));
$function$
;

-- Function: pgr_transitiveclosure
-- Comment: pgr_transitiveClosure
- EXPERIMENTAL
- Directed graph
- Parameters:
  - edges SQL with columns: id, source, target, cost [,reverse_cost]
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_transitiveClosure.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_trsp(text, integer, integer, boolean, boolean, restrictions_sql text DEFAULT NULL::text, OUT seq integer, OUT id1 integer, OUT id2 integer, OUT cost double precision)
 RETURNS SETOF record
 LANGUAGE plpgsql
AS $function$
DECLARE
    edges_sql TEXT    := $1;
    start_vid INTEGER := $2;
    end_vid INTEGER   := $3;
    directed BOOLEAN  := $4;
    has_rcost BOOLEAN := $5;

has_reverse BOOLEAN;
new_sql TEXT;
restrictions_query TEXT;
trsp_sql TEXT;
BEGIN
  RAISE WARNING 'pgr_trsp(text,integer,integer,boolean,boolean) deprecated signature on v3.4.0';
    has_reverse =_pgr_parameter_check('dijkstra', edges_sql, false);

    new_sql := edges_sql;
    IF (has_reverse != has_rcost) THEN  -- user contradiction
        IF (has_reverse) THEN  -- it has reverse_cost but user don't want it.
            -- to be on the safe side because it reads the data wrong, sending only postitive values
            new_sql :=
            'WITH old_sql AS (' || edges_sql || ')' ||
            '   SELECT id, source, target, cost FROM old_sql';
        ELSE -- it does not have reverse_cost but user wants it
            RAISE EXCEPTION 'Error, reverse_cost is used, but query did''t return ''reverse_cost'' column'
            USING ERRCODE := 'XX000';
        END IF;
    END IF;

    IF (restrictions_sql IS NULL OR length(restrictions_sql) = 0) THEN
        -- no restrictions then its a dijkstra
        RETURN query SELECT a.seq - 1 AS seq, node::INTEGER AS id1, edge::INTEGER AS id2, a.cost
        FROM pgr_dijkstra(new_sql, start_vid, end_vid, directed) a;
        RETURN;
    END IF;


    restrictions_query = $$
        WITH old_restrictions AS ( $$ ||
            $6 || $$
        )
        SELECT ROW_NUMBER() OVER() AS id,
            _pgr_array_reverse(array_prepend(target_id, string_to_array(via_path::text, ',')::INTEGER[])) AS path,
            to_cost AS cost
        FROM old_restrictions;
    $$;



    RETURN query
        SELECT (a.seq - 1)::INTEGER, a.node::INTEGER, a.edge::INTEGER, a.cost
        FROM _pgr_trsp(new_sql, restrictions_query, start_vid, end_vid, directed) AS a;
    IF NOT FOUND THEN
        RAISE EXCEPTION 'Error computing path: Path Not Found';
    END IF;

END
$function$
;

-- Function: pgr_trsp
-- Comment: pgr_trsp deprecated signature on v3.4.0
- Documentation: https://docs.pgrouting.org/latest/en/pgr_trsp.html
-- 
CREATE OR REPLACE FUNCTION public.pgr_trsp(text, text, anyarray, anyarray, directed boolean DEFAULT true, OUT seq integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
  SELECT seq, path_seq, start_vid, end_vid, node, edge, cost, agg_cost
  FROM _pgr_trspv4(
    _pgr_get_statement($1),
    _pgr_get_statement($2),
    $3::BIGINT[],
    $4::BIGINT[],
    $5) AS a;
$function$
;

-- Function: pgr_trsp
-- Comment: pgr_trsp(many to many)
- PROPOSED
- Parameters
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - Restrictions SQL with columns: cost, path
  - Departures ARRAY[vertices identifier]
  - Destinations ARRAY[vertices identifier]
- Optional parameters
  - directed := true
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_trsp.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_trsp(text, integer, double precision, integer, double precision, boolean, boolean, turn_restrict_sql text DEFAULT NULL::text, OUT seq integer, OUT id1 integer, OUT id2 integer, OUT cost double precision)
 RETURNS SETOF record
 LANGUAGE plpgsql
AS $function$
DECLARE
    sql TEXT                 := $1;
    source_eid INTEGER       := $2;
    source_pos FLOAT         := $3;
    target_eid INTEGER       := $4;
    target_pos FLOAT         := $5;
    directed BOOLEAN         := $6;
    has_reverse_cost BOOLEAN := $7;

has_reverse BOOLEAN;
new_sql TEXT;
trsp_sql TEXT;
source_sql TEXT;
target_sql TEXT;
union_sql TEXT;
union_sql1 TEXT;
union_sql2 TEXT;
final_sql TEXT;

BEGIN
    IF $2 IS NULL OR $3 IS NULL OR $4 IS NULL OR $5 IS NULL OR $6 IS NULL THEN
        RETURN;
    END IF;
  RAISE WARNING 'pgr_trsp(text,integer,float,integer,float,boolean,boolean) deprecated signature on v3.4.0';
    has_reverse =_pgr_parameter_check('dijkstra', sql, false);

    new_sql := sql;
    IF (has_reverse != has_reverse_cost) THEN  -- user contradiction
        IF (has_reverse) THEN
            -- it has reverse_cost but user don't want it.
            -- to be on the safe side because it reads the data wrong, sending only postitive values
            new_sql :=
            'WITH old_sql AS (' || sql || ')' ||
            '   SELECT id, source, target, cost FROM old_sql';
        ELSE -- it does not have reverse_cost but user wants it
            RAISE EXCEPTION 'Error, reverse_cost is used, but query did''t return ''reverse_cost'' column'
            USING ERRCODE := 'XX000';
        END IF;
    END IF;

    IF (turn_restrict_sql IS NULL OR length(turn_restrict_sql) = 0) THEN
        -- no restrictions then its a withPoints or dijkstra
        IF source_pos = 0 THEN
            source_sql = '(SELECT source FROM (' || sql || ') b WHERE id = ' ||  source_eid || ')';
        ELSE IF source_pos = 1 THEN
            source_sql = '(SELECT target FROM (' || sql || ') b WHERE id = ' || source_eid || ')';
        ELSE
            source_sql = '-1';
            union_sql1 =  '(SELECT 1 as pid, ' || source_eid || ' as edge_id, ' || source_pos || '::float8 as fraction)';
        END IF;
        END IF;
        -- raise notice 'source_sql %', source_sql;
        -- raise notice 'union_sql1 %', union_sql1;


        IF target_pos = 0 THEN
            target_sql = '(SELECT source FROM (' || sql || ') c WHERE id = ' ||  target_eid || ')';
        ELSE IF target_pos = 1 THEN
            target_sql = '(SELECT target FROM (' || sql || ') c WHERE id = ' ||  target_eid || ')';
        ELSE
            target_sql = '-2';
            union_sql2 =  ' (SELECT 2 as pid, ' || target_eid || ' as edge_id, ' || target_pos || '::float8 as fraction)';
        END IF;
        END IF;

        -- raise notice 'target_sql %', target_sql;
        -- raise notice 'union_sql2 %', union_sql2;

        IF union_sql1 IS NOT NULL AND union_sql2 IS NOT NULL THEN
            union_sql = union_sql1 || ' UNION ' || union_sql2;
        ELSE IF union_sql1 IS NOT NULL AND union_sql2 IS NULL THEN
            union_sql = union_sql1;
        ELSE IF union_sql1 IS NULL AND union_sql2 IS NOT NULL THEN
            union_sql = union_sql2;
        END IF;
        END IF;
        END IF;

        IF union_sql IS NULL THEN
            -- no points then its a dijkstra
            final_sql = 'WITH final_sql AS (
                 SELECT  a.seq-1 AS seq, node::INTEGER AS id1, edge::INTEGER AS id2, cost FROM pgr_dijkstra($$' || new_sql || '$$
                ,' || source_sql || '
                ,' || target_sql || '
                , directed := ' || directed || '
            ) a )
            SELECT seq, id1, id2, cost  FROM final_sql ORDER BY seq';
        ELSE
            -- points then its a withPoints
            final_sql = 'WITH final_sql AS (
                SELECT  a.seq-1 AS seq, node::INTEGER AS id1, edge::INTEGER AS id2, cost FROM pgr_withpoints($$' || new_sql || '$$
                , $$' || union_sql || '$$
                ,' || source_sql || '
                ,' || target_sql || '
                , directed := ' || directed || '
            ) a )
            SELECT seq, CASE WHEN seq = 0 AND ' || source_pos || '=0 THEN id1
                             WHEN seq = 0 AND ' || source_pos || '!=0 THEN -1
                             WHEN id2 = -1 AND ' || target_pos || '=0 THEN id1
                             WHEN id2 = -1 AND ' || target_pos || '!=0 THEN id1
                             ELSE id1 END AS id1, id2, cost  FROM final_sql ORDER BY seq';
        END IF;


        -- raise notice 'final_sql %', final_sql;
        RETURN QUERY EXECUTE final_sql;
        RETURN;

    END IF;

    -- with restrictions calls the original code
    RETURN query
    SELECT a.seq, a.id1, a.id2, a.cost
    FROM _pgr_trsp(new_sql, source_eid, source_pos, target_eid, target_pos, directed, has_reverse_cost, turn_restrict_sql) AS a;
    RETURN;

END
$function$
;

-- Function: pgr_trsp
-- Comment: pgr_trsp deprecated signature on v3.4.0
- Documentation: https://docs.pgrouting.org/latest/en/pgr_trsp_withPoints.html
-- 
CREATE OR REPLACE FUNCTION public.pgr_trsp(text, text, anyarray, bigint, directed boolean DEFAULT true, OUT seq integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
  SELECT seq, path_seq, start_vid, end_vid, node, edge, cost, agg_cost
  FROM _pgr_trspv4(
    _pgr_get_statement($1),
    _pgr_get_statement($2),
    $3::BIGINT[],
    ARRAY[$4]::BIGINT[],
    $5) AS a;
$function$
;

-- Function: pgr_trsp
-- Comment: pgr_trsp(many to one)
- PROPOSED
- Parameters
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - Restrictions SQL with columns: cost, path
  - Departures ARRAY[vertices identifier]
  - Destination vertex identifier
- Optional parameters
  - directed := true
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_trsp.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_trsp(text, text, text, directed boolean DEFAULT true, OUT seq integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
  SELECT seq, path_seq, start_vid, end_vid, node, edge, cost, agg_cost
  FROM _pgr_trspv4(
    _pgr_get_statement($1),
    _pgr_get_statement($2),
    _pgr_get_statement($3),
    $4) AS a;
$function$
;

-- Function: pgr_trsp
-- Comment: pgr_trsp(combinations)
- PROPOSED
- Parameters
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - Restrictions SQL with columns: cost, path
  - Combinations SQL with columns: source, target
- Optional parameters
  - directed := true
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_trsp.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_trsp(text, text, bigint, anyarray, directed boolean DEFAULT true, OUT seq integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
  SELECT seq, path_seq, start_vid, end_vid, node, edge, cost, agg_cost
  FROM _pgr_trspv4(
    _pgr_get_statement($1),
    _pgr_get_statement($2),
    ARRAY[$3]::BIGINT[],
    $4::BIGINT[],
    directed) AS a;
$function$
;

-- Function: pgr_trsp
-- Comment: pgr_trsp(one to many)
- PROPOSED
- Parameters
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - Restrictions SQL with columns: cost, path
  - Departure vertex identifier
  - Destinations ARRAY[vertices identifier]
- Optional parameters
  - directed := true
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_trsp.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_trsp(text, text, bigint, bigint, directed boolean DEFAULT true, OUT seq integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$

  SELECT seq, path_seq, start_vid, end_vid, node, edge, cost, agg_cost
  FROM _pgr_trspv4(
    _pgr_get_statement($1),
    _pgr_get_statement($2),
    ARRAY[$3]::BIGINT[],
    ARRAY[$4]::BIGINT[],
    directed) AS a;

$function$
;

-- Function: pgr_trsp
-- Comment: pgr_trsp(one to one)
- PROPOSED
- Parameters
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - Restrictions SQL with columns: cost, path
  - Departure vertex identifier
  - Destination vertex identifier
- Optional parameters
  - directed
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_trsp.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_trsp_withpoints(text, text, text, bigint, anyarray, directed boolean DEFAULT true, driving_side character DEFAULT 'r'::bpchar, details boolean DEFAULT false, OUT seq integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
SELECT seq, path_seq, departure, end_vid, node, edge, cost, agg_cost
FROM _pgr_trsp_withPoints(
  _pgr_get_statement($1),
  _pgr_get_statement($2),
  _pgr_get_statement($3),
  ARRAY[$4]::BIGINT[], $5::BIGINT[], $6, $7, $8);
$function$
;

-- Function: pgr_trsp_withpoints
-- Comment: pgr_trsp_withPoints(One to Many)
- PROPOSED
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - Restrictions SQL with columns: id, cost, path
  - Points SQL with columns: [pid], edge_id, fraction [,side]
  - Departure vertex/point identifier
  - Destinations ARRAY[vertices/Points identifier]
- Optional Parameters:
  - directed := 'true'
  - driving_side := 'r'
  - details := 'false'
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_trsp_withPoints.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_trsp_withpoints(text, text, text, bigint, bigint, directed boolean DEFAULT true, driving_side character DEFAULT 'r'::bpchar, details boolean DEFAULT false, OUT seq integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
SELECT seq, path_seq, departure, end_vid, node, edge, cost, agg_cost
FROM _pgr_trsp_withPoints(
  _pgr_get_statement($1),
  _pgr_get_statement($2),
  _pgr_get_statement($3),
  ARRAY[$4]::BIGINT[], ARRAY[$5]::BIGINT[], $6, $7, $8);
$function$
;

-- Function: pgr_trsp_withpoints
-- Comment: pgr_trsp_withPoints (One to One)
- PROPOSED
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - Restrictions SQL with columns: id, cost, path
  - Points SQL with columns: [pid], edge_id, fraction [,side]
  - Departure vertex/point identifier
  - Destination vertex/point identifier
- Optional Parameters:
  - directed := 'true'
  - driving_side := 'r'
  - details := 'false'
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_trsp_withPoints.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_trsp_withpoints(text, text, text, anyarray, bigint, directed boolean DEFAULT true, driving_side character DEFAULT 'r'::bpchar, details boolean DEFAULT false, OUT seq integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
SELECT seq, path_seq, departure, end_vid, node, edge, cost, agg_cost
FROM _pgr_trsp_withPoints(
  _pgr_get_statement($1),
  _pgr_get_statement($2),
  _pgr_get_statement($3),
  $4::BIGINT[], ARRAY[$5]::BIGINT[], $6, $7, $8);
$function$
;

-- Function: pgr_trsp_withpoints
-- Comment: pgr_trsp_withPoints(Many to One)
- PROPOSED
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - Restrictions SQL with columns: id, cost, path
  - Points SQL with columns: [pid], edge_id, fraction [,side]
  - Departures ARRAY[vertices/Points identifier]
  - Destination vertex/point identifier
- Optional Parameters:
  - directed := 'true'
  - driving_side := 'r'
  - details := 'false'
- Documentation:
- https://docs.pgrouting.org/latest/en/pgr_trsp_withPoints.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_trsp_withpoints(text, text, text, anyarray, anyarray, directed boolean DEFAULT true, driving_side character DEFAULT 'r'::bpchar, details boolean DEFAULT false, OUT seq integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
SELECT seq, path_seq, departure, end_vid, node, edge, cost, agg_cost
FROM _pgr_trsp_withPoints(
  _pgr_get_statement($1),
  _pgr_get_statement($2),
  _pgr_get_statement($3),
  $4::BIGINT[], $5::BIGINT[], $6, $7, $8);
$function$
;

-- Function: pgr_trsp_withpoints
-- Comment: pgr_trsp_withPoints(Many to Many)
- PROPOSED
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - Restrictions SQL with columns: id, cost, path
  - Points SQL with columns: [pid], edge_id, fraction [,side]
  - Departures ARRAY[vertices/Points identifier]
  - Destinations ARRAY[vertices/Points identifier]
- Optional Parameters:
  - directed := 'true'
  - driving_side := 'r'
  - details := 'false'
- Documentation:
- https://docs.pgrouting.org/latest/en/pgr_trsp_withPoints.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_trsp_withpoints(text, text, text, text, directed boolean DEFAULT true, driving_side character DEFAULT 'r'::bpchar, details boolean DEFAULT false, OUT seq integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
SELECT seq, path_seq, departure, end_vid, node, edge, cost, agg_cost
FROM _pgr_trsp_withPoints(
  _pgr_get_statement($1),
  _pgr_get_statement($2),
  _pgr_get_statement($3),
  _pgr_get_statement($4),
  $5, $6, $7);
$function$
;

-- Function: pgr_trsp_withpoints
-- Comment: pgr_trsp_withPoints(Combinations)
- PROPOSED
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - Restrictions SQL with columns: id, path, cost
  - Points SQL with columns: [pid], edge_id, fraction [,side]
  - Combinations SQL with columns: source, target
- Optional Parameters:
  - directed := 'true'
  - driving_side := 'r'
  - details := 'false'
- Documentation:
- https://docs.pgrouting.org/latest/en/pgr_trsp_withPoints.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_trspvia(text, text, anyarray, directed boolean DEFAULT true, strict boolean DEFAULT false, u_turn_on_edge boolean DEFAULT true, OUT seq integer, OUT path_id integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision, OUT route_agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
SELECT seq, path_id, path_seq, start_vid, end_vid, node, edge, cost, agg_cost, route_agg_cost
FROM _pgr_trspVia(
  _pgr_get_statement($1),
  _pgr_get_statement($2),
  $3 , $4, $5, $6);
$function$
;

-- Function: pgr_trspvia
-- Comment: pgr_trspVia
- PROPOSED
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - Restrictions SQL with columns: cost, path
  - ARRAY[via vertices identifiers]
- Optional Parameters
  - directed := true
  - strict := false
  - U_turn_on_edge := true
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_trspVia.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_trspvia_withpoints(text, text, text, anyarray, directed boolean DEFAULT true, strict boolean DEFAULT false, u_turn_on_edge boolean DEFAULT true, driving_side character DEFAULT 'r'::bpchar, details boolean DEFAULT false, OUT seq integer, OUT path_id integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision, OUT route_agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
SELECT seq, path_id, path_seq, start_vid, end_vid, node, edge, cost, agg_cost, route_agg_cost
FROM _pgr_trspVia_withPoints(
  _pgr_get_statement($1),
  _pgr_get_statement($2),
  _pgr_get_statement($3),
  $4, $5, $6, $7, $8, $9);
$function$
;

-- Function: pgr_trspvia_withpoints
-- Comment: pgr_trspVia_withPoints
- PROPOSED
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - Restrictions SQL with columns: cost, path
  - Points SQL with columns: [pid], edge_id, fraction [,side]
  - ARRAY[via vertices identifiers]
- Optional Parameters
  - directed := true
  - strict := false
  - U_turn_on_edge := true
  - driving_side := 'r'
  - details := 'false'
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_trspVia_withPoints.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_trspviaedges(text, integer[], double precision[], boolean, boolean, turn_restrict_sql text DEFAULT NULL::text, OUT seq integer, OUT id1 integer, OUT id2 integer, OUT id3 integer, OUT cost double precision)
 RETURNS SETOF record
 LANGUAGE plpgsql
 STABLE
AS $function$

declare
    sql TEXT          := $1;
    eids INTEGER[]    := $2;
    pcts FLOAT[]      := $3;
    directed BOOLEAN  := $4;
    has_rcost BOOLEAN := $5;

    i integer;
    rr RECORD;
    lrr RECORD;
    first boolean := true;
    seq1 integer := 0;
    seq2 integer :=0;
    has_reverse BOOLEAN;
    point_is_vertex BOOLEAN := false;
    edges_sql TEXT;
    f float;

begin
  RAISE WARNING 'pgr_trspViaEdges(text,integer[],float[],boolean,boolean,text) deprecated function on v3.4.0';
    SELECT 0::INTEGER AS seq, NULL::INTEGER AS id1, NULL::INTEGER AS id2, NULL::INTEGER AS id3, NULL::FLOAT AS cost INTO lrr;
    has_reverse =_pgr_parameter_check('dijkstra', sql, false);
    edges_sql := sql;
    IF (has_reverse != has_rcost) THEN
        IF (NOT has_rcost) THEN
            -- user does not want to use reverse cost column
            edges_sql = 'SELECT id, source, target, cost FROM (' || sql || ') a';
        ELSE
            raise EXCEPTION 'has_rcost set to true but reverse_cost not found';
        END IF;
    END IF;

    FOREACH f IN ARRAY pcts LOOP
        IF f in (0,1) THEN
           point_is_vertex := true;
        END IF;
    END LOOP;

    IF (turn_restrict_sql IS NULL OR length(turn_restrict_sql) = 0) AND NOT point_is_vertex THEN
        -- no restrictions then its a _pgr_withPointsVia
        RETURN query SELECT a.seq::INTEGER, path_id::INTEGER AS id1, node::INTEGER AS id2, edge::INTEGER AS id3, a.cost
        FROM _pgr_withPointsVia(edges_sql, eids, pcts, directed) a;
        RETURN;
    END IF;

    if array_length(eids, 1) != array_length(pcts, 1) then
        raise exception 'The length of arrays eids and pcts must be the same!';
    end if;

    -- loop through each pair of vids and compute the path
    for i in 1 .. array_length(eids, 1)-1 loop
        seq2 := seq2 + 1;
        for rr in select a.seq, seq2 as id1, a.id1 as id2, a.id2 as id3, a.cost
                    from pgr_trsp(edges_sql,
                                  eids[i], pcts[i],
                                  eids[i+1], pcts[i+1],
                                  directed,
                                  has_rcost,
                                  turn_restrict_sql) as a loop
            -- combine intermediate via costs when cost is split across
            -- two parts of a segment because it stops it and
            -- restarts the next leg also on it
            -- we might not want to do this so we can know where the via points are in the path result
            -- but this needs more thought
            --
            -- there are multiple condition we have to deal with
            -- between the end of one leg and start of the next
            -- 1. same vertex_id. edge_id=-1; drop record with edge_id=-1
            -- means: path ends on vertex
            -- NOTICE:  rr: (19,1,44570022,-1,0)
            -- NOTICE:  rr: (0,2,44570022,1768045,2.89691196717448)
            -- 2. vertex_id=-1; sum cost components
            -- means: path end/starts with the segment
            -- NOTICE:  rr: (11,2,44569628,1775909,9.32885885148532)
            -- NOTICE:  rr: (0,3,-1,1775909,0.771386350984395)

            --raise notice 'rr: %', rr;
            if first then
                lrr := rr;
                first := false;
            else
                if lrr.id3 = -1 then
                    lrr := rr;
                elsif lrr.id3 = rr.id3 then
                    lrr.cost := lrr.cost + rr.cost;
                    if rr.id2 = -1 then
                        rr.id2 := lrr.id2;
                    end if;
                else
                    seq1 := seq1 + 1;
                    lrr.seq := seq1;

                    seq := lrr.seq;
                    id1 := lrr.id1;
                    id2 := lrr.id2;
                    id3 := lrr.id3;
                    cost := lrr.cost;
                    return next;
                    lrr := rr;
                end if;
            end if;
        end loop;
    end loop;

    seq1 := seq1 + 1;
    lrr.seq := seq1;

    seq := lrr.seq;
    id1 := lrr.id1;
    id2 := lrr.id2;
    id3 := lrr.id3;
    cost := lrr.cost;
    return next;
    return;
end;
$function$
;

-- Function: pgr_trspviaedges
-- Comment: pgr_trspViaEdges deprecated function on v3.4.0
- Documentation: https://docs.pgrouting.org/latest/en/pgr_trspVia_withPoints.html
-- 
CREATE OR REPLACE FUNCTION public.pgr_trspviavertices(text, anyarray, boolean, boolean, restrictions_sql text DEFAULT NULL::text, OUT seq integer, OUT id1 integer, OUT id2 integer, OUT id3 integer, OUT cost double precision)
 RETURNS SETOF record
 LANGUAGE plpgsql
AS $function$
DECLARE
    edges_sql TEXT     := $1;
    via_vids INTEGER[] := $2;
    directed BOOLEAN   := $3;
    has_rcost BOOLEAN  := $4;

has_reverse BOOLEAN;
new_sql TEXT;
BEGIN
  RAISE WARNING 'pgr_trspViaVertices(text,anyarray,boolean,boolean,text) deprecated function on v3.4.0';

    has_reverse =_pgr_parameter_check('dijkstra', edges_sql, false);

    new_sql := edges_sql;
    IF (has_reverse != has_rcost) THEN  -- user contradiction
        IF (has_reverse) THEN  -- it has reverse_cost but user don't want it.
            new_sql :=
               'WITH old_sql AS (' || edges_sql || ')' ||
                '   SELECT id, source, target, cost FROM old_sql';
        ELSE -- it does not have reverse_cost but user wants it
            RAISE EXCEPTION 'Error, reverse_cost is used, but query did''t return ''reverse_cost'' column'
            USING ERRCODE := 'XX000';
        END IF;
    END IF;

    IF (restrictions_sql IS NULL OR length(restrictions_sql) = 0) THEN
        RETURN query SELECT (row_number() over())::INTEGER, path_id:: INTEGER, node::INTEGER,
            (CASE WHEN edge = -2 THEN -1 ELSE edge END)::INTEGER, a.cost
            FROM pgr_dijkstraVia(new_sql, via_vids, directed, strict:=true) AS a WHERE edge != -1;
        RETURN;
    END IF;


    -- make the call without contradiction from part of the user
    RETURN query SELECT a.seq, a.id1, a.id2, a.id3, a.cost FROM _pgr_trspViaVertices(new_sql, via_vids::INTEGER[], directed, has_rcost, restrictions_sql) AS a;
    IF NOT FOUND THEN
        RAISE EXCEPTION 'Error computing path: Path Not Found';
    END IF;
END
$function$
;

-- Function: pgr_trspviavertices
-- Comment: pgr_trspViaVertices deprecated function on v3.4.0
- Documentation: https://docs.pgrouting.org/latest/en/pgr_trspVia.html
-- 
CREATE OR REPLACE FUNCTION public.pgr_tsp(text, start_id bigint DEFAULT 0, end_id bigint DEFAULT 0, max_processing_time double precision DEFAULT 'Infinity'::double precision, tries_per_temperature integer DEFAULT 500, max_changes_per_temperature integer DEFAULT 60, max_consecutive_non_changes integer DEFAULT 100, initial_temperature double precision DEFAULT 100, final_temperature double precision DEFAULT 0.1, cooling_factor double precision DEFAULT 0.9, randomize boolean DEFAULT true, OUT seq integer, OUT node bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, node, cost, agg_cost
    FROM _pgr_TSP(_pgr_get_statement($1), $2, $3, $4, $5, $6, $7, $8, $9, $10, $11);
$function$
;

-- Function: pgr_tsp
-- Comment: pgr_TSP
- Parameters
   - matrix SQL with columns: start_vid, end_vid, agg_cost
- Optional parameters
    - start_id := 0
    - end_id := 0

    - max_processing_time := '+infinity'::FLOAT

    - tries_per_temperature := 500
    - max_changes_per_temperature :=  60
    - max_consecutive_non_changes :=  100

    - initial_temperature FLOAT := 100
    - final_temperature := 0.1
    - cooling_factor := 0.9

    - randomize := true
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_TSP.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_tspeuclidean(text, start_id bigint DEFAULT 0, end_id bigint DEFAULT 0, max_processing_time double precision DEFAULT 'Infinity'::double precision, tries_per_temperature integer DEFAULT 500, max_changes_per_temperature integer DEFAULT 60, max_consecutive_non_changes integer DEFAULT 100, initial_temperature double precision DEFAULT 100, final_temperature double precision DEFAULT 0.1, cooling_factor double precision DEFAULT 0.9, randomize boolean DEFAULT true, OUT seq integer, OUT node bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, node, cost, agg_cost
    FROM _pgr_TSPeuclidean(_pgr_get_statement($1), $2,$3, $4, $5,$6,$7, $8,$9,$10, $11);
$function$
;

-- Function: pgr_tspeuclidean
-- Comment: pgr_TSPeuclidean
- Parameters
   - coordinates SQL with columns: id, x, y
- Optional parameters
    - start_id := 0
    - end_id := 0

    - max_processing_time := '+infinity'::FLOAT

    - tries_per_temperature := 500
    - max_changes_per_temperature :=  60
    - max_consecutive_non_changes :=  100

    - initial_temperature FLOAT := 100
    - final_temperature := 0.1
    - cooling_factor := 0.9

    - randomize := true
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_TSPeuclidean.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_turnrestrictedpath(text, text, bigint, bigint, integer, directed boolean DEFAULT true, heap_paths boolean DEFAULT false, stop_on_first boolean DEFAULT true, strict boolean DEFAULT false, OUT seq integer, OUT path_id integer, OUT path_seq integer, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, path_id, path_seq, node, edge, cost, agg_cost
    FROM _pgr_turnRestrictedPath(_pgr_get_statement($1), _pgr_get_statement($2), $3, $4, $5, $6, $7, $8, $9);
$function$
;

-- Function: pgr_turnrestrictedpath
-- Comment: pgr_turnRestrictedPath
- EXPERIMENTAL
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
    - Restrictions SQL with columns: id, cost, path
    - From vertex identifier
    - To vertex identifier
    - K
- Optional Parameters
    - directed := true
    - heap paths := false
    - stop on first := true
    - strict := false
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_turnRestrictedPath.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_version()
 RETURNS text
 LANGUAGE sql
 IMMUTABLE
AS $function$
    SELECT '3.8.0'::varchar AS pgr_version;
$function$
;

-- Function: pgr_version
-- Comment: pgr_version
- Documentation
  - https://docs.pgrouting.org/latest/en/pgr_version.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_vrponedepot(text, text, text, integer, OUT oid integer, OUT opos integer, OUT vid integer, OUT tarrival integer, OUT tdepart integer)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT COST 1000
AS $function$
    SELECT order_id::INTEGER, stop_seq::INTEGER, vehicle_id::INTEGER, arrival_time::INTEGER, departure_time::INTEGER
    FROM _pgr_vrpOneDepot($1, $2,
       '
            SELECT src_id AS start_vid, dest_id AS end_vid, traveltime AS agg_cost FROM ('||$3||') AS a
       ',
       $4);
$function$
;

-- Function: pgr_vrponedepot
-- Comment: pgr_vrpOneDepot
- EXPERIMENTAL
- Parameters
  - orders SQL with columns: id, x, y, order_unit, open_time, close_time, service_time
  - vehicle SQL with columns: vehicle_id, capacity, case_no
  - cost SQL with columns: src_id, dest_id, cost, distance, traveltime
  - depot id
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_vrpOneDepot.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_withpoints(text, text, anyarray, anyarray, directed boolean DEFAULT true, driving_side character DEFAULT 'b'::bpchar, details boolean DEFAULT false, OUT seq integer, OUT path_seq integer, OUT start_pid bigint, OUT end_pid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
SELECT a.seq, a.path_seq, a.start_pid, a.end_pid, a.node, a.edge, a.cost, a.agg_cost
    FROM _pgr_withPoints(_pgr_get_statement($1), $2, $3::bigint[], $4::bigint[], $5, $6, $7) AS a;
$function$
;

-- Function: pgr_withpoints
-- Comment: pgr_withPoints (Many to Many)
- PROPOSED
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
    - Points SQL with columns: [pid], edge_id, fraction[,side]
    - From ARRAY[vertices/points identifiers]
    - To ARRAY[vertices/points identifiers]
- Optional Parameters
    - directed := 'true'
    - driving_side := 'b'
    - details := 'false'
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_withPoints.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_withpoints(text, text, text, directed boolean DEFAULT true, driving_side character DEFAULT 'b'::bpchar, details boolean DEFAULT false, OUT seq integer, OUT path_seq integer, OUT start_pid bigint, OUT end_pid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT a.seq, a.path_seq, a.start_pid, a.end_pid, a.node, a.edge, a.cost, a.agg_cost
    FROM _pgr_withPoints(_pgr_get_statement($1), _pgr_get_statement($2), _pgr_get_statement($3),
        $4, $5, $6) AS a;
$function$
;

-- Function: pgr_withpoints
-- Comment: pgr_withPoints(Combinations)
- Parameters:
   - Edges SQL with columns: id, source, target, cost [,reverse_cost]
   - Points SQL with columns: [pid], edge_id, fraction [,side]
   - Combinations SQL with columns: source, target
- Optional Parameters
    - directed := 'true'
    - driving_side := 'b'
    - details := 'false'
- Documentation:
   - https://docs.pgrouting.org/latest/en/pgr_withPoints.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_withpoints(text, text, anyarray, bigint, directed boolean DEFAULT true, driving_side character DEFAULT 'b'::bpchar, details boolean DEFAULT false, OUT seq integer, OUT path_seq integer, OUT start_pid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
SELECT a.seq, a.path_seq, a.start_pid, a.node, a.edge, a.cost, a.agg_cost
    FROM _pgr_withPoints(_pgr_get_statement($1), $2, $3::bigint[], ARRAY[$4]::bigint[], $5, $6, $7, FALSE, FALSE) AS a;
$function$
;

-- Function: pgr_withpoints
-- Comment: pgr_withPoints (Many to One)
- PROPOSED
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
    - Points SQL with columns: [pid], edge_id, fraction[,side]
    - From  ARRAY[vertices/points identifiers]
    - To vertex identifier/point identifier
- Optional Parameters
    - directed := 'true'
    - driving_side := 'b'
    - details := 'false'
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_withPoints.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_withpoints(text, text, bigint, anyarray, directed boolean DEFAULT true, driving_side character DEFAULT 'b'::bpchar, details boolean DEFAULT false, OUT seq integer, OUT path_seq integer, OUT end_pid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
SELECT a.seq, a.path_seq, a.end_pid, a.node, a.edge, a.cost, a.agg_cost
    FROM _pgr_withPoints(_pgr_get_statement($1), $2, ARRAY[$3]::bigint[], $4::bigint[], $5, $6, $7) AS a;
$function$
;

-- Function: pgr_withpoints
-- Comment: pgr_withPoints (One to Many)
- PROPOSED
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
    - Points SQL with columns: [pid], edge_id, fraction[,side]
    - From vertex identifier/point identifier
    - To ARRAY[vertices/points identifier]
- Optional Parameters
    - directed := 'true'
    - driving_side := 'b'
    - details := 'false'
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_withPoints.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_withpoints(text, text, bigint, bigint, directed boolean DEFAULT true, driving_side character DEFAULT 'b'::bpchar, details boolean DEFAULT false, OUT seq integer, OUT path_seq integer, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT a.seq, a.path_seq, a.node, a.edge, a.cost, a.agg_cost
    FROM _pgr_withPoints(_pgr_get_statement($1), $2, ARRAY[$3]::bigint[], ARRAY[$4]::bigint[], $5, $6, $7) AS a;
$function$
;

-- Function: pgr_withpoints
-- Comment: pgr_withPoints (One to One)
- PROPOSED
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
    - Points SQL with columns: [pid], edge_id, fraction[,side]
    - From vertex identifier/point identifier
    - To vertex identifier/point identifier
- Optional Parameters
    - directed := 'true'
    - driving_side := 'b'
    - details := 'false'
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_withPoints.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_withpointscost(text, text, bigint, bigint, directed boolean DEFAULT true, driving_side character DEFAULT 'b'::bpchar, OUT start_pid bigint, OUT end_pid bigint, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT $3, $4, a.agg_cost
    FROM _pgr_withPoints(_pgr_get_statement($1), $2, ARRAY[$3]::BIGINT[], ARRAY[$4]::BIGINT[], $5, $6, TRUE, TRUE) AS a;
$function$
;

-- Function: pgr_withpointscost
-- Comment: pgr_withPointsCost (One to One)
- PROPOSED
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
    - Points SQL with columns: [pid], edge_id, fraction[,side]
    - From vertex/point identifier
    - To vertex/point identifier
- Optional Parameters
    - directed := 'true'
    - driving_side := 'b'
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_withPointsCost.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_withpointscost(text, text, bigint, anyarray, directed boolean DEFAULT true, driving_side character DEFAULT 'b'::bpchar, OUT start_pid bigint, OUT end_pid bigint, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT $3, a.end_pid, a.agg_cost
    FROM _pgr_withPoints(_pgr_get_statement($1), $2, ARRAY[$3]::BIGINT[], $4::BIGINT[], $5, $6, TRUE, TRUE) AS a;
$function$
;

-- Function: pgr_withpointscost
-- Comment: pgr_withPointsCost (One to Many)
- PROPOSED
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
    - Points SQL with columns: [pid], edge_id, fraction[,side]
    - From vertex/point identifier
    - To ARRAY[vertices/points identifiers]
- Optional Parameters
    - directed := 'true'
    - driving_side := 'b'
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_withPointsCost.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_withpointscost(text, text, anyarray, bigint, directed boolean DEFAULT true, driving_side character DEFAULT 'b'::bpchar, OUT start_pid bigint, OUT end_pid bigint, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT a.start_pid, $4, a.agg_cost
    FROM _pgr_withPoints(_pgr_get_statement($1), $2, $3::BIGINT[], ARRAY[$4]::BIGINT[], $5, $6, TRUE, TRUE) AS a;
$function$
;

-- Function: pgr_withpointscost
-- Comment: pgr_withPointsCost (Many to One)
- PROPOSED
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
    - Points SQL with columns: [pid], edge_id, fraction[,side]
    - From ARRAY[vertices/points identifiers]
    - To vertex/point identifier
- Optional Parameters
    - directed := 'true'
    - driving_side := 'b'
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_withPointsCost.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_withpointscost(text, text, anyarray, anyarray, directed boolean DEFAULT true, driving_side character DEFAULT 'b'::bpchar, OUT start_pid bigint, OUT end_pid bigint, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT a.start_pid, a.end_pid, a.agg_cost
    FROM _pgr_withPoints(_pgr_get_statement($1), $2, $3::BIGINT[], $4::BIGINT[], $5,  $6, TRUE, TRUE) AS a;
$function$
;

-- Function: pgr_withpointscost
-- Comment: pgr_withPointsCost (Many to Many)
- PROPOSED
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
    - Points SQL with columns: [pid], edge_id, fraction[,side]
    - From ARRAY[vertices/points identifiers]
    - To ARRAY[vertices/points identifiers]
- Optional Parameters
    - directed := 'true'
    - driving_side := 'b'
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_withPointsCost.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_withpointscost(text, text, text, directed boolean DEFAULT true, driving_side character DEFAULT 'b'::bpchar, OUT start_pid bigint, OUT end_pid bigint, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT a.start_pid, a.end_pid, a.agg_cost
    FROM _pgr_withPoints(_pgr_get_statement($1), _pgr_get_statement($2), _pgr_get_statement($3), $4, $5, TRUE, TRUE) AS a;
$function$
;

-- Function: pgr_withpointscost
-- Comment: pgr_withPointsCost(Combinations)
- PROPOSED
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
    - Points SQL with columns: [pid], edge_id, fraction [,side]
    - Combinations SQL with columns: source, target
- Optional Parameters
    - directed := 'true'
    - driving_side := 'b'
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_withPointsCost.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_withpointscostmatrix(text, text, anyarray, directed boolean DEFAULT true, driving_side character DEFAULT 'b'::bpchar, OUT start_vid bigint, OUT end_vid bigint, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT a.start_pid, a.end_pid, a.agg_cost
    FROM _pgr_withPoints(_pgr_get_statement($1), _pgr_get_statement($2), $3, $3, $4,  $5, TRUE, TRUE) AS a;
$function$
;

-- Function: pgr_withpointscostmatrix
-- Comment: pgr_withPointsCostMatrix
- PROPOSED
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
    - Points SQL with columns: [pid], edge_id, fraction[,side]
    - ARRAY [points identifiers],
- Optional Parameters
    - directed := true
    - driving_side := 'b'
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_withPointsCostMatrix.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_withpointsdd(text, text, anyarray, double precision, character, directed boolean DEFAULT true, details boolean DEFAULT false, equicost boolean DEFAULT false, OUT seq bigint, OUT depth bigint, OUT start_vid bigint, OUT pred bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, depth, start_vid, pred, node, edge, cost, agg_cost
    FROM _pgr_withPointsDDv4(_pgr_get_statement($1), _pgr_get_statement($2), $3, $4, $5, $6, $7, $8);
$function$
;

-- Function: pgr_withpointsdd
-- Comment: pgr_withPointsDD(Multiple Vertices)
- PROPOSED
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
    - Points SQL with columns: [pid], edge_id, fraction[,side]
    - From ARRAY[vertices identifiers]
    - Distance
    - Driving_side
- Optional Parameters
    - directed := true
    - details := false
    - equicost := false
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_withPointsDD.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_withpointsdd(text, text, anyarray, double precision, directed boolean DEFAULT true, driving_side character DEFAULT 'b'::bpchar, details boolean DEFAULT false, equicost boolean DEFAULT false, OUT seq integer, OUT start_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE plpgsql
 STRICT
AS $function$
BEGIN
  RAISE WARNING 'pgr_withpointsdd(text,text,anyarray,double precision,boolean,character,boolean,boolean) deprecated signature on v3.6.0';
  RETURN QUERY
    SELECT a.seq, a.start_vid, a.node, a.edge, a.cost, a.agg_cost
    FROM _pgr_withPointsDD(_pgr_get_statement($1), _pgr_get_statement($2), $3, $4, $5, $6, $7, $8) AS a;
END;
$function$
;

-- Function: pgr_withpointsdd
-- Comment: pgRouting deprecated signature on v3.6.0
- Documentation: https://docs.pgrouting.org/latest/en/pgr_withPointsDD.html
-- 
CREATE OR REPLACE FUNCTION public.pgr_withpointsdd(text, text, bigint, double precision, directed boolean DEFAULT true, driving_side character DEFAULT 'b'::bpchar, details boolean DEFAULT false, OUT seq integer, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE plpgsql
 STRICT
AS $function$
BEGIN
    RAISE WARNING 'pgr_withpointsdd(text,text,bigint,double precision,boolean,character,boolean) deprecated signature on 3.6.0';
    RETURN QUERY
    SELECT a.seq, a.node, a.edge, a.cost, a.agg_cost
    FROM _pgr_withPointsDD(_pgr_get_statement($1), _pgr_get_statement($2), ARRAY[$3]::BIGINT[], $4, $5, $6, $7, false) AS a;
END;
$function$
;

-- Function: pgr_withpointsdd
-- Comment: pgRouting deprecated signature on v3.6.0
- Documentation: https://docs.pgrouting.org/latest/en/pgr_withPointsDD.html
-- 
CREATE OR REPLACE FUNCTION public.pgr_withpointsdd(text, text, bigint, double precision, character, directed boolean DEFAULT true, details boolean DEFAULT false, OUT seq bigint, OUT depth bigint, OUT start_vid bigint, OUT pred bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, depth, start_vid, pred, node, edge, cost, agg_cost
    FROM _pgr_withPointsDDv4(_pgr_get_statement($1), _pgr_get_statement($2), ARRAY[$3]::BIGINT[], $4, $5, $6, $7, false);
$function$
;

-- Function: pgr_withpointsdd
-- Comment: pgr_withPointsDD(Single Vertex)
- PROPOSED
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
    - Points SQL with columns: [pid], edge_id, fraction[,side]
    - From vertex identifier
    - Distance
    - Driving_side
- Optional Parameters
    - directed := true
    - details := false
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_withPointsDD.html

-- 
CREATE OR REPLACE FUNCTION public.pgr_withpointsksp(text, text, anyarray, anyarray, integer, character, directed boolean DEFAULT true, heap_paths boolean DEFAULT false, details boolean DEFAULT false, OUT seq integer, OUT path_id integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, path_id, path_seq, start_vid, end_vid, node, edge, cost, agg_cost
    FROM _pgr_withPointsKSP(_pgr_get_statement($1), _pgr_get_statement($2), $3::BIGINT[], $4::BIGINT[], $5, $6, $7, $8, $9, true);
$function$
;

-- Function: pgr_withpointsksp
-- Comment: pgr_withPointsKSP
- PROPOSED
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
    - Points SQL with columns: [pid], edge_id, fraction[,side]
    - From ARRAY[vertices identifier]
    - To ARRAY[vertices identifiers]
    - K
    - driving side
- Optional Parameters
    - directed := true
    - heap paths := false
    - details := false
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_withPointsKSP.html
-- 
CREATE OR REPLACE FUNCTION public.pgr_withpointsksp(text, text, anyarray, bigint, integer, character, directed boolean DEFAULT true, heap_paths boolean DEFAULT false, details boolean DEFAULT false, OUT seq integer, OUT path_id integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, path_id, path_seq, start_vid, end_vid, node, edge, cost, agg_cost
    FROM _pgr_withPointsKSP(_pgr_get_statement($1), _pgr_get_statement($2), $3::BIGINT[], ARRAY[$4]::BIGINT[], $5, $6, $7, $8, $9, true);
$function$
;

-- Function: pgr_withpointsksp
-- Comment: pgr_withPointsKSP
- PROPOSED
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
    - Points SQL with columns: [pid], edge_id, fraction[,side]
    - From ARRAY[vertices identifier]
    - To vertex identifier
    - K
    - driving side
- Optional Parameters
    - directed := true
    - heap paths := false
    - details := false
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_withPointsKSP.html
-- 
CREATE OR REPLACE FUNCTION public.pgr_withpointsksp(text, text, text, integer, character, directed boolean DEFAULT true, heap_paths boolean DEFAULT false, details boolean DEFAULT false, OUT seq integer, OUT path_id integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, path_id, path_seq, start_vid, end_vid, node, edge, cost, agg_cost
    FROM _pgr_withPointsKSP(_pgr_get_statement($1), _pgr_get_statement($2), _pgr_get_statement($3), $4, $5, $6, $7, $8);
$function$
;

-- Function: pgr_withpointsksp
-- Comment: pgr_withPointsKSP
- PROPOSED
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
    - Points SQL with columns: [pid], edge_id, fraction[,side]
    - Combinations SQL with columns: source, target
    - K
    - driving side
- Optional Parameters
    - directed := true
    - heap paths := false
    - details := false
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_withPointsKSP.html
-- 
CREATE OR REPLACE FUNCTION public.pgr_withpointsksp(text, text, bigint, anyarray, integer, character, directed boolean DEFAULT true, heap_paths boolean DEFAULT false, details boolean DEFAULT false, OUT seq integer, OUT path_id integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, path_id, path_seq, start_vid, end_vid, node, edge, cost, agg_cost
    FROM _pgr_withPointsKSP(_pgr_get_statement($1), _pgr_get_statement($2), ARRAY[$3]::BIGINT[], $4::BIGINT[], $5, $6, $7, $8, $9, true);
$function$
;

-- Function: pgr_withpointsksp
-- Comment: pgr_withPointsKSP
- PROPOSED
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
    - Points SQL with columns: [pid], edge_id, fraction[,side]
    - From vertex identifier
    - To ARRAY[vertices identifiers]
    - K
    - driving side
- Optional Parameters
    - directed := true
    - heap paths := false
    - details := false
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_withPointsKSP.html
-- 
CREATE OR REPLACE FUNCTION public.pgr_withpointsksp(text, text, bigint, bigint, integer, character, directed boolean DEFAULT true, heap_paths boolean DEFAULT false, details boolean DEFAULT false, OUT seq integer, OUT path_id integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
    SELECT seq, path_id, path_seq, start_vid, end_vid, node, edge, cost, agg_cost
    FROM _pgr_withPointsKSP(_pgr_get_statement($1), _pgr_get_statement($2), ARRAY[$3]::BIGINT[], ARRAY[$4]::BIGINT[], $5, $6, $7, $8, $9, true);
$function$
;

-- Function: pgr_withpointsksp
-- Comment: pgr_withPointsKSP
- PROPOSED
- Parameters:
    - Edges SQL with columns: id, source, target, cost [,reverse_cost]
    - Points SQL with columns: [pid], edge_id, fraction[,side]
    - From vertex identifier
    - To vertex identifier
    - K
    - driving side
- Optional Parameters
    - directed := true
    - heap paths := false
    - details := false
- Documentation:
    - https://docs.pgrouting.org/latest/en/pgr_withPointsKSP.html
-- 
CREATE OR REPLACE FUNCTION public.pgr_withpointsksp(text, text, bigint, bigint, integer, directed boolean DEFAULT true, heap_paths boolean DEFAULT false, driving_side character DEFAULT 'b'::bpchar, details boolean DEFAULT false, OUT seq integer, OUT path_id integer, OUT path_seq integer, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE plpgsql
 STRICT
AS $function$
BEGIN
    RAISE WARNING 'pgr_withPointsKSP(text,text,bigint,bigint,integer,boolean,boolean,char,boolean) deprecated signature on v3.6.0';
    RETURN QUERY
    SELECT a.seq, a.path_id, a.path_seq, a.node, a.edge, a.cost, a.agg_cost
    FROM _pgr_withPointsKSP(_pgr_get_statement($1), _pgr_get_statement($2), $3, $4, $5, $6, $7, $8, $9) AS a;
END
$function$
;

-- Function: pgr_withpointsksp
-- Comment: pgr_withPointsKSP deprecated signature on v3.6.0
- Documentation: https://docs.pgrouting.org/latest/en/pgr_withPointsKSP.html
-- 
CREATE OR REPLACE FUNCTION public.pgr_withpointsvia(text, text, anyarray, directed boolean DEFAULT true, strict boolean DEFAULT false, u_turn_on_edge boolean DEFAULT true, driving_side character DEFAULT 'b'::bpchar, details boolean DEFAULT false, OUT seq integer, OUT path_id integer, OUT path_seq integer, OUT start_vid bigint, OUT end_vid bigint, OUT node bigint, OUT edge bigint, OUT cost double precision, OUT agg_cost double precision, OUT route_agg_cost double precision)
 RETURNS SETOF record
 LANGUAGE sql
 STRICT
AS $function$
  SELECT seq, path_id, path_seq, start_vid, end_vid, node, edge, cost, agg_cost, route_agg_cost
  FROM _pgr_withPointsVia( _pgr_get_statement($1), _pgr_get_statement($2), $3, $4, $5, $6, $7, $8);
$function$
;

-- Function: pgr_withpointsvia
-- Comment: pgr_withPointsVia
- PROPOSED
- Parameters:
  - Edges SQL with columns: id, source, target, cost [,reverse_cost]
  - Points SQL with columns: [pid], edge_id, fraction [,side]
  - ARRAY[via vertices identifiers]
- Optional Parameters
  - directed := true
  - strict := false
  - U_turn_on_edge := true
  - driving_side := 'b'
  - details := 'false'
- Documentation:
  - https://docs.pgrouting.org/latest/en/pgr_withPointsVia.html

-- 
CREATE OR REPLACE FUNCTION public.point(geometry)
 RETURNS point
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$geometry_to_point$function$
;

CREATE OR REPLACE FUNCTION public.polygon(geometry)
 RETURNS polygon
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$geometry_to_polygon$function$
;

CREATE OR REPLACE FUNCTION public.populate_geometry_columns(use_typmod boolean DEFAULT true)
 RETURNS text
 LANGUAGE plpgsql
AS $function$
DECLARE
	inserted	integer;
	oldcount	integer;
	probed	  integer;
	stale	   integer;
	gcs		 RECORD;
	gc		  RECORD;
	gsrid	   integer;
	gndims	  integer;
	gtype	   text;
	query	   text;
	gc_is_valid boolean;

BEGIN
	SELECT count(*) INTO oldcount FROM public.geometry_columns;
	inserted := 0;

	-- Count the number of geometry columns in all tables and views
	SELECT count(DISTINCT c.oid) INTO probed
	FROM pg_class c,
		 pg_attribute a,
		 pg_type t,
		 pg_namespace n
	WHERE c.relkind IN('r','v','f', 'p')
		AND t.typname = 'geometry'
		AND a.attisdropped = false
		AND a.atttypid = t.oid
		AND a.attrelid = c.oid
		AND c.relnamespace = n.oid
		AND n.nspname NOT ILIKE 'pg_temp%' AND c.relname != 'raster_columns' ;

	-- Iterate through all non-dropped geometry columns
	RAISE DEBUG 'Processing Tables.....';

	FOR gcs IN
	SELECT DISTINCT ON (c.oid) c.oid, n.nspname, c.relname
		FROM pg_class c,
			 pg_attribute a,
			 pg_type t,
			 pg_namespace n
		WHERE c.relkind IN( 'r', 'f', 'p')
		AND t.typname = 'geometry'
		AND a.attisdropped = false
		AND a.atttypid = t.oid
		AND a.attrelid = c.oid
		AND c.relnamespace = n.oid
		AND n.nspname NOT ILIKE 'pg_temp%' AND c.relname != 'raster_columns'
	LOOP

		inserted := inserted + public.populate_geometry_columns(gcs.oid, use_typmod);
	END LOOP;

	IF oldcount > inserted THEN
		stale = oldcount-inserted;
	ELSE
		stale = 0;
	END IF;

	RETURN 'probed:' ||probed|| ' inserted:'||inserted;
END

$function$
;

CREATE OR REPLACE FUNCTION public.populate_geometry_columns(tbl_oid oid, use_typmod boolean DEFAULT true)
 RETURNS integer
 LANGUAGE plpgsql
AS $function$
DECLARE
	gcs		 RECORD;
	gc		  RECORD;
	gc_old	  RECORD;
	gsrid	   integer;
	gndims	  integer;
	gtype	   text;
	query	   text;
	gc_is_valid boolean;
	inserted	integer;
	constraint_successful boolean := false;

BEGIN
	inserted := 0;

	-- Iterate through all geometry columns in this table
	FOR gcs IN
	SELECT n.nspname, c.relname, a.attname, c.relkind
		FROM pg_class c,
			 pg_attribute a,
			 pg_type t,
			 pg_namespace n
		WHERE c.relkind IN('r', 'f', 'p')
		AND t.typname = 'geometry'
		AND a.attisdropped = false
		AND a.atttypid = t.oid
		AND a.attrelid = c.oid
		AND c.relnamespace = n.oid
		AND n.nspname NOT ILIKE 'pg_temp%'
		AND c.oid = tbl_oid
	LOOP

		RAISE DEBUG 'Processing column %.%.%', gcs.nspname, gcs.relname, gcs.attname;

		gc_is_valid := true;
		-- Find the srid, coord_dimension, and type of current geometry
		-- in geometry_columns -- which is now a view

		SELECT type, srid, coord_dimension, gcs.relkind INTO gc_old
			FROM geometry_columns
			WHERE f_table_schema = gcs.nspname AND f_table_name = gcs.relname AND f_geometry_column = gcs.attname;

		IF upper(gc_old.type) = 'GEOMETRY' THEN
		-- This is an unconstrained geometry we need to do something
		-- We need to figure out what to set the type by inspecting the data
			EXECUTE 'SELECT public.ST_srid(' || quote_ident(gcs.attname) || ') As srid, public.GeometryType(' || quote_ident(gcs.attname) || ') As type, public.ST_NDims(' || quote_ident(gcs.attname) || ') As dims ' ||
					 ' FROM ONLY ' || quote_ident(gcs.nspname) || '.' || quote_ident(gcs.relname) ||
					 ' WHERE ' || quote_ident(gcs.attname) || ' IS NOT NULL LIMIT 1;'
				INTO gc;
			IF gc IS NULL THEN -- there is no data so we can not determine geometry type
				RAISE WARNING 'No data in table %.%, so no information to determine geometry type and srid', gcs.nspname, gcs.relname;
				RETURN 0;
			END IF;
			gsrid := gc.srid; gtype := gc.type; gndims := gc.dims;

			IF use_typmod THEN
				BEGIN
					EXECUTE 'ALTER TABLE ' || quote_ident(gcs.nspname) || '.' || quote_ident(gcs.relname) || ' ALTER COLUMN ' || quote_ident(gcs.attname) ||
						' TYPE geometry(' || postgis_type_name(gtype, gndims, true) || ', ' || gsrid::text  || ') ';
					inserted := inserted + 1;
				EXCEPTION
						WHEN invalid_parameter_value OR feature_not_supported THEN
						RAISE WARNING 'Could not convert ''%'' in ''%.%'' to use typmod with srid %, type %: %', quote_ident(gcs.attname), quote_ident(gcs.nspname), quote_ident(gcs.relname), gsrid, postgis_type_name(gtype, gndims, true), SQLERRM;
							gc_is_valid := false;
				END;

			ELSE
				-- Try to apply srid check to column
				constraint_successful = false;
				IF (gsrid > 0 AND postgis_constraint_srid(gcs.nspname, gcs.relname,gcs.attname) IS NULL ) THEN
					BEGIN
						EXECUTE 'ALTER TABLE ONLY ' || quote_ident(gcs.nspname) || '.' || quote_ident(gcs.relname) ||
								 ' ADD CONSTRAINT ' || quote_ident('enforce_srid_' || gcs.attname) ||
								 ' CHECK (ST_srid(' || quote_ident(gcs.attname) || ') = ' || gsrid || ')';
						constraint_successful := true;
					EXCEPTION
						WHEN check_violation THEN
							RAISE WARNING 'Not inserting ''%'' in ''%.%'' into geometry_columns: could not apply constraint CHECK (st_srid(%) = %)', quote_ident(gcs.attname), quote_ident(gcs.nspname), quote_ident(gcs.relname), quote_ident(gcs.attname), gsrid;
							gc_is_valid := false;
					END;
				END IF;

				-- Try to apply ndims check to column
				IF (gndims IS NOT NULL AND postgis_constraint_dims(gcs.nspname, gcs.relname,gcs.attname) IS NULL ) THEN
					BEGIN
						EXECUTE 'ALTER TABLE ONLY ' || quote_ident(gcs.nspname) || '.' || quote_ident(gcs.relname) || '
								 ADD CONSTRAINT ' || quote_ident('enforce_dims_' || gcs.attname) || '
								 CHECK (st_ndims(' || quote_ident(gcs.attname) || ') = '||gndims||')';
						constraint_successful := true;
					EXCEPTION
						WHEN check_violation THEN
							RAISE WARNING 'Not inserting ''%'' in ''%.%'' into geometry_columns: could not apply constraint CHECK (st_ndims(%) = %)', quote_ident(gcs.attname), quote_ident(gcs.nspname), quote_ident(gcs.relname), quote_ident(gcs.attname), gndims;
							gc_is_valid := false;
					END;
				END IF;

				-- Try to apply geometrytype check to column
				IF (gtype IS NOT NULL AND postgis_constraint_type(gcs.nspname, gcs.relname,gcs.attname) IS NULL ) THEN
					BEGIN
						EXECUTE 'ALTER TABLE ONLY ' || quote_ident(gcs.nspname) || '.' || quote_ident(gcs.relname) || '
						ADD CONSTRAINT ' || quote_ident('enforce_geotype_' || gcs.attname) || '
						CHECK (geometrytype(' || quote_ident(gcs.attname) || ') = ' || quote_literal(gtype) || ')';
						constraint_successful := true;
					EXCEPTION
						WHEN check_violation THEN
							-- No geometry check can be applied. This column contains a number of geometry types.
							RAISE WARNING 'Could not add geometry type check (%) to table column: %.%.%', gtype, quote_ident(gcs.nspname),quote_ident(gcs.relname),quote_ident(gcs.attname);
					END;
				END IF;
				 --only count if we were successful in applying at least one constraint
				IF constraint_successful THEN
					inserted := inserted + 1;
				END IF;
			END IF;
		END IF;

	END LOOP;

	RETURN inserted;
END

$function$
;

CREATE OR REPLACE FUNCTION public.postgis_addbbox(geometry)
 RETURNS geometry
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT COST 50
AS '$libdir/postgis-3', $function$LWGEOM_addBBOX$function$
;

CREATE OR REPLACE FUNCTION public.postgis_cache_bbox()
 RETURNS trigger
 LANGUAGE c
AS '$libdir/postgis-3', $function$cache_bbox$function$
;

CREATE OR REPLACE FUNCTION public.postgis_constraint_dims(geomschema text, geomtable text, geomcolumn text)
 RETURNS integer
 LANGUAGE sql
 STABLE PARALLEL SAFE STRICT COST 250
AS $function$
SELECT  replace(split_part(s.consrc, ' = ', 2), ')', '')::integer
		 FROM pg_class c, pg_namespace n, pg_attribute a
		 , (SELECT connamespace, conrelid, conkey, pg_get_constraintdef(oid) As consrc
			FROM pg_constraint) AS s
		 WHERE n.nspname = $1
		 AND c.relname = $2
		 AND a.attname = $3
		 AND a.attrelid = c.oid
		 AND s.connamespace = n.oid
		 AND s.conrelid = c.oid
		 AND a.attnum = ANY (s.conkey)
		 AND s.consrc LIKE '%ndims(% = %';
$function$
;

CREATE OR REPLACE FUNCTION public.postgis_constraint_srid(geomschema text, geomtable text, geomcolumn text)
 RETURNS integer
 LANGUAGE sql
 STABLE PARALLEL SAFE STRICT COST 250
AS $function$
SELECT replace(replace(split_part(s.consrc, ' = ', 2), ')', ''), '(', '')::integer
		 FROM pg_class c, pg_namespace n, pg_attribute a
		 , (SELECT connamespace, conrelid, conkey, pg_get_constraintdef(oid) As consrc
			FROM pg_constraint) AS s
		 WHERE n.nspname = $1
		 AND c.relname = $2
		 AND a.attname = $3
		 AND a.attrelid = c.oid
		 AND s.connamespace = n.oid
		 AND s.conrelid = c.oid
		 AND a.attnum = ANY (s.conkey)
		 AND s.consrc LIKE '%srid(% = %';
$function$
;

CREATE OR REPLACE FUNCTION public.postgis_constraint_type(geomschema text, geomtable text, geomcolumn text)
 RETURNS character varying
 LANGUAGE sql
 STABLE PARALLEL SAFE STRICT COST 250
AS $function$
SELECT  replace(split_part(s.consrc, '''', 2), ')', '')::varchar
		 FROM pg_class c, pg_namespace n, pg_attribute a
		 , (SELECT connamespace, conrelid, conkey, pg_get_constraintdef(oid) As consrc
			FROM pg_constraint) AS s
		 WHERE n.nspname = $1
		 AND c.relname = $2
		 AND a.attname = $3
		 AND a.attrelid = c.oid
		 AND s.connamespace = n.oid
		 AND s.conrelid = c.oid
		 AND a.attnum = ANY (s.conkey)
		 AND s.consrc LIKE '%geometrytype(% = %';
$function$
;

CREATE OR REPLACE FUNCTION public.postgis_dropbbox(geometry)
 RETURNS geometry
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT COST 50
AS '$libdir/postgis-3', $function$LWGEOM_dropBBOX$function$
;

CREATE OR REPLACE FUNCTION public.postgis_extensions_upgrade(target_version text DEFAULT NULL::text)
 RETURNS text
 LANGUAGE plpgsql
AS $function$
DECLARE
	rec record;
	sql text;
	var_schema text;
BEGIN

	FOR rec IN
		SELECT name, default_version, installed_version
		FROM pg_catalog.pg_available_extensions
		WHERE name IN (
			'postgis',
			'postgis_raster',
			'postgis_sfcgal',
			'postgis_topology',
			'postgis_tiger_geocoder'
		)
		ORDER BY length(name) -- this is to make sure 'postgis' is first !
	LOOP --{

		IF target_version IS NULL THEN
			target_version := rec.default_version;
		END IF;

		IF rec.installed_version IS NULL THEN --{
			-- If the support installed by available extension
			-- is found unpackaged, we package it
			IF --{
				 -- PostGIS is always available (this function is part of it)
				 rec.name = 'postgis'

				 -- PostGIS raster is available if type 'raster' exists
				 OR ( rec.name = 'postgis_raster' AND EXISTS (
							SELECT 1 FROM pg_catalog.pg_type
							WHERE typname = 'raster' ) )

				 -- PostGIS SFCGAL is available if
				 -- 'postgis_sfcgal_version' function exists
				 OR ( rec.name = 'postgis_sfcgal' AND EXISTS (
							SELECT 1 FROM pg_catalog.pg_proc
							WHERE proname = 'postgis_sfcgal_version' ) )

				 -- PostGIS Topology is available if
				 -- 'topology.topology' table exists
				 -- NOTE: watch out for https://trac.osgeo.org/postgis/ticket/2503
				 OR ( rec.name = 'postgis_topology' AND EXISTS (
							SELECT 1 FROM pg_catalog.pg_class c
							JOIN pg_catalog.pg_namespace n ON (c.relnamespace = n.oid )
							WHERE n.nspname = 'topology' AND c.relname = 'topology') )

				 OR ( rec.name = 'postgis_tiger_geocoder' AND EXISTS (
							SELECT 1 FROM pg_catalog.pg_class c
							JOIN pg_catalog.pg_namespace n ON (c.relnamespace = n.oid )
							WHERE n.nspname = 'tiger' AND c.relname = 'geocode_settings') )
			THEN --}{ -- the code is unpackaged
				-- Force install in same schema as postgis
				SELECT INTO var_schema n.nspname
				  FROM pg_namespace n, pg_proc p
				  WHERE p.proname = 'postgis_full_version'
					AND n.oid = p.pronamespace
				  LIMIT 1;
				IF rec.name NOT IN('postgis_topology', 'postgis_tiger_geocoder')
				THEN
					sql := format(
							  'CREATE EXTENSION %1$I SCHEMA %2$I VERSION unpackaged;'
							  'ALTER EXTENSION %1$I UPDATE TO %3$I',
							  rec.name, var_schema, target_version);
				ELSE
					sql := format(
							 'CREATE EXTENSION %1$I VERSION unpackaged;'
							 'ALTER EXTENSION %1$I UPDATE TO %2$I',
							 rec.name, target_version);
				END IF;
				RAISE NOTICE 'Packaging and updating %', rec.name;
				RAISE DEBUG '%', sql;
				EXECUTE sql;
			ELSE
				RAISE DEBUG 'Skipping % (not in use)', rec.name;
			END IF; --}
		ELSE -- The code is already packaged, upgrade it --}{
			sql = format(
				'ALTER EXTENSION %1$I UPDATE TO "ANY";'
				'ALTER EXTENSION %1$I UPDATE TO %2$I',
				rec.name, target_version
				);
			RAISE NOTICE 'Updating extension % %', rec.name, rec.installed_version;
			RAISE DEBUG '%', sql;
			EXECUTE sql;
		END IF; --}

	END LOOP; --}

	RETURN format(
		'Upgrade to version %s completed, run SELECT postgis_full_version(); for details',
		target_version
	);


END
$function$
;

CREATE OR REPLACE FUNCTION public.postgis_full_version()
 RETURNS text
 LANGUAGE plpgsql
 IMMUTABLE
AS $function$
DECLARE
	libver text;
	librev text;
	projver text;
	projver_compiled text;
	geosver text;
	geosver_compiled text;
	sfcgalver text;
	gdalver text := NULL;
	libxmlver text;
	liblwgeomver text;
	dbproc text;
	relproc text;
	fullver text;
	rast_lib_ver text := NULL;
	rast_scr_ver text := NULL;
	topo_scr_ver text := NULL;
	json_lib_ver text;
	protobuf_lib_ver text;
	wagyu_lib_ver text;
	sfcgal_lib_ver text;
	sfcgal_scr_ver text;
	pgsql_scr_ver text;
	pgsql_ver text;
	core_is_extension bool;
BEGIN
	SELECT public.postgis_lib_version() INTO libver;
	SELECT public.postgis_proj_version() INTO projver;
	SELECT public.postgis_geos_version() INTO geosver;
	SELECT public.postgis_geos_compiled_version() INTO geosver_compiled;
	SELECT public.postgis_proj_compiled_version() INTO projver_compiled;
	SELECT public.postgis_libjson_version() INTO json_lib_ver;
	SELECT public.postgis_libprotobuf_version() INTO protobuf_lib_ver;
	SELECT public.postgis_wagyu_version() INTO wagyu_lib_ver;
	SELECT public._postgis_scripts_pgsql_version() INTO pgsql_scr_ver;
	SELECT public._postgis_pgsql_version() INTO pgsql_ver;
	BEGIN
		SELECT public.postgis_gdal_version() INTO gdalver;
	EXCEPTION
		WHEN undefined_function THEN
			RAISE DEBUG 'Function postgis_gdal_version() not found.  Is raster support enabled and rtpostgis.sql installed?';
	END;
	BEGIN
		SELECT public.postgis_sfcgal_full_version() INTO sfcgalver;
		BEGIN
			SELECT public.postgis_sfcgal_scripts_installed() INTO sfcgal_scr_ver;
		EXCEPTION
			WHEN undefined_function THEN
				sfcgal_scr_ver := 'missing';
		END;
	EXCEPTION
		WHEN undefined_function THEN
			RAISE DEBUG 'Function postgis_sfcgal_scripts_installed() not found. Is sfcgal support enabled and sfcgal.sql installed?';
	END;
	SELECT public.postgis_liblwgeom_version() INTO liblwgeomver;
	SELECT public.postgis_libxml_version() INTO libxmlver;
	SELECT public.postgis_scripts_installed() INTO dbproc;
	SELECT public.postgis_scripts_released() INTO relproc;
	SELECT public.postgis_lib_revision() INTO librev;
	BEGIN
		SELECT topology.postgis_topology_scripts_installed() INTO topo_scr_ver;
	EXCEPTION
		WHEN undefined_function OR invalid_schema_name THEN
			RAISE DEBUG 'Function postgis_topology_scripts_installed() not found. Is topology support enabled and topology.sql installed?';
		WHEN insufficient_privilege THEN
			RAISE NOTICE 'Topology support cannot be inspected. Is current user granted USAGE on schema "topology" ?';
		WHEN OTHERS THEN
			RAISE NOTICE 'Function postgis_topology_scripts_installed() could not be called: % (%)', SQLERRM, SQLSTATE;
	END;

	BEGIN
		SELECT postgis_raster_scripts_installed() INTO rast_scr_ver;
	EXCEPTION
		WHEN undefined_function THEN
			RAISE DEBUG 'Function postgis_raster_scripts_installed() not found. Is raster support enabled and rtpostgis.sql installed?';
		WHEN OTHERS THEN
			RAISE NOTICE 'Function postgis_raster_scripts_installed() could not be called: % (%)', SQLERRM, SQLSTATE;
	END;

	BEGIN
		SELECT public.postgis_raster_lib_version() INTO rast_lib_ver;
	EXCEPTION
		WHEN undefined_function THEN
			RAISE DEBUG 'Function postgis_raster_lib_version() not found. Is raster support enabled and rtpostgis.sql installed?';
		WHEN OTHERS THEN
			RAISE NOTICE 'Function postgis_raster_lib_version() could not be called: % (%)', SQLERRM, SQLSTATE;
	END;

	fullver = 'POSTGIS="' || libver;

	IF  librev IS NOT NULL THEN
		fullver = fullver || ' ' || librev;
	END IF;

	fullver = fullver || '"';

	IF EXISTS (
		SELECT * FROM pg_catalog.pg_extension
		WHERE extname = 'postgis')
	THEN
			fullver = fullver || ' [EXTENSION]';
			core_is_extension := true;
	ELSE
			core_is_extension := false;
	END IF;

	IF liblwgeomver != relproc THEN
		fullver = fullver || ' (liblwgeom version mismatch: "' || liblwgeomver || '")';
	END IF;

	fullver = fullver || ' PGSQL="' || pgsql_scr_ver || '"';
	IF pgsql_scr_ver != pgsql_ver THEN
		fullver = fullver || ' (procs need upgrade for use with PostgreSQL "' || pgsql_ver || '")';
	END IF;

	IF  geosver IS NOT NULL THEN
		fullver = fullver || ' GEOS="' || geosver || '"';
		IF (string_to_array(geosver, '.'))[1:2] != (string_to_array(geosver_compiled, '.'))[1:2]
		THEN
			fullver = format('%s (compiled against GEOS %s)', fullver, geosver_compiled);
		END IF;
	END IF;

	IF  sfcgalver IS NOT NULL THEN
		fullver = fullver || ' SFCGAL="' || sfcgalver || '"';
	END IF;

	IF  projver IS NOT NULL THEN
		fullver = fullver || ' PROJ="' || projver || '"';
		IF (string_to_array(projver, '.'))[1:3] != (string_to_array(projver_compiled, '.'))[1:3]
		THEN
			fullver = format('%s (compiled against PROJ %s)', fullver, projver_compiled);
		END IF;
	END IF;

	IF  gdalver IS NOT NULL THEN
		fullver = fullver || ' GDAL="' || gdalver || '"';
	END IF;

	IF  libxmlver IS NOT NULL THEN
		fullver = fullver || ' LIBXML="' || libxmlver || '"';
	END IF;

	IF json_lib_ver IS NOT NULL THEN
		fullver = fullver || ' LIBJSON="' || json_lib_ver || '"';
	END IF;

	IF protobuf_lib_ver IS NOT NULL THEN
		fullver = fullver || ' LIBPROTOBUF="' || protobuf_lib_ver || '"';
	END IF;

	IF wagyu_lib_ver IS NOT NULL THEN
		fullver = fullver || ' WAGYU="' || wagyu_lib_ver || '"';
	END IF;

	IF dbproc != relproc THEN
		fullver = fullver || ' (core procs from "' || dbproc || '" need upgrade)';
	END IF;

	IF topo_scr_ver IS NOT NULL THEN
		fullver = fullver || ' TOPOLOGY';
		IF topo_scr_ver != relproc THEN
			fullver = fullver || ' (topology procs from "' || topo_scr_ver || '" need upgrade)';
		END IF;
		IF core_is_extension AND NOT EXISTS (
			SELECT * FROM pg_catalog.pg_extension
			WHERE extname = 'postgis_topology')
		THEN
				fullver = fullver || ' [UNPACKAGED!]';
		END IF;
	END IF;

	IF rast_lib_ver IS NOT NULL THEN
		fullver = fullver || ' RASTER';
		IF rast_lib_ver != relproc THEN
			fullver = fullver || ' (raster lib from "' || rast_lib_ver || '" need upgrade)';
		END IF;
		IF core_is_extension AND NOT EXISTS (
			SELECT * FROM pg_catalog.pg_extension
			WHERE extname = 'postgis_raster')
		THEN
				fullver = fullver || ' [UNPACKAGED!]';
		END IF;
	END IF;

	IF rast_scr_ver IS NOT NULL AND rast_scr_ver != relproc THEN
		fullver = fullver || ' (raster procs from "' || rast_scr_ver || '" need upgrade)';
	END IF;

	IF sfcgal_scr_ver IS NOT NULL AND sfcgal_scr_ver != relproc THEN
		fullver = fullver || ' (sfcgal procs from "' || sfcgal_scr_ver || '" need upgrade)';
	END IF;

	-- Check for the presence of deprecated functions
	IF EXISTS ( SELECT oid FROM pg_catalog.pg_proc WHERE proname LIKE '%_deprecated_by_postgis_%' )
	THEN
		fullver = fullver || ' (deprecated functions exist, upgrade is not complete)';
	END IF;

	RETURN fullver;
END
$function$
;

CREATE OR REPLACE FUNCTION public.postgis_gdal_version()
 RETURNS text
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE
AS '$libdir/postgis_raster-3', $function$RASTER_gdal_version$function$
;

CREATE OR REPLACE FUNCTION public.postgis_geos_compiled_version()
 RETURNS text
 LANGUAGE c
 IMMUTABLE
AS '$libdir/postgis-3', $function$postgis_geos_compiled_version$function$
;

CREATE OR REPLACE FUNCTION public.postgis_geos_noop(geometry)
 RETURNS geometry
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$GEOSnoop$function$
;

CREATE OR REPLACE FUNCTION public.postgis_geos_version()
 RETURNS text
 LANGUAGE c
 IMMUTABLE
AS '$libdir/postgis-3', $function$postgis_geos_version$function$
;

CREATE OR REPLACE FUNCTION public.postgis_getbbox(geometry)
 RETURNS box2d
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$LWGEOM_to_BOX2DF$function$
;

CREATE OR REPLACE FUNCTION public.postgis_hasbbox(geometry)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$LWGEOM_hasBBOX$function$
;

CREATE OR REPLACE FUNCTION public.postgis_index_supportfn(internal)
 RETURNS internal
 LANGUAGE c
AS '$libdir/postgis-3', $function$postgis_index_supportfn$function$
;

CREATE OR REPLACE FUNCTION public.postgis_lib_build_date()
 RETURNS text
 LANGUAGE c
 IMMUTABLE
AS '$libdir/postgis-3', $function$postgis_lib_build_date$function$
;

CREATE OR REPLACE FUNCTION public.postgis_lib_revision()
 RETURNS text
 LANGUAGE c
 IMMUTABLE
AS '$libdir/postgis-3', $function$postgis_lib_revision$function$
;

CREATE OR REPLACE FUNCTION public.postgis_lib_version()
 RETURNS text
 LANGUAGE c
 IMMUTABLE
AS '$libdir/postgis-3', $function$postgis_lib_version$function$
;

CREATE OR REPLACE FUNCTION public.postgis_libjson_version()
 RETURNS text
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$postgis_libjson_version$function$
;

CREATE OR REPLACE FUNCTION public.postgis_liblwgeom_version()
 RETURNS text
 LANGUAGE c
 IMMUTABLE
AS '$libdir/postgis-3', $function$postgis_liblwgeom_version$function$
;

CREATE OR REPLACE FUNCTION public.postgis_libprotobuf_version()
 RETURNS text
 LANGUAGE c
 IMMUTABLE STRICT
AS '$libdir/postgis-3', $function$postgis_libprotobuf_version$function$
;

CREATE OR REPLACE FUNCTION public.postgis_libxml_version()
 RETURNS text
 LANGUAGE c
 IMMUTABLE
AS '$libdir/postgis-3', $function$postgis_libxml_version$function$
;

CREATE OR REPLACE FUNCTION public.postgis_noop(raster)
 RETURNS geometry
 LANGUAGE c
 STABLE STRICT
AS '$libdir/postgis_raster-3', $function$RASTER_noop$function$
;

CREATE OR REPLACE FUNCTION public.postgis_noop(geometry)
 RETURNS geometry
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$LWGEOM_noop$function$
;

CREATE OR REPLACE FUNCTION public.postgis_proj_compiled_version()
 RETURNS text
 LANGUAGE c
 IMMUTABLE
AS '$libdir/postgis-3', $function$postgis_proj_compiled_version$function$
;

CREATE OR REPLACE FUNCTION public.postgis_proj_version()
 RETURNS text
 LANGUAGE c
 IMMUTABLE
AS '$libdir/postgis-3', $function$postgis_proj_version$function$
;

CREATE OR REPLACE FUNCTION public.postgis_raster_lib_build_date()
 RETURNS text
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE
AS '$libdir/postgis_raster-3', $function$RASTER_lib_build_date$function$
;

CREATE OR REPLACE FUNCTION public.postgis_raster_lib_version()
 RETURNS text
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE
AS '$libdir/postgis_raster-3', $function$RASTER_lib_version$function$
;

CREATE OR REPLACE FUNCTION public.postgis_raster_scripts_installed()
 RETURNS text
 LANGUAGE sql
 IMMUTABLE PARALLEL SAFE
AS $function$ SELECT trim('3.5.3'::text || $rev$ 0 $rev$) AS version $function$
;

CREATE OR REPLACE FUNCTION public.postgis_scripts_build_date()
 RETURNS text
 LANGUAGE sql
 IMMUTABLE
AS $function$SELECT ''::text AS version$function$
;

CREATE OR REPLACE FUNCTION public.postgis_scripts_installed()
 RETURNS text
 LANGUAGE sql
 IMMUTABLE
AS $function$ SELECT trim('3.5.3'::text || $rev$ 0 $rev$) AS version $function$
;

CREATE OR REPLACE FUNCTION public.postgis_scripts_released()
 RETURNS text
 LANGUAGE c
 IMMUTABLE
AS '$libdir/postgis-3', $function$postgis_scripts_released$function$
;

CREATE OR REPLACE FUNCTION public.postgis_srs(auth_name text, auth_srid text)
 RETURNS TABLE(auth_name text, auth_srid text, srname text, srtext text, proj4text text, point_sw geometry, point_ne geometry)
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT COST 250
AS '$libdir/postgis-3', $function$postgis_srs_entry$function$
;

CREATE OR REPLACE FUNCTION public.postgis_srs_all()
 RETURNS TABLE(auth_name text, auth_srid text, srname text, srtext text, proj4text text, point_sw geometry, point_ne geometry)
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT COST 5000
AS '$libdir/postgis-3', $function$postgis_srs_entry_all$function$
;

CREATE OR REPLACE FUNCTION public.postgis_srs_codes(auth_name text)
 RETURNS SETOF text
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT COST 250
AS '$libdir/postgis-3', $function$postgis_srs_codes$function$
;

CREATE OR REPLACE FUNCTION public.postgis_srs_search(bounds geometry, authname text DEFAULT 'EPSG'::text)
 RETURNS TABLE(auth_name text, auth_srid text, srname text, srtext text, proj4text text, point_sw geometry, point_ne geometry)
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT COST 5000
AS '$libdir/postgis-3', $function$postgis_srs_search$function$
;

CREATE OR REPLACE FUNCTION public.postgis_svn_version()
 RETURNS text
 LANGUAGE sql
 IMMUTABLE
AS $function$
	SELECT public._postgis_deprecate(
		'postgis_svn_version', 'postgis_lib_revision', '3.1.0');
	SELECT public.postgis_lib_revision();
$function$
;

CREATE OR REPLACE FUNCTION public.postgis_transform_geometry(geom geometry, text, text, integer)
 RETURNS geometry
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT COST 250
AS '$libdir/postgis-3', $function$transform_geom$function$
;

CREATE OR REPLACE FUNCTION public.postgis_transform_pipeline_geometry(geom geometry, pipeline text, forward boolean, to_srid integer)
 RETURNS geometry
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT COST 250
AS '$libdir/postgis-3', $function$transform_pipeline_geom$function$
;

CREATE OR REPLACE FUNCTION public.postgis_type_name(geomname character varying, coord_dimension integer, use_new_name boolean DEFAULT true)
 RETURNS character varying
 LANGUAGE sql
 IMMUTABLE PARALLEL SAFE STRICT COST 5000
AS $function$
	SELECT CASE WHEN $3 THEN new_name ELSE old_name END As geomname
	FROM
	( VALUES
			('GEOMETRY', 'Geometry', 2),
			('GEOMETRY', 'GeometryZ', 3),
			('GEOMETRYM', 'GeometryM', 3),
			('GEOMETRY', 'GeometryZM', 4),

			('GEOMETRYCOLLECTION', 'GeometryCollection', 2),
			('GEOMETRYCOLLECTION', 'GeometryCollectionZ', 3),
			('GEOMETRYCOLLECTIONM', 'GeometryCollectionM', 3),
			('GEOMETRYCOLLECTION', 'GeometryCollectionZM', 4),

			('POINT', 'Point', 2),
			('POINT', 'PointZ', 3),
			('POINTM','PointM', 3),
			('POINT', 'PointZM', 4),

			('MULTIPOINT','MultiPoint', 2),
			('MULTIPOINT','MultiPointZ', 3),
			('MULTIPOINTM','MultiPointM', 3),
			('MULTIPOINT','MultiPointZM', 4),

			('POLYGON', 'Polygon', 2),
			('POLYGON', 'PolygonZ', 3),
			('POLYGONM', 'PolygonM', 3),
			('POLYGON', 'PolygonZM', 4),

			('MULTIPOLYGON', 'MultiPolygon', 2),
			('MULTIPOLYGON', 'MultiPolygonZ', 3),
			('MULTIPOLYGONM', 'MultiPolygonM', 3),
			('MULTIPOLYGON', 'MultiPolygonZM', 4),

			('MULTILINESTRING', 'MultiLineString', 2),
			('MULTILINESTRING', 'MultiLineStringZ', 3),
			('MULTILINESTRINGM', 'MultiLineStringM', 3),
			('MULTILINESTRING', 'MultiLineStringZM', 4),

			('LINESTRING', 'LineString', 2),
			('LINESTRING', 'LineStringZ', 3),
			('LINESTRINGM', 'LineStringM', 3),
			('LINESTRING', 'LineStringZM', 4),

			('CIRCULARSTRING', 'CircularString', 2),
			('CIRCULARSTRING', 'CircularStringZ', 3),
			('CIRCULARSTRINGM', 'CircularStringM' ,3),
			('CIRCULARSTRING', 'CircularStringZM', 4),

			('COMPOUNDCURVE', 'CompoundCurve', 2),
			('COMPOUNDCURVE', 'CompoundCurveZ', 3),
			('COMPOUNDCURVEM', 'CompoundCurveM', 3),
			('COMPOUNDCURVE', 'CompoundCurveZM', 4),

			('CURVEPOLYGON', 'CurvePolygon', 2),
			('CURVEPOLYGON', 'CurvePolygonZ', 3),
			('CURVEPOLYGONM', 'CurvePolygonM', 3),
			('CURVEPOLYGON', 'CurvePolygonZM', 4),

			('MULTICURVE', 'MultiCurve', 2),
			('MULTICURVE', 'MultiCurveZ', 3),
			('MULTICURVEM', 'MultiCurveM', 3),
			('MULTICURVE', 'MultiCurveZM', 4),

			('MULTISURFACE', 'MultiSurface', 2),
			('MULTISURFACE', 'MultiSurfaceZ', 3),
			('MULTISURFACEM', 'MultiSurfaceM', 3),
			('MULTISURFACE', 'MultiSurfaceZM', 4),

			('POLYHEDRALSURFACE', 'PolyhedralSurface', 2),
			('POLYHEDRALSURFACE', 'PolyhedralSurfaceZ', 3),
			('POLYHEDRALSURFACEM', 'PolyhedralSurfaceM', 3),
			('POLYHEDRALSURFACE', 'PolyhedralSurfaceZM', 4),

			('TRIANGLE', 'Triangle', 2),
			('TRIANGLE', 'TriangleZ', 3),
			('TRIANGLEM', 'TriangleM', 3),
			('TRIANGLE', 'TriangleZM', 4),

			('TIN', 'Tin', 2),
			('TIN', 'TinZ', 3),
			('TINM', 'TinM', 3),
			('TIN', 'TinZM', 4) )
			 As g(old_name, new_name, coord_dimension)
	WHERE (upper(old_name) = upper($1) OR upper(new_name) = upper($1))
		AND coord_dimension = $2;
$function$
;

CREATE OR REPLACE FUNCTION public.postgis_typmod_dims(integer)
 RETURNS integer
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$postgis_typmod_dims$function$
;

CREATE OR REPLACE FUNCTION public.postgis_typmod_srid(integer)
 RETURNS integer
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$postgis_typmod_srid$function$
;

CREATE OR REPLACE FUNCTION public.postgis_typmod_type(integer)
 RETURNS text
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$postgis_typmod_type$function$
;

CREATE OR REPLACE FUNCTION public.postgis_version()
 RETURNS text
 LANGUAGE c
 IMMUTABLE
AS '$libdir/postgis-3', $function$postgis_version$function$
;

CREATE OR REPLACE FUNCTION public.postgis_wagyu_version()
 RETURNS text
 LANGUAGE c
 IMMUTABLE
AS '$libdir/postgis-3', $function$postgis_wagyu_version$function$
;

CREATE OR REPLACE FUNCTION public.raster_above(raster, raster)
 RETURNS boolean
 LANGUAGE sql
 IMMUTABLE PARALLEL SAFE STRICT
AS $function$select $1::public.geometry |>> $2::public.geometry$function$
;

CREATE OR REPLACE FUNCTION public.raster_below(raster, raster)
 RETURNS boolean
 LANGUAGE sql
 IMMUTABLE PARALLEL SAFE STRICT
AS $function$select $1::public.geometry <<| $2::public.geometry$function$
;

CREATE OR REPLACE FUNCTION public.raster_contain(raster, raster)
 RETURNS boolean
 LANGUAGE sql
 IMMUTABLE PARALLEL SAFE STRICT
AS $function$select $1::public.geometry ~ $2::public.geometry$function$
;

CREATE OR REPLACE FUNCTION public.raster_contained(raster, raster)
 RETURNS boolean
 LANGUAGE sql
 IMMUTABLE PARALLEL SAFE STRICT
AS $function$select $1::public.geometry OPERATOR(public.@) $2::public.geometry$function$
;

CREATE OR REPLACE FUNCTION public.raster_contained_by_geometry(raster, geometry)
 RETURNS boolean
 LANGUAGE sql
 IMMUTABLE PARALLEL SAFE STRICT
AS $function$select $1::public.geometry OPERATOR(public.@) $2$function$
;

CREATE OR REPLACE FUNCTION public.raster_eq(raster, raster)
 RETURNS boolean
 LANGUAGE sql
 IMMUTABLE PARALLEL SAFE STRICT
AS $function$ SELECT public.raster_hash($1) = public.raster_hash($2) $function$
;

CREATE OR REPLACE FUNCTION public.raster_geometry_contain(raster, geometry)
 RETURNS boolean
 LANGUAGE sql
 IMMUTABLE PARALLEL SAFE STRICT
AS $function$select $1::public.geometry ~ $2$function$
;

CREATE OR REPLACE FUNCTION public.raster_geometry_overlap(raster, geometry)
 RETURNS boolean
 LANGUAGE sql
 IMMUTABLE PARALLEL SAFE STRICT
AS $function$select $1::public.geometry OPERATOR(public.&&) $2$function$
;

CREATE OR REPLACE FUNCTION public.raster_hash(raster)
 RETURNS integer
 LANGUAGE internal
 IMMUTABLE PARALLEL SAFE STRICT
AS $function$hashvarlena$function$
;

CREATE OR REPLACE FUNCTION public.raster_in(cstring)
 RETURNS raster
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis_raster-3', $function$RASTER_in$function$
;

CREATE OR REPLACE FUNCTION public.raster_left(raster, raster)
 RETURNS boolean
 LANGUAGE sql
 IMMUTABLE PARALLEL SAFE STRICT
AS $function$select $1::public.geometry << $2::public.geometry$function$
;

CREATE OR REPLACE FUNCTION public.raster_out(raster)
 RETURNS cstring
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis_raster-3', $function$RASTER_out$function$
;

CREATE OR REPLACE FUNCTION public.raster_overabove(raster, raster)
 RETURNS boolean
 LANGUAGE sql
 IMMUTABLE PARALLEL SAFE STRICT
AS $function$select $1::public.geometry |&> $2::public.geometry$function$
;

CREATE OR REPLACE FUNCTION public.raster_overbelow(raster, raster)
 RETURNS boolean
 LANGUAGE sql
 IMMUTABLE PARALLEL SAFE STRICT
AS $function$select $1::public.geometry &<| $2::public.geometry$function$
;

CREATE OR REPLACE FUNCTION public.raster_overlap(raster, raster)
 RETURNS boolean
 LANGUAGE sql
 IMMUTABLE PARALLEL SAFE STRICT
AS $function$select $1::public.geometry OPERATOR(public.&&) $2::public.geometry$function$
;

CREATE OR REPLACE FUNCTION public.raster_overleft(raster, raster)
 RETURNS boolean
 LANGUAGE sql
 IMMUTABLE PARALLEL SAFE STRICT
AS $function$select $1::public.geometry &< $2::public.geometry$function$
;

CREATE OR REPLACE FUNCTION public.raster_overright(raster, raster)
 RETURNS boolean
 LANGUAGE sql
 IMMUTABLE PARALLEL SAFE STRICT
AS $function$select $1::public.geometry &> $2::public.geometry$function$
;

CREATE OR REPLACE FUNCTION public.raster_right(raster, raster)
 RETURNS boolean
 LANGUAGE sql
 IMMUTABLE PARALLEL SAFE STRICT
AS $function$select $1::public.geometry >> $2::public.geometry$function$
;

CREATE OR REPLACE FUNCTION public.raster_same(raster, raster)
 RETURNS boolean
 LANGUAGE sql
 IMMUTABLE PARALLEL SAFE STRICT
AS $function$select $1::public.geometry ~= $2::public.geometry$function$
;

CREATE OR REPLACE FUNCTION public.recalculate_elevation_data(geometry geometry)
 RETURNS TABLE(elevation_gain real, elevation_loss real)
 LANGUAGE plpgsql
AS $function$ DECLARE total_gain real := 0; total_loss real := 0; prev_elevation real; curr_elevation real; point_geom geometry; BEGIN FOR i IN 1..ST_NPoints($1) LOOP point_geom := ST_PointN($1, i); curr_elevation := ST_Z(point_geom); IF i > 1 THEN IF curr_elevation > prev_elevation THEN total_gain := total_gain + (curr_elevation - prev_elevation); ELSIF curr_elevation < prev_elevation THEN total_loss := total_loss + (prev_elevation - curr_elevation); END IF; END IF; prev_elevation := curr_elevation; END LOOP; RETURN QUERY SELECT total_gain, total_loss; END; $function$
;

CREATE OR REPLACE FUNCTION public.show_routing_summary()
 RETURNS TABLE(function_name text, version text, description text)
 LANGUAGE plpgsql
AS $function$ BEGIN RETURN QUERY VALUES ('generate_routing_nodes_native', 'v1', 'Original version - creates nodes at trail endpoints'), ('generate_routing_nodes_native_v2', 'v2', 'Latest version - creates nodes at trail endpoints with improved clustering'), ('generate_routing_edges_native', 'v1', 'Original version - creates edges between nodes'), ('generate_routing_edges_native_v2', 'v2', 'Latest version - creates edges between nodes with improved tolerance handling'), ('cleanup_routing_graph', 'v1', 'Cleans up orphaned nodes and edges'), ('show_routing_summary', 'v1', 'Shows available routing functions and versions'); END; $function$
;

CREATE OR REPLACE FUNCTION public.soundex(text)
 RETURNS text
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/fuzzystrmatch', $function$soundex$function$
;

CREATE OR REPLACE FUNCTION public.spheroid_in(cstring)
 RETURNS spheroid
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$ellipsoid_in$function$
;

CREATE OR REPLACE FUNCTION public.spheroid_out(spheroid)
 RETURNS cstring
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis-3', $function$ellipsoid_out$function$
;

CREATE OR REPLACE FUNCTION public.st_3dclosestpoint(geom1 geometry, geom2 geometry)
 RETURNS geometry
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT COST 250
AS '$libdir/postgis-3', $function$LWGEOM_closestpoint3d$function$
;

CREATE OR REPLACE FUNCTION public.st_3ddfullywithin(geom1 geometry, geom2 geometry, double precision)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT COST 5000 SUPPORT postgis_index_supportfn
AS '$libdir/postgis-3', $function$LWGEOM_dfullywithin3d$function$
;

CREATE OR REPLACE FUNCTION public.st_3ddistance(geom1 geometry, geom2 geometry)
 RETURNS double precision
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT COST 250
AS '$libdir/postgis-3', $function$ST_3DDistance$function$
;

CREATE OR REPLACE FUNCTION public.st_3ddwithin(geom1 geometry, geom2 geometry, double precision)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT COST 5000 SUPPORT postgis_index_supportfn
AS '$libdir/postgis-3', $function$LWGEOM_dwithin3d$function$
;

CREATE OR REPLACE FUNCTION public.st_3dintersects(geom1 geometry, geom2 geometry)
 RETURNS boolean
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT COST 5000 SUPPORT postgis_index_supportfn
AS '$libdir/postgis-3', $function$ST_3DIntersects$function$
;

CREATE OR REPLACE FUNCTION public.st_3dlength(geometry)
 RETURNS double precision
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT COST 50
AS '$libdir/postgis-3', $function$LWGEOM_length_linestring$function$
;

CREATE OR REPLACE FUNCTION public.st_3dlineinterpolatepoint(geometry, double precision)
 RETURNS geometry
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT COST 50
AS '$libdir/postgis-3', $function$ST_3DLineInterpolatePoint$function$
;

CREATE OR REPLACE FUNCTION public.st_3dlongestline(geom1 geometry, geom2 geometry)
 RETURNS geometry
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT COST 250
AS '$libdir/postgis-3', $function$LWGEOM_longestline3d$function$
;

CREATE OR REPLACE FUNCTION public.st_3dmakebox(geom1 geometry, geom2 geometry)
 RETURNS box3d
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT COST 50
AS '$libdir/postgis-3', $function$BOX3D_construct$function$
;

CREATE OR REPLACE FUNCTION public.st_3dmaxdistance(geom1 geometry, geom2 geometry)
 RETURNS double precision
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT COST 250
AS '$libdir/postgis-3', $function$LWGEOM_maxdistance3d$function$
;

CREATE OR REPLACE FUNCTION public.st_3dperimeter(geometry)
 RETURNS double precision
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT COST 50
AS '$libdir/postgis-3', $function$LWGEOM_perimeter_poly$function$
;

CREATE OR REPLACE FUNCTION public.st_3dshortestline(geom1 geometry, geom2 geometry)
 RETURNS geometry
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT COST 250
AS '$libdir/postgis-3', $function$LWGEOM_shortestline3d$function$
;

CREATE OR REPLACE FUNCTION public.st_addband(torast raster, fromrasts raster[], fromband integer DEFAULT 1, torastindex integer DEFAULT NULL::integer)
 RETURNS raster
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE
AS '$libdir/postgis_raster-3', $function$RASTER_addBandRasterArray$function$
;

CREATE OR REPLACE FUNCTION public.st_addband(rast raster, addbandargset addbandarg[])
 RETURNS raster
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT
AS '$libdir/postgis_raster-3', $function$RASTER_addBand$function$
;

CREATE OR REPLACE FUNCTION public.st_addband(torast raster, fromrast raster, fromband integer DEFAULT 1, torastindex integer DEFAULT NULL::integer)
 RETURNS raster
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE
AS '$libdir/postgis_raster-3', $function$RASTER_copyBand$function$
;

CREATE OR REPLACE FUNCTION public.st_addband(rast raster, index integer, pixeltype text, initialvalue double precision DEFAULT '0'::numeric, nodataval double precision DEFAULT NULL::double precision)
 RETURNS raster
 LANGUAGE sql
 IMMUTABLE PARALLEL SAFE
AS $function$ SELECT  public.ST_addband($1, ARRAY[ROW($2, $3, $4, $5)]::public.addbandarg[]) $function$
;

CREATE OR REPLACE FUNCTION public.st_addband(rast raster, index integer, outdbfile text, outdbindex integer[], nodataval double precision DEFAULT NULL::double precision)
 RETURNS raster
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE
AS '$libdir/postgis_raster-3', $function$RASTER_addBandOutDB$function$
;

CREATE OR REPLACE FUNCTION public.st_addband(rast raster, outdbfile text, outdbindex integer[], index integer DEFAULT NULL::integer, nodataval double precision DEFAULT NULL::double precision)
 RETURNS raster
 LANGUAGE sql
 IMMUTABLE PARALLEL SAFE
AS $function$ SELECT public.ST_AddBand($1, $4, $2, $3, $5) $function$
;

CREATE OR REPLACE FUNCTION public.st_addband(rast raster, pixeltype text, initialvalue double precision DEFAULT '0'::numeric, nodataval double precision DEFAULT NULL::double precision)
 RETURNS raster
 LANGUAGE sql
 IMMUTABLE PARALLEL SAFE
AS $function$ SELECT  public.ST_addband($1, ARRAY[ROW(NULL, $2, $3, $4)]::public.addbandarg[]) $function$
;

CREATE OR REPLACE FUNCTION public.st_addmeasure(geometry, double precision, double precision)
 RETURNS geometry
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT COST 250
AS '$libdir/postgis-3', $function$ST_AddMeasure$function$
;

CREATE OR REPLACE FUNCTION public.st_addpoint(geom1 geometry, geom2 geometry)
 RETURNS geometry
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT COST 50
AS '$libdir/postgis-3', $function$LWGEOM_addpoint$function$
;

CREATE OR REPLACE FUNCTION public.st_addpoint(geom1 geometry, geom2 geometry, integer)
 RETURNS geometry
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT COST 50
AS '$libdir/postgis-3', $function$LWGEOM_addpoint$function$
;

CREATE OR REPLACE FUNCTION public.st_affine(geometry, double precision, double precision, double precision, double precision, double precision, double precision, double precision, double precision, double precision, double precision, double precision, double precision)
 RETURNS geometry
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT COST 50
AS '$libdir/postgis-3', $function$LWGEOM_affine$function$
;

CREATE OR REPLACE FUNCTION public.st_affine(geometry, double precision, double precision, double precision, double precision, double precision, double precision)
 RETURNS geometry
 LANGUAGE sql
 IMMUTABLE PARALLEL SAFE STRICT COST 50
AS $function$SELECT public.ST_Affine($1,  $2, $3, 0,  $4, $5, 0,  0, 0, 1,  $6, $7, 0)$function$
;

CREATE OR REPLACE FUNCTION public.st_angle(line1 geometry, line2 geometry)
 RETURNS double precision
 LANGUAGE sql
 IMMUTABLE PARALLEL SAFE STRICT COST 50
AS $function$SELECT public.ST_Angle(public.St_StartPoint($1), public.ST_EndPoint($1), public.ST_StartPoint($2), public.ST_EndPoint($2))$function$
;

CREATE OR REPLACE FUNCTION public.st_angle(pt1 geometry, pt2 geometry, pt3 geometry, pt4 geometry DEFAULT '0101000000000000000000F87F000000000000F87F'::geometry)
 RETURNS double precision
 LANGUAGE c
 IMMUTABLE PARALLEL SAFE STRICT COST 50
AS '$libdir/postgis-3', $function$LWGEOM_angle$function$
;

CREATE OR REPLACE FUNCTION public.st_approxcount(rast raster, nband integer, sample_percent double precision)
 RETURNS bigint
 LANGUAGE sql
 IMMUTABLE PARALLEL SAFE STRICT
AS $function$ SELECT public._ST_count($1, $2, TRUE, $3) $function$
;

CREATE OR REPLACE FUNCTION public.st_approxcount(rast raster, nband integer DEFAULT 1, exclude_nodata_value boolean DEFAULT true, sample_percent double precision DEFAULT 0.1)
 RETURNS bigint
 LANGUAGE sql
 IMMUTABLE PARALLEL SAFE STRICT
AS $function$ SELECT public._ST_count($1, $2, $3, $4) $function$
;

CREATE OR REPLACE FUNCTION public.st_approxcount(rast raster, sample_percent double precision)
 RETURNS bigint
 LANGUAGE sql
 IMMUTABLE PARALLEL SAFE STRICT
AS $function$ SELECT public._ST_count($1, 1, TRUE, $2) $function$
;

CREATE OR REPLACE FUNCTION public.st_approxcount(rast raster, exclude_nodata_value boolean, sample_percent double precision DEFAULT 0.1)
 RETURNS bigint
 LANGUAGE sql
 IMMUTABLE PARALLEL SAFE STRICT
AS $function$ SELECT public._ST_count($1, 1, $2, $3) $function$
;

CREATE OR REPLACE FUNCTION public.st_approxhistogram(rast raster, nband integer DEFAULT 1, exclude_nodata_value boolean DEFAULT true, sample_percent double precision DEFAULT 0.1, bins integer DEFAULT 0, width double precision[] DEFAULT NULL::double precision[], "right" boolean DEFAULT false, OUT min double precision, OUT max double precision, OUT count bigint, OUT percent double precision)
 RETURNS SETOF record
 LANGUAGE sql
 IMMUTABLE PARALLEL SAFE
AS $function$ SELECT min, max, count, percent FROM public._ST_histogram($1, $2, $3, $4, $5, $6, $7) $function$
;

CREATE OR REPLACE FUNCTION public.st_approxhistogram(rast raster, nband integer, sample_percent double precision, bins integer, "right" boolean, OUT min double precision, OUT max double precision, OUT count bigint, OUT percent double precision)
 RETURNS SETOF record
 LANGUAGE sql
 IMMUTABLE PARALLEL SAFE STRICT
AS $function$ SELECT min, max, count, percent FROM public._ST_histogram($1, $2, TRUE, $3, $4, NULL, $5) $function$
;

CREATE OR REPLACE FUNCTION public.st_approxhistogram(rast raster, nband integer, sample_percent double precision, bins integer, width double precision[] DEFAULT NULL::double precision[], "right" boolean DEFAULT false, OUT min double precision, OUT max double precision, OUT count bigint, OUT percent double precision)
 RETURNS SETOF record
 LANGUAGE sql
 IMMUTABLE PARALLEL SAFE STRICT
AS $function$ SELECT min, max, count, percent FROM public._ST_histogram($1, $2, TRUE, $3, $4, $5, $6) $function$
;

CREATE OR REPLACE FUNCTION public.st_approxhistogram(rast raster, sample_percent double precision, OUT min double precision, OUT max double precision, OUT count bigint, OUT percent double precision)
 RETURNS SETOF record
 LANGUAGE sql
 IMMUTABLE PARALLEL SAFE STRICT
AS $function$ SELECT min, max, count, percent FROM public._ST_histogram($1, 1, TRUE, $2, 0, NULL, FALSE) $function$
;

CREATE OR REPLACE FUNCTION public.st_approxhistogram(rast raster, nband integer, sample_percent double precision, OUT min double precision, OUT max double precision, OUT count bigint, OUT percent double precision)
 RETURNS SETOF record
 LANGUAGE sql
 IMMUTABLE PARALLEL SAFE STRICT
AS $function$ SELECT min, max, count, percent FROM public._ST_histogram($1, $2, TRUE, $3, 0, NULL, FALSE) $function$
;

CREATE OR REPLACE FUNCTION public.st_approxhistogram(rast raster, nband integer, exclude_nodata_value boolean, sample_percent double precision, bins integer, "right" boolean, OUT min double precision, OUT max double precision, OUT count bigint, OUT percent double precision)
 RETURNS SETOF record
 LANGUAGE sql
 IMMUTABLE PARALLEL SAFE STRICT
AS $function$ SELECT min, max, count, percent FROM public._ST_histogram($1, $2, $3, $4, $5, NULL, $6) $function$
;

CREATE OR REPLACE FUNCTION public.st_approxquantile(rast raster, nband integer, sample_percent double precision, quantiles double precision[] DEFAULT NULL::double precision[], OUT quantile double precision, OUT value double precision)
 RETURNS SETOF record
 LANGUAGE sql
 IMMUTABLE PARALLEL SAFE
AS $function$ SELECT public._ST_quantile($1, $2, TRUE, $3, $4) $function$
;

CREATE OR REPLACE FUNCTION public.st_approxquantile(rast raster, quantiles double precision[], OUT quantile double precision, OUT value double precision)
 RETURNS SETOF record
 LANGUAGE sql
 IMMUTABLE PARALLEL SAFE STRICT
AS $function$ SELECT public._ST_quantile($1, 1, TRUE, 0.1, $2) $function$
;

CREATE OR REPLACE FUNCTION public.st_approxquantile(rast raster, nband integer, exclude_nodata_value boolean, sample_percent double precision, quantile double precision)
 RETURNS double precision
 LANGUAGE sql
 IMMUTABLE PARALLEL SAFE STRICT
AS $function$ SELECT ( public._ST_quantile($1, $2, $3, $4, ARRAY[$5]::double precision[])).value $function$
;

CREATE OR REPLACE FUNCTION public.st_approxquantile(rast raster, nband integer, sample_percent double precision, quantile double precision)
 RETURNS double precision
 LANGUAGE sql
 IMMUTABLE PARALLEL SAFE STRICT
AS $function$ SELECT ( public._ST_quantile($1, $2, TRUE, $3, ARRAY[$4]::double precision[])).value $function$
;

