Merge lp:~jmuc/percona-toolkit/float-log-precision into lp:percona-toolkit/2.2

Proposed by Johannes W
Status: Needs review
Proposed branch: lp:~jmuc/percona-toolkit/float-log-precision
Merge into: lp:percona-toolkit/2.2
Diff against target: 116 lines (+49/-4)
2 files modified
bin/pt-table-checksum (+24/-2)
bin/pt-table-sync (+25/-2)
To merge this branch: bzr merge lp:~jmuc/percona-toolkit/float-log-precision
Reviewer Review Type Date Requested Status
Percona Toolkit developers Pending
Review via email: mp+155494@code.launchpad.net

Description of the change

Add new option "--float-log-precision" for alternative rounding algorithm.

This is necessary to compare very large and small floats. See bug #1156214
for details.

To post a comment you must log in.

Unmerged revisions

569. By Johannes W

Add new option "--float-log-precision" for alternative rounding algorithm.

This is necessary to compare very large and small floats. See bug #1156214
for details.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bin/pt-table-checksum'
2--- bin/pt-table-checksum 2013-03-20 17:53:36 +0000
3+++ bin/pt-table-checksum 2013-03-26 14:09:22 +0000
4@@ -5497,7 +5497,15 @@
5 $query = join(', ',
6 map {
7 my $col = $_;
8- if ( $col =~ m/\+ 0/ ) {
9+ if ( $col =~ m/SIGN/ ) {
10+ my ($real_col) = m/SIGN\(([^\)]+)\)/;
11+ $col .= " AS $real_col";
12+ }
13+ elsif ( $col =~ m/ROUND/ ) {
14+ my ($real_col) = m/ROUND\(([^,]+)/;
15+ $col .= " AS $real_col";
16+ }
17+ elsif ( $col =~ m/\+ 0/ ) {
18 my ($real_col) = /^(\S+)/;
19 $col .= " AS $real_col";
20 }
21@@ -5587,6 +5595,7 @@
22
23 my $trim = $o->get('trim');
24 my $float_precision = $o->get('float-precision');
25+ my $float_log_precision = $o->get('float-log-precision');
26
27 my $tbl_struct = $tbl->{tbl_struct};
28 my $ignore_col = $o->get('ignore-columns') || {};
29@@ -5601,7 +5610,12 @@
30 $result .= ' + 0';
31 }
32 elsif ( $float_precision && $type =~ m/float|double/ ) {
33- $result = "ROUND($result, $float_precision)";
34+ if ( $float_log_precision ) {
35+ $result = "IF($result = 0, 0, SIGN($result) * ROUND(LOG2(ABS($result)), $float_precision))";
36+ }
37+ else {
38+ $result = "ROUND($result, $float_precision)";
39+ }
40 }
41 elsif ( $trim && $type =~ m/varchar/ ) {
42 $result = "TRIM($result)";
43@@ -11573,6 +11587,14 @@
44 the string representation. If you specify a value of 2, for example, then the
45 values 1.008 and 1.009 will be rounded to 1.01, and will checksum as equal.
46
47+=item --float-log-precision
48+
49+Activate an alternative rounding algorithm instead of the simple ROUND()
50+when using L<"--float-precision">. This is necessary to compare very small or
51+large floats. The algorithm is:
52+
53+IF(col = 0, 0, SIGN(col) * ROUND(LOG2(ABS(col)), float_precision))
54+
55 =item --function
56
57 type: string
58
59=== modified file 'bin/pt-table-sync'
60--- bin/pt-table-sync 2013-03-20 17:53:36 +0000
61+++ bin/pt-table-sync 2013-03-26 14:09:22 +0000
62@@ -4757,7 +4757,12 @@
63 $result .= ' + 0';
64 }
65 elsif ( $args{float_precision} && $type =~ m/float|double/ ) {
66- $result = "ROUND($result, $args{float_precision})";
67+ if ( $args{float_log_precision} ) {
68+ $result = "IF($result = 0, 0, SIGN($result) * ROUND(LOG2(ABS($result)), $args{float_precision}))";
69+ }
70+ else {
71+ $result = "ROUND($result, $args{float_precision})";
72+ }
73 }
74 elsif ( $args{trim} && $type =~ m/varchar/ ) {
75 $result = "TRIM($result)";
76@@ -4774,7 +4779,16 @@
77 $query = join(', ',
78 map {
79 my $col = $_;
80- if ( $col =~ m/\+ 0/ ) {
81+
82+ if ( $col =~ m/SIGN/ ) {
83+ my ($real_col) = m/SIGN\(([^\)]+)\)/;
84+ $col .= " AS $real_col";
85+ }
86+ elsif ( $col =~ m/ROUND/ ) {
87+ my ($real_col) = m/ROUND\(([^,]+)/;
88+ $col .= " AS $real_col";
89+ }
90+ elsif ( $col =~ m/\+ 0/ ) {
91 my ($real_col) = /^(\S+)/;
92 $col .= " AS $real_col";
93 }
94@@ -10501,6 +10515,7 @@
95 || $o->get('bidirectional')
96 || 0,
97 float_precision => $o->get('float-precision'),
98+ float_log_precision => $o->get('float-log-precision'),
99 index_hint => $o->get('index-hint'),
100 chunk_index => $o->get('chunk-index'),
101 chunk_col => $o->get('chunk-column'),
102@@ -12006,6 +12021,14 @@
103 the string representation. If you specify a value of 2, for example, then the
104 values 1.008 and 1.009 will be rounded to 1.01, and will checksum as equal.
105
106+=item --float-log-precision
107+
108+Activate an alternative rounding algorithm instead of the simple ROUND()
109+when using L<"--float-precision">. This is necessary to compare very small or
110+large floats. The algorithm is:
111+
112+IF(col = 0, 0, SIGN(col) * ROUND(LOG2(ABS(col)), float_precision))
113+
114 =item --[no]foreign-key-checks
115
116 default: yes

Subscribers

People subscribed via source and target branches