diff --git a/healpix_alchemy/func.py b/healpix_alchemy/func.py index 35b2e9f..2e49735 100644 --- a/healpix_alchemy/func.py +++ b/healpix_alchemy/func.py @@ -5,4 +5,4 @@ def union(tiles): - return _func.unnest(_func.range_agg(tiles), type_=_Tile) + return _func.multirange_unnest(_func.range_agg(tiles), type_=_Tile) diff --git a/healpix_alchemy/types.py b/healpix_alchemy/types.py index da80aed..e65b50c 100644 --- a/healpix_alchemy/types.py +++ b/healpix_alchemy/types.py @@ -94,3 +94,26 @@ def _create_indices(index, parent): isinstance(index.expressions[0].type, Tile) ): index.dialect_options['postgresql']['using'] = 'spgist' + + +@sa.event.listens_for(sa.Table, 'after_create') +def _after_create_table(target, connection, **kwargs): + """Declare our own version of unnest() with a hardcoded planner row count + estimate that is more appropriate for sky maps. + + FIXME: Remove this when PostgreSQL gets better planner support for + multiranges. + + See https://github.com/skyportal/healpix-alchemy/pull/55. + """ + connection.execute(sa.text( + 'CREATE OR REPLACE FUNCTION multirange_unnest(arg anymultirange)' + ' RETURNS SETOF anyrange' + ' AS $$ select unnest($1); $$' + ' LANGUAGE SQL' + ' IMMUTABLE' + ' PARALLEL SAFE' + ' STRICT' + ' COST 1' + ' ROWS 2000' + ))