~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to lib/GenTest/Transform.pm

merge from internal tree

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package GenTest::Transform;
 
2
 
 
3
require Exporter;
 
4
@ISA = qw(GenTest);
 
5
 
 
6
use strict;
 
7
 
 
8
use lib 'lib';
 
9
use GenTest;
 
10
use GenTest::Constants;
 
11
 
 
12
use constant TRANSFORMER_QUERIES_PROCESSED      => 0;
 
13
use constant TRANSFORMER_QUERIES_TRANSFORMED    => 1;
 
14
 
 
15
use constant TRANSFORM_OUTCOME_EXACT_MATCH      => 1001;
 
16
use constant TRANSFORM_OUTCOME_UNORDERED_MATCH  => 1002;
 
17
use constant TRANSFORM_OUTCOME_SUPERSET         => 1003;
 
18
use constant TRANSFORM_OUTCOME_SUBSET           => 1004;
 
19
use constant TRANSFORM_OUTCOME_SINGLE_ROW       => 1005;
 
20
use constant TRANSFORM_OUTCOME_FIRST_ROW        => 1006;
 
21
use constant TRANSFORM_OUTCOME_DISTINCT         => 1007;
 
22
use constant TRANSFORM_OUTCOME_COUNT            => 1008;
 
23
use constant TRANSFORM_OUTCOME_CUSTOM           => 1009;
 
24
 
 
25
my %transform_outcomes = (
 
26
        'TRANSFORM_OUTCOME_EXACT_MATCH'         => 1001,
 
27
        'TRANSFORM_OUTCOME_UNORDERED_MATCH'     => 1002,
 
28
        'TRANSFORM_OUTCOME_SUPERSET'            => 1003,
 
29
        'TRANSFORM_OUTCOME_SUBSET'              => 1004,
 
30
        'TRANSFORM_OUTCOME_SINGLE_ROW'          => 1005,
 
31
        'TRANSFORM_OUTCOME_FIRST_ROW'           => 1006,
 
32
        'TRANSFORM_OUTCOME_DISTINCT'            => 1007,
 
33
        'TRANSFORM_OUTCOME_COUNT'               => 1008,
 
34
        'TRANSFORM_OUTCOME_CUSTOM'              => 1009
 
35
);
 
36
 
 
37
sub transformExecuteValidate {
 
38
        my ($transformer, $original_query, $original_result, $executor) = @_;
 
39
 
 
40
        $transformer->[TRANSFORMER_QUERIES_PROCESSED]++;
 
41
 
 
42
        my $transformed_query = $transformer->transform($original_query, $executor);
 
43
 
 
44
        return STATUS_OK if $transformed_query == STATUS_OK || $transformed_query == STATUS_WONT_HANDLE;
 
45
        return $transformed_query if $transformed_query =~ m{^\d+$}sgio;
 
46
 
 
47
        $transformer->[TRANSFORMER_QUERIES_TRANSFORMED]++;
 
48
 
 
49
        my $result_transformed = $executor->execute($transformed_query, 1);
 
50
        my $transform_outcome = $transformer->validate([ $original_result, $result_transformed ]);
 
51
 
 
52
        return ($transform_outcome, $transformed_query, $result_transformed);
 
53
}
 
54
 
 
55
sub validate {
 
56
        my ($transformer, $results) = @_;
 
57
 
 
58
        foreach my $result (@$results) {
 
59
                return STATUS_OK if not defined $result->data();
 
60
        }
 
61
 
 
62
        my $transformed_query = $results->[1]->query();
 
63
 
 
64
        my $transform_outcome = TRANSFORM_OUTCOME_CUSTOM;
 
65
 
 
66
        foreach my $potential_outcome (keys %transform_outcomes) {
 
67
                if ($transformed_query =~ m{$potential_outcome}s) {
 
68
                        $transform_outcome = $transform_outcomes{$potential_outcome};
 
69
                        last;
 
70
                }
 
71
        }
 
72
 
 
73
        if ($transform_outcome == TRANSFORM_OUTCOME_SINGLE_ROW) {
 
74
                return $transformer->isSingleRow($results);
 
75
        } elsif ($transform_outcome == TRANSFORM_OUTCOME_DISTINCT) {
 
76
                return $transformer->isDistinct($results);
 
77
        } elsif ($transform_outcome == TRANSFORM_OUTCOME_UNORDERED_MATCH) {
 
78
                return GenTest::Comparator::compare($results->[0], $results->[1]);
 
79
        } elsif ($transform_outcome == TRANSFORM_OUTCOME_SUPERSET) {
 
80
                return $transformer->isSuperset($results);
 
81
        } elsif ($transform_outcome == TRANSFORM_OUTCOME_FIRST_ROW) {
 
82
                return $transformer->isFirstRow($results);
 
83
        } elsif ($transform_outcome == TRANSFORM_OUTCOME_COUNT) {
 
84
                return $transformer->isCount($results);
 
85
        } else {
 
86
                die ("Unknown transform_outcome = $transform_outcome.");
 
87
        }
 
88
}
 
