-
Notifications
You must be signed in to change notification settings - Fork 151
/
mysql.t
157 lines (141 loc) · 5.05 KB
/
mysql.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
155
156
157
BEGIN { do "./t/lib/ANFANG.pm" or die ( $@ || $! ) }
use strict;
use warnings;
use Test::More;
use DBICTest ':DiffSQL';
my $schema = DBICTest::Schema->connect (DBICTest->_database, { quote_char => '`' });
# cheat
require DBIx::Class::Storage::DBI::mysql;
*DBIx::Class::Storage::DBI::mysql::_get_server_version = sub { 5 };
bless ( $schema->storage, 'DBIx::Class::Storage::DBI::mysql' );
# check that double-subqueries are properly wrapped
{
# the expected SQL may seem wastefully nonsensical - this is due to
# CD's tablename being \'cd', which triggers the "this can be anything"
# mode, and forces a subquery. This in turn forces *another* subquery
# because mysql is being mysql
# Also we know it will fail - never deployed. All we care about is the
# SQL to compare, hence the eval
$schema->is_executed_sql_bind( sub {
eval { $schema->resultset ('CD')->update({ genreid => undef }) }
},[[
'UPDATE cd SET `genreid` = ? WHERE `cdid` IN ( SELECT * FROM ( SELECT `me`.`cdid` FROM cd `me` ) `_forced_double_subquery` )',
[ { dbic_colname => "genreid", sqlt_datatype => "integer" } => undef ],
]], 'Correct update-SQL with double-wrapped subquery' );
# same comment as above
$schema->is_executed_sql_bind( sub {
eval { $schema->resultset ('CD')->delete }
}, [[
'DELETE FROM cd WHERE `cdid` IN ( SELECT * FROM ( SELECT `me`.`cdid` FROM cd `me` ) `_forced_double_subquery` )',
]], 'Correct delete-SQL with double-wrapped subquery' );
# and a couple of really contrived examples (we test them live in t/71mysql.t)
my $rs = $schema->resultset('Artist')->search({ name => { -like => 'baby_%' } });
my ($count_sql, @count_bind) = @${$rs->count_rs->as_query};
$schema->is_executed_sql_bind( sub {
eval {
$schema->resultset('Artist')->search(
{ artistid => {
-in => $rs->get_column('artistid')
->as_query
} },
)->update({ name => \[ "CONCAT( `name`, '_bell_out_of_', $count_sql )", @count_bind ] });
}
}, [[
q(
UPDATE `artist`
SET `name` = CONCAT(`name`, '_bell_out_of_', (
SELECT *
FROM (
SELECT COUNT( * )
FROM `artist` `me`
WHERE `name` LIKE ?
) `_forced_double_subquery`
))
WHERE
`artistid` IN (
SELECT *
FROM (
SELECT `me`.`artistid`
FROM `artist` `me`
WHERE `name` LIKE ?
) `_forced_double_subquery` )
),
( [ { dbic_colname => "name", sqlt_datatype => "varchar", sqlt_size => 100 }
=> 'baby_%' ]
) x 2
]]);
$schema->is_executed_sql_bind( sub {
eval {
$schema->resultset('CD')->search_related('artist',
{ 'artist.name' => { -like => 'baby_with_%' } }
)->delete
}
}, [[
q(
DELETE FROM `artist`
WHERE `artistid` IN (
SELECT *
FROM (
SELECT `artist`.`artistid`
FROM cd `me`
JOIN `artist` `artist`
ON `artist`.`artistid` = `me`.`artist`
WHERE `artist`.`name` LIKE ?
) `_forced_double_subquery`
)
),
[ { dbic_colname => "artist.name", sqlt_datatype => "varchar", sqlt_size => 100 }
=> 'baby_with_%' ],
]] );
}
# Test support for straight joins
{
my $cdsrc = $schema->source('CD');
my $artrel_info = $cdsrc->relationship_info ('artist');
$cdsrc->add_relationship(
'straight_artist',
$artrel_info->{class},
$artrel_info->{cond},
{ %{$artrel_info->{attrs}}, join_type => 'straight' },
);
is_same_sql_bind (
$cdsrc->resultset->search({}, { prefetch => 'straight_artist' })->as_query,
'(
SELECT `me`.`cdid`, `me`.`artist`, `me`.`title`, `me`.`year`, `me`.`genreid`, `me`.`single_track`,
`straight_artist`.`artistid`, `straight_artist`.`name`, `straight_artist`.`rank`, `straight_artist`.`charfield`
FROM cd `me`
STRAIGHT_JOIN `artist` `straight_artist` ON `straight_artist`.`artistid` = `me`.`artist`
)',
[],
'straight joins correctly supported for mysql'
);
}
# Test support for inner joins on mysql v3
for (
[ 3 => 'INNER JOIN' ],
[ 4 => 'JOIN' ],
) {
my ($ver, $join_op) = @$_;
# we do not care at this point if data is available, just do a reconnect cycle
# to clear the server version cache and then get a new maker
{
$schema->storage->disconnect;
$schema->storage->_sql_maker(undef);
no warnings 'redefine';
local *DBIx::Class::Storage::DBI::mysql::_get_server_version = sub { $ver };
$schema->storage->ensure_connected;
$schema->storage->sql_maker;
}
is_same_sql_bind (
$schema->resultset('CD')->search ({}, { prefetch => 'artist' })->as_query,
"(
SELECT `me`.`cdid`, `me`.`artist`, `me`.`title`, `me`.`year`, `me`.`genreid`, `me`.`single_track`,
`artist`.`artistid`, `artist`.`name`, `artist`.`rank`, `artist`.`charfield`
FROM cd `me`
$join_op `artist` `artist` ON `artist`.`artistid` = `me`.`artist`
)",
[],
"default join type works for version $ver",
);
}
done_testing;