-
Notifications
You must be signed in to change notification settings - Fork 75
/
Copy path41int_min_max.t
154 lines (132 loc) · 6.31 KB
/
41int_min_max.t
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
use strict;
use warnings;
use bigint;
use DBI;
use Test::More;
use lib 't', '.';
use Data::Dumper;
require 'lib.pl';
use vars qw($test_dsn $test_user $test_password);
my $dbh;
eval {$dbh= DBI->connect($test_dsn, $test_user, $test_password,
{ RaiseError => 1, PrintError => 1, AutoCommit => 1 });};
if ($@) {
plan skip_all => "no database connection";
}
if ($dbh->{mysql_serverversion} < 50002) {
plan skip_all =>
"SKIP TEST: You must have MySQL version 5.0.2 and greater for this test to run";
}
# nostrict tests + strict tests + init/tear down commands
plan tests => (19*8 + 17*8 + 4) * 2;
my $table = 'dbd_mysql_t41minmax'; # name of the table we will be using
my $mode; # 'strict' or 'nostrict' corresponds to strict SQL mode
sub test_int_type ($$$$) {
my ($perl_type, $mysql_type, $min, $max) = @_;
# Disable the warning text clobbering our output
local $SIG{__WARN__} = sub { 1; };
# Create the table
ok($dbh->do(qq{DROP TABLE IF EXISTS $table}), "removing $table");
ok($dbh->do(qq{
CREATE TABLE `$table` (
`id` int not null auto_increment,
`val` $mysql_type,
primary key (id)
)
}), "creating minmax table for type $mysql_type");
my ($store, $retrieve); # statements
my $read_value; # retrieved value
ok($store = $dbh->prepare("INSERT INTO $table (val) VALUES (?)"));
ok($retrieve = $dbh->prepare("SELECT val from $table where id=(SELECT MAX(id) FROM $table)"));
########################################
# Insert allowed min value
########################################
ok($store->bind_param( 1, $min->bstr(), $perl_type ), "binding minimal $mysql_type, mode=$mode");
ok($store->execute(), "inserting min data for type $mysql_type, mode=$mode");
########################################
# Read it back and compare
########################################
ok{$retrieve->execute()};
($read_value) = $retrieve->fetchrow_array();
cmp_ok($read_value, 'eq', $min, "retrieved minimal value for $mysql_type, mode=$mode");
########################################
# Insert allowed max value
########################################
ok($store->bind_param( 1, $max->bstr(), $perl_type ), "binding maximal $mysql_type, mode=$mode");
ok($store->execute(), "inserting max data for type $mysql_type, mode=$mode");
########################################
# Read it back and compare
########################################
ok{$retrieve->execute()};
($read_value) = $retrieve->fetchrow_array();
cmp_ok($read_value, 'eq', $max, "retrieved maximal value for $mysql_type, mode=$mode");
########################################
# Try to insert under the limit value
########################################
ok($store->bind_param( 1, ($min-1)->bstr(), $perl_type ), "binding less than minimal $mysql_type, mode=$mode");
if ($mode eq 'strict') {
$@ = '';
eval{$store->execute()};
like($@, qr/Out of range value (?:adjusted )?for column 'val'/, "Error, you stored ".($min-1)." into $mysql_type, mode=$mode\n".
Data::Dumper->Dump([$dbh->selectall_arrayref("SELECT * FROM $table")]).
Data::Dumper->Dump([$dbh->selectall_arrayref("describe $table")])
);
} else {
ok{$store->execute()};
########################################
# Check that it was rounded correctly
########################################
ok{$retrieve->execute()};
($read_value) = $retrieve->fetchrow_array();
cmp_ok($read_value, 'eq', $min, "retrieved minimal value for type $mysql_type, mode=$mode");
};
########################################
# Try to insert over the limit value
########################################
ok($store->bind_param( 1, ($max+1)->bstr(), $perl_type ), "binding more than maximal $mysql_type, mode=$mode");
if ($mode eq 'strict') {
$@ = '';
eval{$store->execute()};
like($@, qr/Out of range value (?:adjusted )?for column 'val'/, "Error, you stored ".($max+1)." into $mysql_type, mode=$mode\n".
Data::Dumper->Dump([$dbh->selectall_arrayref("SELECT * FROM $table")]).
Data::Dumper->Dump([$dbh->selectall_arrayref("describe $table")])
);
} else {
ok{$store->execute()};
########################################
# Check that it was rounded correctly
########################################
ok{$retrieve->execute()};
($read_value) = $retrieve->fetchrow_array();
cmp_ok($read_value, 'eq', $max, "retrieved maximal value for type $mysql_type, mode=$mode");
};
}
$dbh->disconnect;
for my $mysql_server_prepare (0, 1) {
$dbh= DBI->connect($test_dsn . ';mysql_server_prepare=' . $mysql_server_prepare, $test_user, $test_password,
{ RaiseError => 1, PrintError => 1, AutoCommit => 0 });
# Set strict SQL mode
ok($dbh->do("SET SQL_MODE='STRICT_ALL_TABLES'"),"Enter strict SQL mode.");
$mode = 'strict';
test_int_type(DBI::SQL_TINYINT, 'tinyint signed', -2**7, 2**7-1);
test_int_type(DBI::SQL_TINYINT, 'tinyint unsigned', 0, 2**8-1);
test_int_type(DBI::SQL_SMALLINT, 'smallint signed', -2**15, 2**15-1);
test_int_type(DBI::SQL_SMALLINT, 'smallint unsigned', 0, 2**16-1);
test_int_type(DBI::SQL_INTEGER, 'int signed', -2**31, 2**31-1);
test_int_type(DBI::SQL_INTEGER, 'int unsigned', 0, 2**32-1);
test_int_type(DBI::SQL_BIGINT, 'bigint signed', -2**63, 2**63-1);
test_int_type(DBI::SQL_BIGINT, 'bigint unsigned', 0, 2**64-1);
# Do not use strict SQL mode
ok($dbh->do("SET SQL_MODE=''"),"Leave strict SQL mode.");
$mode = 'nostrict';
test_int_type(DBI::SQL_TINYINT, 'tinyint signed', -2**7, 2**7-1);
test_int_type(DBI::SQL_TINYINT, 'tinyint unsigned', 0, 2**8-1);
test_int_type(DBI::SQL_SMALLINT, 'smallint signed', -2**15, 2**15-1);
test_int_type(DBI::SQL_SMALLINT, 'smallint unsigned', 0, 2**16-1);
test_int_type(DBI::SQL_INTEGER, 'int signed', -2**31, 2**31-1);
test_int_type(DBI::SQL_INTEGER, 'int unsigned', 0, 2**32-1);
test_int_type(DBI::SQL_BIGINT, 'bigint signed', -2**63, 2**63-1);
test_int_type(DBI::SQL_BIGINT, 'bigint unsigned', 0, 2**64-1);
ok ($dbh->do("DROP TABLE $table"));
ok $dbh->disconnect;
}