89
 
 
90
sub isFirstRow {
 
91
        my ($transformer, $results) = @_;
 
92
 
 
93
        if (
 
94
                ($results->[1]->rows() == 0) &&
 
95
                ($results->[0]->rows() == 0)
 
96
        ) {
 
97
                return STATUS_OK;
 
98
        } else {
 
99
                my $row1 = join('<col>', @{$results->[0]->data()->[0]}) if defined $results->[0]->data();
 
100
                my $row2 = join('<col>', @{$results->[1]->data()->[0]}) if defined $results->[1]->data();
 
101
                return STATUS_CONTENT_MISMATCH if $row1 ne $row2;
 
102
        }
 
103
        return STATUS_OK;
 
104
}
 
105
 
 
106
sub isDistinct {
 
107
        my ($transformer, $results) = @_;
 
108
 
 
109
        my @rows;
 
110
 
 
111
        foreach my $i (0..1) {
 
112
                foreach my $row_ref (@{$results->[$i]->data()}) {
 
113
                        my $row = join('<col>', @$row_ref);
 
114
                        $rows[$i]->{$row}++;
 
115
                        return STATUS_LENGTH_MISMATCH if $rows[$i]->{$row} > 1 && $i == 1;
 
116
                }
 
117
        }
 
118
        
 
119
        my $distinct_original = join ('<row>', sort keys %{$rows[0]} );
 
120
        my $distinct_transformed = join ('<row>', sort keys %{$rows[1]} );
 
121
 
 
122
        if ($distinct_original ne $distinct_transformed) {
 
123
                return STATUS_CONTENT_MISMATCH;
 
124
        } else {
 
125
                return STATUS_OK;
 
126
        }
 
127
}
 
128
 
 
129
sub isSuperset {
 
130
        my ($transformer, $results) = @_;
 
131
        my %rows;
 
132
        foreach my $row_ref (@{$results->[0]->data()}) {
 
133
                my $row = join('<col>', @$row_ref);
 
134
                $rows{$row}++;
 
135
        }
 
136
 
 
137
        foreach my $row_ref (@{$results->[1]->data()}) {
 
138
                my $row = join('<col>', @$row_ref);
 
139
                $rows{$row}--;
 
140
        }
 
141
 
 
142
        foreach my $row (keys %rows) {
 
143
                return STATUS_LENGTH_MISMATCH if $rows{$row} > 0;
 
144
        }
 
145
 
 
146
        return STATUS_OK;
 
147
}
 
148
 
 
149
sub isSingleRow {
 
150
        my ($transformer, $results) = @_;
 
151
 
 
152
        if (
 
153
                ($results->[1]->rows() == 0) &&
 
154
                ($results->[0]->rows() == 0)
 
155
        ) {
 
156
                return STATUS_OK;
 
157
        } elsif ($results->[1]->rows() == 1) {
 
158
                my $transformed_row = join('<col>', @{$results->[1]->data()->[0]});
 
159
                foreach my $original_row_ref (@{$results->[0]->data()}) {
 
160
                        my $original_row = join('<col>', @$original_row_ref);
 
161
                        return STATUS_OK if $original_row eq $transformed_row;
 
162
                }
 
163
                return STATUS_CONTENT_MISMATCH;
 
164
        } else {
 
165
                # More than one row, something is messed up
 
166
                return STATUS_LENGTH_MISMATCH;
 
167
        }
 
168
}
 
169
 
 
170
sub isCount {
 
171
        my ($transformer, $results) = @_;
 
172
 
 
173
        my ($large_result, $small_result) ;
 
174
 
 
175
        if (
 
176
                ($results->[0]->rows() == 0) ||
 
177
                ($results->[1]->rows() == 0)
 
178
        ) {
 
179
                return STATUS_OK;
 
180
        } elsif (
 
181
                ($results->[0]->rows() == 1) &&
 
182
                ($results->[1]->rows() == 1)
 
183
        ) {
 
184
                return STATUS_OK;
 
185
        } elsif (
 
186
                ($results->[0]->rows() == 1) &&
 
187
                ($results->[1]->rows() >= 1)
 
188
        ) {
 
189
                $small_result = $results->[0];
 
190
                $large_result = $results->[1];
 
191
        } elsif (
 
192
                ($results->[1]->rows() == 1) &&
 
193
                ($results->[0]->rows() >= 1)
 
194
        ) {
 
195
                $small_result = $results->[1];
 
196
                $large_result = $results->[0];
 
197
        } else {
 
198
                return STATUS_LENGTH_MISMATCH;
 
199
        }
 
200
 
 
201
        if ($large_result->rows() != $small_result->data()->[0]->[0]) {
 
202
                return STATUS_LENGTH_MISMATCH;
 
203
        } else {
 
204
                return STATUS_OK;
 
205
        }
 
206
}
 
207
 
 
208
sub name {
 
209
        my $transformer = shift;
 
210
        my ($name) = $transformer =~ m{.*::([a-z]*)}sgio;
 
211
        return $name;
 
212
}
 
213
 
 
214
sub DESTROY {
 
215
        my $transformer = shift;
 
216
        print "# $transformer: queries_processed: ".$transformer->[TRANSFORMER_QUERIES_PROCESSED]."; queries_transformed: ".$transformer->[TRANSFORMER_QUERIES_TRANSFORMED]."\n" if rqg_debug();
 
217
}
 
218
 
 
219
1;