1#! /usr/bin/perl
2
3# Read the output of async_queries.c. Run the queries again serially, using
4# the normal (not asynchronous) API. Compare the two results for correctness.
5
6use strict;
7use warnings;
8
9use DBI;
10
11my $D= [];
12
13die "Usage: $0 <host> <user> <password> <database>\n"
14    unless @ARGV == 4;
15
16my $dbh= DBI->connect("DBI:mysql:database=$ARGV[3];host=$ARGV[0]",
17                      $ARGV[1], $ARGV[2],
18                      { RaiseError => 1, PrintError => 0 });
19
20while (<STDIN>) {
21  chomp;
22  if (/^([0-9]+) ! (.*);$/) {
23    my ($index, $query)= ($1, $2);
24    $D->[$index]= { QUERY => $query, OUTPUT => [] };
25  } elsif (/^([0-9]+) - (.*)$/) {
26    my ($index, $data)= ($1, $2);
27    push @{$D->[$index]{OUTPUT}}, $data;
28  } elsif (/^([0-9]+) \| Error: (.*)$/) {
29    my ($index, $errmsg)= ($1, $2);
30    my $rows;
31    my $res= eval {
32      my $stm= $dbh->prepare($D->[$index]{QUERY});
33      $stm->execute();
34      $rows= $stm->fetchall_arrayref();
35      1;
36    };
37    if ($res) {
38      die "Query $index succeeded, but should have failed with error.\nquery=$D->[$index]{QUERY}\nerror=$errmsg\n";
39    }
40    my $errmsg2= $@;
41    if ($errmsg2 =~ /^DBD::.*failed: (.*) at .*$/s) {
42      $errmsg2= $1;
43    } else {
44      die "Unexpected DBD error message format: '$errmsg2'\n";
45    }
46    if ($errmsg2 ne $errmsg) {
47      die "Query $index failed with different error message\nquery=$D->[$index]{QUERY}\nerror1=$errmsg\nerror2=$errmsg2\n";
48    }
49    print "OK $index\n";
50    delete $D->[$index];
51  } elsif (/^([0-9]+) \| EOF$/) {
52    my $index= $1;
53    my $rows;
54    my $res= eval {
55      my $stm= $dbh->prepare($D->[$index]{QUERY});
56      $stm->execute();
57      $rows= $stm->fetchall_arrayref();
58      1;
59    };
60    if (!$res) {
61      die "Query $index failed, but should have succeeded.\nquery=$D->[$index]{QUERY}\nerror=$@\n";
62    }
63    my $result_string= join("\n", sort @{$D->[$index]{OUTPUT}});
64    my $result_string2= join("\n", sort(map(join("\t", map((defined($_) ? $_ : "(null)"), @$_)), @$rows)));
65    if ($result_string ne $result_string2) {
66      die "Query $index result difference.\nquery=$D->[$index]{QUERY}\noutput1=\n$$result_string\noutput2=\n$result_string2\n";
67    }
68    delete $D->[$index];
69  } else {
70    die "Unexpected line: '$_'\n";
71  }
72}
73$dbh->disconnect();
74