????
Current Path : C:/opt/pgsql/utils/ |
Current File : C:/opt/pgsql/utils/create_skip_signatures.pl |
#!/usr/bin/env perl # # PostGIS - Spatial Types for PostgreSQL # http://postgis.net # # Copyright (C) 2023 Sandro Santilli <strk@kbt.io> # # This is free software; you can redistribute and/or modify it under # the terms of the GNU General Public Licence. See the COPYING file. # #--------------------------------------------------------------------- # # This script is aimed at generating a list of objects # signatures used by postgis_restore.pl to decide # which objects belong to PostGIS # #--------------------------------------------------------------------- use warnings; use strict; my $me = $0; my $usage = qq{ Usage: $me [<sqlfile> ...] Reads sql statements from given files or standard input and generates a list of signatures from DROP lines. }; my %reserved_sql_word = ( 'double' => 1, 'character' => 1 ); # Example: # INPUT: inout first double precision, second integer, OUT third text, fourth bool # OUTPUT: first double precision, second integer, fourth bool sub clean_inout_arguments { my @args = @_; my @out; #print "XXX to strip: " . join(',', @args) . "\n"; foreach ( @args ) { my $a = $_; #print " XXX arg: [$a]\n"; # If the arg is composed by multiple words # check for out and inout indicators if ( $a =~ m/([^ ]*) (.*)/ ) { # Skip this arg if out only next if $1 eq 'out'; # Hide the inout indicator $a = $2 if $1 eq 'inout'; } #print " XXX arg became: $a\n"; push @out, $a; } #print "XXX striped: " . join(',', @out) . "\n"; return @out; } # Example: # INPUT: int,named double precision,named text # OUTPUT: int,double precision,text sub strip_argument_names { my @args = @_; my @out; #print "XXX to strip: " . join(',', @args) . "\n"; foreach ( @args ) { my $a = $_; #print " XXX arg: $a\n"; # Drop all but reserved words from multi-word arg while ( $a =~ m/^([^ ]*) (.*)/ ) { last if $reserved_sql_word{$1}; $a = $2; #print " XXX arg became: $a\n"; } push @out, $a; } #print "XXX striped: " . join(',', @out) . "\n"; return @out; } sub canonicalize_args { my @args = @_; my @out; foreach ( @args ) { my $a = $_; $a =~ s/varchar/character varying/g; $a =~ s/float8/double precision/g; $a =~ s/\bint\b/integer/g; $a =~ s/\bint4\b/integer/g; $a =~ s/\bint8\b/bigint/g; $a =~ s/\bchar\b/character/g; $a =~ s/\bbool\b/boolean/g; push @out, $a; } return @out; } sub handle_function_signature { my $line = shift; $line = lc($line); $line =~ s/topology\.//g; $line =~ m/ *([^\( ]*) *\((.*)\)/ or die "Unexpected FUNCTION signature: $line"; my $name = $1; my $args = $2; $args =~ s/\s*$//; # trim trailing blanks $args =~ s/^\s*//; # trim leading blanks my @args = split('\s*,\s*', $args); @args = canonicalize_args(@args); # No inout indicator or out parameters for function signatures my @inonly_args = clean_inout_arguments(@args); # For *function* signature we are supposed to strip argument names my @unnamed_args = strip_argument_names(@inonly_args); print "FUNCTION $name(" . join(', ', @unnamed_args) . ")\n"; } while (<>) { #print "XXX 0 $_"; # type signature if ( /^DROP TYPE IF EXISTS\s\s*([^\s]*)/ ) { my $t = lc($1); $t =~ s/topology\.//g; print "TYPE $t\n"; } # aggregate signature if ( /^DROP AGGREGATE IF EXISTS\s+(.*)\((.*)\)/ ) { my $name = lc($1); my $args = lc($2); s/^\s+//, s/\s+$// for $name; $name =~ s/topology\.//g; $args =~ s/topology\.//g; my @args = split('\s*,\s*', $args); @args = canonicalize_args(@args); # For *aggregate* signature we are supposed to strip # also argument names, which aint easy my @unnamed_args = strip_argument_names(@args); print "AGGREGATE $name(" . join(', ', @unnamed_args) . ")\n"; } # Function signature elsif ( /^DROP FUNCTION IF EXISTS/ ) { my $origline = $_; my $line = $origline; $line =~ s/DROP FUNCTION IF EXISTS //; # We don't want to ALWAYS strip comments # because we might handle 'Replaces' comment # at some point $line =~ s/ *--.*//; handle_function_signature($line); } # Deprecated function signature # EXAMPLE: ALTER FUNCTION _st_concavehull( geometry ) RENAME TO _st_concavehull_deprecated_by_postgis_303; elsif ( /ALTER FUNCTION .* RENAME TO .*_deprecated_by_postgis_/ ) { my $origline = $_; my $line = $origline; $line =~ s/ *ALTER FUNCTION (.*) RENAME TO .*_deprecated_by_postgis_.*/$1/; handle_function_signature($line); } # Deprecated function signature using # _postgis_drop_function_by_signature # EXAMPLE: SELECT _postgis_drop_function_by_signature('pgis_geometry_union_finalfn(internal)'); elsif ( /SELECT _postgis_drop_function_by_signature\('[^']*'/ ) { my $origline = $_; my $line = $origline; $line =~ s/.*SELECT _postgis_drop_function_by_signature\('([^']*)'.*/$1/; handle_function_signature($line); } }