Chapter: Appendix C. exfmtDIF.pl

Appendix C. exfmtDIF.pl
The following PERL program will parse the output of the SQL snapshot and convert the information to comma-delimited format so that it can be imported into a spreadsheet.
#!/usr/bin/perl
#
# exfmtDIF.pl - Find differences between access plans obtained by
# the db2exfmt utility
#
# Description:
# exfmtDIF will identify differences in two
# access plans obtained using the db2exfmt tool with -g option.
#
# Details:
# For each statement that is the same in the two plans,
# retreive the access plan and compare them.
#
# - If the second file contains a query not found in the first,
# the difference will not be revealed.
#
use English;
if (scalar(@ARGV) != 2) {
print "$PROGRAM_NAME requires 2 plans to compare\n";
exit;
}
$filename1 = @ARGV[0];
$filename2 = @ARGV[1];
open(FILE1, "<$filename1");
open(FILE2, "<$filename2");
@file1 = <FILE1>;
@file2 = <FILE2>;
close(FILE1);
close(FILE2);
main();
#
# Main body of program. Gets the statements and plans for each
# file and compares queries and plans to find differences
#
sub main2
{
my(@queries1) = get_statements(@file1);
my(@queries2) = get_statements(@file2);
my(@plans1) = get_plans(@file1);
my(@plans2) = get_plans(@file2);
my($querycount1) = $#queries1+1;
my($querycount2) = $#queries2+1;
my($index1) = 0;
my($found) = 0;
# For each query from the first file
while ($index1 < $querycount1)
{
my($index2) = 0;
# Compare to every query in the second file
while ($index2 < $querycount2)
{
# If the queries are the same, compare the associated access
# plans
if (@queries1[$index1] eq @queries2[$index2])
{
my($i) = $index1 + 1;
my($j) = $index2 + 1;
print "$filename1, plan \#$i vs. $filename2, plan \#$j: ";
if (compare_plans(@plans1[$index1], @plans2[$index2]))
{
print "same\n";
}
else
{
print "**DIFFERENT**\n";
print "$filename1, plan \#$i:\n";
my($fmtplan) = fmt_plan(@plans1[$index1]);
print "$fmtplan\n";
print "$filename2, plan \#$j:\n";
$fmtplan = fmt_plan(@plans2[$index2]);
print "$fmtplan\n";
}
$index2 = $querycount2;
$found = 1;
}
$index2++;
}
if ($found == 0)
{
print "QUERY:\n@queries1[$index1]\n\n not found in $filename2";
}
$index1++;
}
}
#
# Get all the 'Original Statement' queries from the
# given array of text
#
sub get_statements
{
my(@data) = @_;
my(@stmts) = ();
while (@data)
{
if (shift(@data) =~ /^Original Statement:/)
{
shift(@data);
my($line) = shift(@data);
# Get the original statement block
my(@stmt) = ();
while ($line !~ /^\s*$/)
{
push(@stmt, $line);
$line = shift(@data);
}
push(@stmt, "\n");
push(@stmts,join(' ',@stmt));
}
}
return @stmts;
}
#
# Get all the access plans from the inputted text array
#
sub get_plans
{
my(@data) = @_;
my(@plans) = ();
while (@data)
{
if (shift(@data) =~ /^Access Plan:/)
{
shift(@data);
shift(@data);
shift(@data);
shift(@data);
my($line) = shift(@data);
# Get the access plan block
my(@plan) = ();
while ($line !~ /^\s*$/)
{
push(@plan, $line);
$line = shift(@data);
}
push(@plan, "\n");
push(@plans,join(' ',@plan));
}
}
return @plans;
}
#
# Compares the two access plan strings
# Returns 1 if they are the same, otherwise, returns 0
#
sub compare_plans
{
my($plan1,$plan2) = @_;
$plan1 = fmt_plan($plan1);
$plan2 = fmt_plan($plan2);
if ($plan1 eq $plan2)
{
return 1;
}
else
{
return 0;
}
}
#
# Formats an access plan string to discard information
# that we do not care about when comparing access plans
#
sub fmt_plan
{
my($plan) = @_;
$plan =~ s/\d*e\+\d*//g; # take out exponent
$plan =~ s/[^a-zA-Z]\d/ /g;# replace numbers not beside a letter with blanks
$plan =~ s/[^a-zA-Z]\d/ /g;# replace numbers not beside a letter with blanks
$plan =~ s/\./ /g; # replace periods with blanks
$plan =~ s/\(/ /g; # replace brackets with blanks
$plan =~ s/\)/ /g;
$plan =~ s/\n\s+\n/\n/g; # take out blank lines
return $plan;
}
![]() | Advanced dba certification guide and reference |






