2010-01-20 20:17:09 +00:00
|
|
|
#!/usr/bin/perl
|
2005-06-06 16:49:41 +00:00
|
|
|
|
2011-12-13 09:16:09 +00:00
|
|
|
#
|
|
|
|
# PostGIS - Spatial Types for PostgreSQL
|
|
|
|
# http://postgis.refractions.net
|
|
|
|
#
|
|
|
|
# Copyright (C) 2009-2010 Paul Ramsey <pramsey@opengeo.org>
|
|
|
|
# Copyright (C) 2005 Refractions Research Inc.
|
|
|
|
#
|
|
|
|
# This is free software; you can redistribute and/or modify it under
|
|
|
|
# the terms of the GNU General Public Licence. See the COPYING file.
|
|
|
|
#
|
|
|
|
|
2005-12-16 08:33:04 +00:00
|
|
|
#
|
|
|
|
# This script produces an .sql file containing
|
|
|
|
# CREATE OR REPLACE calls for each function
|
2009-11-13 20:04:37 +00:00
|
|
|
# in postgis.sql
|
2005-12-16 08:33:04 +00:00
|
|
|
#
|
|
|
|
# In addition, the transaction contains
|
|
|
|
# a check for Major postgis_lib_version()
|
|
|
|
# to match the one contained in lwpostgis.sql
|
|
|
|
#
|
|
|
|
# This never happens by just running make install
|
|
|
|
# as MODULE_FILENAME contains SO_MAJOR under
|
|
|
|
# all architectures.
|
|
|
|
#
|
|
|
|
#
|
|
|
|
|
2005-06-06 16:49:41 +00:00
|
|
|
eval "exec perl -w $0 $@"
|
|
|
|
if (0);
|
|
|
|
|
|
|
|
use strict;
|
2011-12-13 09:59:01 +00:00
|
|
|
use warnings;
|
2005-06-06 16:49:41 +00:00
|
|
|
|
2009-11-13 22:13:17 +00:00
|
|
|
#
|
|
|
|
# Conditionally upgraded types and operators. Only include these
|
|
|
|
# if the major numbers in version_from are less than the version_to
|
|
|
|
# number.
|
|
|
|
#
|
|
|
|
my $objs = {
|
|
|
|
"104" => {
|
|
|
|
"types" => {
|
|
|
|
"box3d_extent" => 1,
|
|
|
|
"pgis_abs" => 1
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"105" => {
|
|
|
|
"operators" => {
|
|
|
|
"geography >" => 1,
|
|
|
|
"geography >=" => 1,
|
|
|
|
"geography =" => 1,
|
|
|
|
"geography <=" => 1,
|
|
|
|
"geography <" => 1,
|
|
|
|
"geography &&" => 1
|
|
|
|
},
|
|
|
|
"opclasses" => {
|
|
|
|
"gist_geography_ops" => 1,
|
|
|
|
"btree_geography_ops" => 1
|
|
|
|
},
|
2010-03-09 00:31:26 +00:00
|
|
|
"views" => {
|
|
|
|
"geography_columns" => 1
|
|
|
|
},
|
2009-11-13 22:13:17 +00:00
|
|
|
"types" => {
|
|
|
|
"geography" => 1,
|
|
|
|
"gidx" => 1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
#
|
|
|
|
# Commandline argument handling
|
|
|
|
#
|
2005-10-26 11:07:55 +00:00
|
|
|
($#ARGV == 0) ||
|
2009-11-13 22:13:17 +00:00
|
|
|
die "Usage: perl postgis_proc_upgrade.pl <postgis.sql> <version_from> [<schema>]\nCreates a new SQL script to upgrade all of the PostGIS functions.\n"
|
|
|
|
if ( @ARGV < 1 || @ARGV > 3 );
|
2005-06-06 16:49:41 +00:00
|
|
|
|
2009-11-13 22:13:17 +00:00
|
|
|
my $sql_file = $ARGV[0];
|
|
|
|
my $version_to = "";
|
|
|
|
my $version_to_num = 0;
|
|
|
|
my $version_from = $ARGV[1];
|
|
|
|
my $version_from_num = 0;
|
|
|
|
my $schema = "";
|
|
|
|
$schema = $ARGV[2] if @ARGV > 2;
|
2005-06-06 16:49:41 +00:00
|
|
|
|
2009-11-13 22:13:17 +00:00
|
|
|
if ( $version_from =~ /^(\d+)\.(\d+)/ )
|
|
|
|
{
|
|
|
|
$version_from_num = 100 * $1 + $2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
die "Version from number invalid, must be of form X.X\n";
|
|
|
|
}
|
2005-06-06 16:49:41 +00:00
|
|
|
|
2009-11-13 22:13:17 +00:00
|
|
|
die "Unable to open input SQL file $sql_file\n"
|
|
|
|
if ( ! -f $sql_file );
|
2005-10-26 11:07:55 +00:00
|
|
|
|
2009-11-13 22:13:17 +00:00
|
|
|
#
|
|
|
|
# Search the SQL file for the target version number (the
|
|
|
|
# version we are upgrading *to*.
|
|
|
|
#
|
|
|
|
open( INPUT, $sql_file ) || die "Couldn't open file: $sql_file\n";
|
2005-06-06 16:49:41 +00:00
|
|
|
while(<INPUT>)
|
|
|
|
{
|
2005-12-16 01:41:44 +00:00
|
|
|
#
|
|
|
|
# Since 1.1.0 scripts/lib/release versions are the same
|
|
|
|
#
|
2009-11-13 20:04:37 +00:00
|
|
|
if (/INSTALL VERSION: (.*)/)
|
2005-06-06 16:49:41 +00:00
|
|
|
{
|
2009-11-13 22:13:17 +00:00
|
|
|
$version_to = $1;
|
2009-11-13 20:04:37 +00:00
|
|
|
last;
|
2005-06-06 16:49:41 +00:00
|
|
|
}
|
|
|
|
}
|
2009-11-13 20:04:37 +00:00
|
|
|
close(INPUT);
|
2005-06-06 16:49:41 +00:00
|
|
|
|
2009-11-13 22:13:17 +00:00
|
|
|
die "Unable to locate target new version number in $sql_file\n"
|
|
|
|
if( ! $version_to );
|
|
|
|
|
|
|
|
if ( $version_to =~ /(\d+)\.(\d+)\..*/ )
|
|
|
|
{
|
|
|
|
$version_to = $1 . "." . $2;
|
|
|
|
$version_to_num = 100 * $1 + $2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
die "Version to number invalid, must be of form X.X.X\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
print qq{
|
|
|
|
--
|
|
|
|
-- UPGRADE SCRIPT FROM PostGIS $version_from TO PostGIS $version_to
|
|
|
|
--
|
|
|
|
|
|
|
|
};
|
2009-06-08 23:21:55 +00:00
|
|
|
|
2009-11-13 22:13:17 +00:00
|
|
|
print "BEGIN;\n";
|
|
|
|
print "SET search_path TO $schema;\n" if $schema;
|
|
|
|
|
|
|
|
#
|
|
|
|
# Add in the conditional check function to ensure this script is
|
|
|
|
# not being applied to a major version update.
|
|
|
|
#
|
2005-06-06 16:49:41 +00:00
|
|
|
while(<DATA>)
|
|
|
|
{
|
2009-11-13 22:13:17 +00:00
|
|
|
s/NEWVERSION/$version_to/g;
|
2005-06-06 16:49:41 +00:00
|
|
|
print;
|
|
|
|
}
|
|
|
|
|
2009-11-13 22:13:17 +00:00
|
|
|
#
|
|
|
|
# Go through the SQL file and strip out objects that cannot be
|
|
|
|
# applied to an existing, loaded database: types and operators
|
|
|
|
# and operator classes that have already been defined.
|
|
|
|
#
|
|
|
|
open( INPUT, $sql_file ) || die "Couldn't open file: $sql_file\n";
|
2005-06-06 16:49:41 +00:00
|
|
|
while(<INPUT>)
|
|
|
|
{
|
2009-11-13 22:13:17 +00:00
|
|
|
|
2009-11-14 00:40:37 +00:00
|
|
|
next if ( /^\-\-/ );
|
|
|
|
|
|
|
|
#
|
|
|
|
# Allow through deprecations from postgis_drop.sql
|
|
|
|
#
|
|
|
|
print if ( /^drop function if exists/i );
|
|
|
|
print if ( /^drop aggregate if exists/i );
|
|
|
|
|
|
|
|
if ( /^create or replace function/i )
|
2005-06-06 16:49:41 +00:00
|
|
|
{
|
|
|
|
print $_;
|
2009-11-14 00:40:37 +00:00
|
|
|
my $endfunc = 0;
|
2005-06-06 16:49:41 +00:00
|
|
|
while(<INPUT>)
|
|
|
|
{
|
|
|
|
print $_;
|
2009-11-14 00:40:37 +00:00
|
|
|
$endfunc = 1 if /^\s*LANGUAGE /;
|
|
|
|
last if ( $endfunc && /\;/ );
|
2005-06-06 16:49:41 +00:00
|
|
|
}
|
|
|
|
}
|
2005-06-10 16:27:19 +00:00
|
|
|
|
2009-11-14 00:40:37 +00:00
|
|
|
if ( /^create type (\w+)/i )
|
2009-06-08 23:21:55 +00:00
|
|
|
{
|
|
|
|
my $newtype = $1;
|
2009-11-13 20:04:37 +00:00
|
|
|
my $def .= $_;
|
2009-06-08 23:21:55 +00:00
|
|
|
while(<INPUT>)
|
|
|
|
{
|
2009-11-13 20:04:37 +00:00
|
|
|
$def .= $_;
|
2009-11-14 00:40:37 +00:00
|
|
|
last if /\)/;
|
2009-06-08 23:21:55 +00:00
|
|
|
}
|
2009-11-13 22:13:17 +00:00
|
|
|
my $ver = $version_from_num + 1;
|
|
|
|
while( $version_from_num < $version_to_num && $ver <= $version_to_num )
|
|
|
|
{
|
|
|
|
if( $objs->{$ver}->{"types"}->{$newtype} )
|
|
|
|
{
|
|
|
|
print $def;
|
|
|
|
last;
|
|
|
|
}
|
|
|
|
$ver++;
|
|
|
|
}
|
2009-06-08 23:21:55 +00:00
|
|
|
}
|
|
|
|
|
2009-11-13 20:04:37 +00:00
|
|
|
# This code handles casts by dropping and recreating them.
|
|
|
|
if ( /^create cast\s+\(\s*(\w+)\s+as\s+(\w+)\)/i )
|
|
|
|
{
|
|
|
|
my $type1 = $1;
|
|
|
|
my $type2 = $2;
|
|
|
|
my $def = $_;
|
|
|
|
print "DROP CAST IF EXISTS ($type1 AS $type2);\n";
|
|
|
|
print $def;
|
|
|
|
}
|
2009-06-08 23:21:55 +00:00
|
|
|
|
2009-06-03 23:56:23 +00:00
|
|
|
# This code handles aggregates by dropping and recreating them.
|
2009-11-13 20:04:37 +00:00
|
|
|
if ( /^create aggregate\s+(\S+)\s*\(/i )
|
2009-06-03 23:56:23 +00:00
|
|
|
{
|
|
|
|
my $aggname = $1;
|
2009-11-13 22:13:17 +00:00
|
|
|
my $aggtype = 'unknown';
|
2009-06-03 23:56:23 +00:00
|
|
|
my $def = $_;
|
|
|
|
while(<INPUT>)
|
|
|
|
{
|
|
|
|
$def .= $_;
|
2009-11-14 00:40:37 +00:00
|
|
|
$aggtype = $1 if ( /basetype\s*=\s*([^,]*)\s*,/i );
|
|
|
|
last if /\);/;
|
2009-06-03 23:56:23 +00:00
|
|
|
}
|
2009-11-13 22:13:17 +00:00
|
|
|
print "DROP AGGREGATE IF EXISTS $aggname($aggtype);\n";
|
2009-11-13 20:04:37 +00:00
|
|
|
print $def;
|
|
|
|
}
|
|
|
|
|
|
|
|
# This code handles operators by creating them if we are doing a major upgrade
|
|
|
|
if ( /^create operator\s+(\S+)\s*\(/i )
|
|
|
|
{
|
|
|
|
my $opname = $1;
|
2009-11-13 22:13:17 +00:00
|
|
|
my $optype = 'unknown';
|
2009-11-13 20:04:37 +00:00
|
|
|
my $def = $_;
|
|
|
|
while(<INPUT>)
|
|
|
|
{
|
|
|
|
$def .= $_;
|
2009-11-14 00:40:37 +00:00
|
|
|
$optype = $1 if ( /leftarg\s*=\s*(\w+)\s*,/i );
|
|
|
|
last if /\);/;
|
2009-11-13 20:04:37 +00:00
|
|
|
}
|
2009-11-13 22:13:17 +00:00
|
|
|
my $opsig = $optype . " " . $opname;
|
|
|
|
my $ver = $version_from_num + 1;
|
|
|
|
while( $version_from_num < $version_to_num && $ver <= $version_to_num )
|
|
|
|
{
|
|
|
|
if( $objs->{$ver}->{"operators"}->{$opsig} )
|
|
|
|
{
|
|
|
|
print $def;
|
|
|
|
last;
|
|
|
|
}
|
|
|
|
$ver++;
|
|
|
|
}
|
2009-06-03 23:56:23 +00:00
|
|
|
}
|
2005-06-10 16:27:19 +00:00
|
|
|
|
2010-03-09 00:31:26 +00:00
|
|
|
# This code handles view by creating them if we are doing a major upgrade
|
|
|
|
if ( /^create or replace view\s+(\S+)\s*/i )
|
|
|
|
{
|
|
|
|
my $viewname = $1;
|
|
|
|
my $def = $_;
|
|
|
|
while(<INPUT>)
|
|
|
|
{
|
|
|
|
$def .= $_;
|
|
|
|
last if /\;\s*$/;
|
|
|
|
}
|
|
|
|
my $ver = $version_from_num + 1;
|
|
|
|
while( $version_from_num < $version_to_num && $ver <= $version_to_num )
|
|
|
|
{
|
|
|
|
if( $objs->{$ver}->{"views"}->{$viewname} )
|
|
|
|
{
|
|
|
|
print $def;
|
|
|
|
last;
|
|
|
|
}
|
|
|
|
$ver++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-11-13 20:04:37 +00:00
|
|
|
# This code handles operator classes by creating them if we are doing a major upgrade
|
|
|
|
if ( /^create operator class\s+(\w+)\s*/i )
|
|
|
|
{
|
|
|
|
my $opclassname = $1;
|
|
|
|
my $opctype = 'unknown';
|
|
|
|
my $opcidx = 'unknown';
|
|
|
|
my $def = $_;
|
|
|
|
while(<INPUT>)
|
|
|
|
{
|
|
|
|
$def .= $_;
|
2009-11-14 00:40:37 +00:00
|
|
|
$opctype = $1 if ( /for type (\w+) /i );
|
|
|
|
$opcidx = $1 if ( /using (\w+) /i );
|
|
|
|
last if /\);/;
|
2009-11-13 20:04:37 +00:00
|
|
|
}
|
|
|
|
$opctype =~ tr/A-Z/a-z/;
|
|
|
|
$opcidx =~ tr/A-Z/a-z/;
|
2009-11-13 22:13:17 +00:00
|
|
|
my $ver = $version_from_num + 1;
|
|
|
|
while( $version_from_num < $version_to_num && $ver <= $version_to_num )
|
|
|
|
{
|
|
|
|
if( $objs->{$ver}->{"opclasses"}->{$opclassname} )
|
|
|
|
{
|
|
|
|
print $def;
|
|
|
|
last;
|
|
|
|
}
|
|
|
|
$ver++;
|
|
|
|
}
|
2009-11-13 20:04:37 +00:00
|
|
|
}
|
2005-06-06 16:49:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
close( INPUT );
|
|
|
|
|
|
|
|
print "COMMIT;\n";
|
|
|
|
|
|
|
|
1;
|
|
|
|
|
|
|
|
__END__
|
|
|
|
|
2005-12-16 01:41:44 +00:00
|
|
|
CREATE OR REPLACE FUNCTION postgis_major_version_check()
|
2005-06-06 16:49:41 +00:00
|
|
|
RETURNS text
|
|
|
|
AS '
|
|
|
|
DECLARE
|
|
|
|
old_scripts text;
|
|
|
|
new_scripts text;
|
2005-12-16 08:33:04 +00:00
|
|
|
old_maj text;
|
|
|
|
new_maj text;
|
2005-06-06 16:49:41 +00:00
|
|
|
BEGIN
|
2005-12-16 01:48:52 +00:00
|
|
|
--
|
|
|
|
-- This uses postgis_lib_version() rather then
|
|
|
|
-- postgis_scripts_installed() as in 1.0 because
|
|
|
|
-- in the 1.0 => 1.1 transition that would result
|
|
|
|
-- in an impossible upgrade:
|
|
|
|
--
|
|
|
|
-- from 0.3.0 to 1.1.0
|
|
|
|
--
|
|
|
|
-- Next releases will still be ok as
|
|
|
|
-- postgis_lib_version() and postgis_scripts_installed()
|
|
|
|
-- would both return actual PostGIS release number.
|
|
|
|
--
|
2005-12-16 01:41:44 +00:00
|
|
|
SELECT into old_scripts postgis_lib_version();
|
2005-06-06 16:49:41 +00:00
|
|
|
SELECT into new_scripts ''NEWVERSION'';
|
2005-12-16 08:33:04 +00:00
|
|
|
SELECT into old_maj substring(old_scripts from 1 for 2);
|
|
|
|
SELECT into new_maj substring(new_scripts from 1 for 2);
|
2005-06-06 16:49:41 +00:00
|
|
|
|
2005-12-16 08:33:04 +00:00
|
|
|
IF old_maj != new_maj THEN
|
2009-07-08 00:20:48 +00:00
|
|
|
RAISE EXCEPTION ''Upgrade from version % to version % requires a dump/reload. See PostGIS manual for instructions'', old_scripts, new_scripts;
|
2005-06-06 16:49:41 +00:00
|
|
|
ELSE
|
|
|
|
RETURN ''Scripts versions checked for upgrade: ok'';
|
|
|
|
END IF;
|
|
|
|
END
|
|
|
|
'
|
|
|
|
LANGUAGE 'plpgsql';
|
|
|
|
|
2005-12-16 01:41:44 +00:00
|
|
|
SELECT postgis_major_version_check();
|
2005-06-06 16:49:41 +00:00
|
|
|
|
2005-12-16 01:41:44 +00:00
|
|
|
DROP FUNCTION postgis_major_version_check();
|