

package PostgreSQL::AdjustUpgrade;

use PostgreSQL::Version;

use strict;
use warnings;

# internal utility routine
sub _add_st
{
	my ($res, $db, @st) = @_;
	$res->{$db} ||= [];
	push (@{$res->{$db}},@st);
}

# takes an old_version parameter - what we're upgrading from, gives back a list
# of statements reuired to adjust the old version instance before trying to
# upgrade.

# The old_version is typically  HEAD or REL_?foo_STABLE which is what the
# buildfarm uses, but can also be anything PostgreSQL::Version accepts
# (e.g. output from pg_config --version)

# returns a reference to a hash. The keys are database names and the values are
# arrayrefs to lists of statements to be run in those databases

sub adjustment_statements
{
	my $o_ver = shift;
	my $res = {};
	if ($o_ver eq 'HEAD')
	{
		# upgrading from HEAD to HEAD should require no adjustment
		# and upgrading from HEAD to anything else is not supported
		return $res;
	}
	
	$o_ver =~ s/REL_?(\d+(?:_\d+)?)_STABLE/$1/;
	$o_ver =~ s/_/./;
	my $old_version = PostgreSQL::Version->new($o_ver);
	
	_add_st($res,'postgres',
			"drop database if exists contrib_regression_tsearch2");
	_add_st($res,'regression',
			"drop function if exists oldstyle_length(integer, text)");
	if ($old_version < 11)
	{
		_add_st($res,'regression',
				"drop function if exists public.boxarea(box)",
				"drop function if exists public.funny_dup17()");
	}
	_add_st($res,'contrib_regression_test_extensions',
			"drop extension if exists test_ext7");

	if ($old_version < 12)
	{
		my $nooid_stmt = q{
           DO $stmt$
           DECLARE
              rec text;
           BEGIN
              FOR rec in
                 select oid::regclass::text
                 from pg_class
                 where relname !~ '^pg_'
                    and relhasoids
                    and relkind in ('r','m')
                 order by 1
              LOOP
                 execute 'ALTER TABLE ' || rec || ' SET WITHOUT OIDS';
                 RAISE NOTICE 'removing oids from table %', rec;
              END LOOP;
           END; $stmt$;
        };
		_add_st($res,'regression',$nooid_stmt);
		_add_st($res,'contrib_regression_btree_gist', $nooid_stmt);

		if ($old_version >= 10)
		{
			_add_st($res,"contrib_regression_postgres_fdw",
					"drop foreign table if exists ft_pg_type");
		}
	}
	if ($old_version <= 9.3)
	{
		_add_st($res,'regression',
				"drop table if exists abstime_tbl, reltime_tbl, tinterval_tbl");
	}
	if ($old_version <= 13)
	{
		_add_st($res, 'regression',
				'drop operator if exists #@# (bigint,NONE)',
				'drop operator if exists #%# (bigint,NONE)',
				'drop operator if exists !=- (bigint,NONE)',
				'drop operator if exists #@%# (bigint,NONE)');


		my $regrdb =
		  $old_version <= 9.4
		  ? "contrib_regression"
		  : "contrib_regression_dblink";

		_add_st($res, $regrdb,
				"drop function if exists public.putenv(text)");
	}
	if ($old_version <= 9.4)
	{
		_add_st($res,'regression',
				'drop operator @#@ (NONE, bigint)',
				q{CREATE OPERATOR @#@ (
				    PROCEDURE = factorial,
				    RIGHTARG = bigint 
                  )},
				'drop aggregate if exists public.array_cat_accum(anyarray)',
				q{CREATE AGGREGATE array_larger_accum (anyarray) (
				    sfunc = array_larger,
				    stype = anyarray,
				    initcond = $${}$$
				  )});
	}

	if ($old_version <= 15)
	{
		_add_st($res, 'regression',
				q{alter table if exists public.tab_core_types
                    drop column if exists aclitem},
				'drop table if exists public.gtest_normal_child',
				'drop table if exists public.gtest_normal_child2');
	}

	return $res;
	
};

1;
