← Index
NYTProf Performance Profile   « block view • line view • sub view »
For xt/tapper-mcp-scheduler-with-db-longrun.t
  Run on Tue May 22 17:18:39 2012
Reported on Tue May 22 17:23:19 2012

Filename/2home/ss5/perl5/perlbrew/perls/perl-5.12.3/lib/site_perl/5.12.3/DBIx/Class/SQLMaker.pm
StatementsExecuted 648511 statements in 1.68s
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
63788102423ms1.77sDBIx::Class::SQLMaker::::_quoteDBIx::Class::SQLMaker::_quote
4519752392ms1.43sDBIx::Class::SQLMaker::::_recurse_fieldsDBIx::Class::SQLMaker::_recurse_fields (recurses: max depth 2, inclusive time 1.36s)
733022258ms440msDBIx::Class::SQLMaker::::_order_byDBIx::Class::SQLMaker::_order_by (recurses: max depth 1, inclusive time 106ms)
1370631231ms563msDBIx::Class::SQLMaker::::_from_chunk_to_sqlDBIx::Class::SQLMaker::_from_chunk_to_sql (recurses: max depth 1, inclusive time 206ms)
670611208ms4.80sDBIx::Class::SQLMaker::::selectDBIx::Class::SQLMaker::select
80194174.5ms1.01sDBIx::Class::SQLMaker::::_tableDBIx::Class::SQLMaker::_table
67061169.2ms663msDBIx::Class::SQLMaker::::_gen_from_blocksDBIx::Class::SQLMaker::_gen_from_blocks
1006274159.4ms59.4msDBIx::Class::SQLMaker::::CORE:matchDBIx::Class::SQLMaker::CORE:match (opcode)
67061159.1ms59.1msDBIx::Class::SQLMaker::::_assemble_bindsDBIx::Class::SQLMaker::_assemble_binds
67061149.2ms713msDBIx::Class::SQLMaker::::_recurse_fromDBIx::Class::SQLMaker::_recurse_from
68533345.3ms154msDBIx::Class::SQLMaker::::_parse_rs_attrsDBIx::Class::SQLMaker::_parse_rs_attrs
449118.16ms431msDBIx::Class::SQLMaker::::insertDBIx::Class::SQLMaker::insert
147112.61ms8.56msDBIx::Class::SQLMaker::::_where_op_IDENTDBIx::Class::SQLMaker::_where_op_IDENT
147111.57ms30.7msDBIx::Class::SQLMaker::::_join_conditionDBIx::Class::SQLMaker::_join_condition
147111.13ms1.13msDBIx::Class::SQLMaker::::_quote_charsDBIx::Class::SQLMaker::_quote_chars
14711982µs982µsDBIx::Class::SQLMaker::::_generate_join_clauseDBIx::Class::SQLMaker::_generate_join_clause
511144µs625µsDBIx::Class::SQLMaker::::newDBIx::Class::SQLMaker::new
11133µs248µsDBIx::Class::SQLMaker::::BEGIN@64DBIx::Class::SQLMaker::BEGIN@64
101119µs19µsDBIx::Class::SQLMaker::::CORE:qrDBIx::Class::SQLMaker::CORE:qr (opcode)
11114µs19µsDBIx::Class::SQLMaker::::BEGIN@3DBIx::Class::SQLMaker::BEGIN@3
11112µs24µsDBIx::Class::SQLMaker::::BEGIN@43DBIx::Class::SQLMaker::BEGIN@43
11112µs52µsDBIx::Class::SQLMaker::::BEGIN@45DBIx::Class::SQLMaker::BEGIN@45
11111µs28µsDBIx::Class::SQLMaker::::BEGIN@4DBIx::Class::SQLMaker::BEGIN@4
11110µs30µsDBIx::Class::SQLMaker::::BEGIN@67DBIx::Class::SQLMaker::BEGIN@67
1119µs103µsDBIx::Class::SQLMaker::::BEGIN@46DBIx::Class::SQLMaker::BEGIN@46
1119µs9.28msDBIx::Class::SQLMaker::::BEGIN@38DBIx::Class::SQLMaker::BEGIN@38
1117µs180µsDBIx::Class::SQLMaker::::BEGIN@48DBIx::Class::SQLMaker::BEGIN@48
1116µs6µsDBIx::Class::SQLMaker::::BEGIN@47DBIx::Class::SQLMaker::BEGIN@47
0000s0sDBIx::Class::SQLMaker::::__ANON__[:72]DBIx::Class::SQLMaker::__ANON__[:72]
0000s0sDBIx::Class::SQLMaker::::__ANON__[:77]DBIx::Class::SQLMaker::__ANON__[:77]
0000s0sDBIx::Class::SQLMaker::::_lock_selectDBIx::Class::SQLMaker::_lock_select
0000s0sDBIx::Class::SQLMaker::::_where_op_NESTDBIx::Class::SQLMaker::_where_op_NEST
0000s0sDBIx::Class::SQLMaker::::_where_op_VALUEDBIx::Class::SQLMaker::_where_op_VALUE
0000s0sDBIx::Class::SQLMaker::::throw_exceptionDBIx::Class::SQLMaker::throw_exception
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1package DBIx::Class::SQLMaker;
2
3322µs224µs
# spent 19µs (14+5) within DBIx::Class::SQLMaker::BEGIN@3 which was called: # once (14µs+5µs) by base::import at line 3
use strict;
# spent 19µs making 1 call to DBIx::Class::SQLMaker::BEGIN@3 # spent 5µs making 1 call to strict::import
4338µs245µs
# spent 28µs (11+17) within DBIx::Class::SQLMaker::BEGIN@4 which was called: # once (11µs+17µs) by base::import at line 4
use warnings;
# spent 28µs making 1 call to DBIx::Class::SQLMaker::BEGIN@4 # spent 17µs making 1 call to warnings::import
5
6=head1 NAME
7
8DBIx::Class::SQLMaker - An SQL::Abstract-based SQL maker class
9
10=head1 DESCRIPTION
11
12This module is a subclass of L<SQL::Abstract> and includes a number of
13DBIC-specific workarounds, not yet suitable for inclusion into the
14L<SQL::Abstract> core. It also provides all (and more than) the functionality
15of L<SQL::Abstract::Limit>, see L<DBIx::Class::SQLMaker::LimitDialects> for
16more info.
17
18Currently the enhancements to L<SQL::Abstract> are:
19
20=over
21
22=item * Support for C<JOIN> statements (via extended C<table/from> support)
23
24=item * Support of functions in C<SELECT> lists
25
26=item * C<GROUP BY>/C<HAVING> support (via extensions to the order_by parameter)
27
28=item * Support of C<...FOR UPDATE> type of select statement modifiers
29
30=item * The L</-ident> operator
31
32=item * The L</-value> operator
33
34=back
35
36=cut
37
3810s
# spent 9.28ms (9µs+9.27) within DBIx::Class::SQLMaker::BEGIN@38 which was called: # once (9µs+9.27ms) by base::import at line 42
use base qw/
# spent 9.27ms making 1 call to base::import, recursion: max depth 1, sum of overlapping time 9.27ms
39 DBIx::Class::SQLMaker::LimitDialects
40 SQL::Abstract
41 DBIx::Class
42334µs19.28ms/;
# spent 9.28ms making 1 call to DBIx::Class::SQLMaker::BEGIN@38
43323µs235µs
# spent 24µs (12+11) within DBIx::Class::SQLMaker::BEGIN@43 which was called: # once (12µs+11µs) by base::import at line 43
use mro 'c3';
# spent 24µs making 1 call to DBIx::Class::SQLMaker::BEGIN@43 # spent 11µs making 1 call to mro::import
44
45324µs292µs
# spent 52µs (12+40) within DBIx::Class::SQLMaker::BEGIN@45 which was called: # once (12µs+40µs) by base::import at line 45
use Sub::Name 'subname';
# spent 52µs making 1 call to DBIx::Class::SQLMaker::BEGIN@45 # spent 40µs making 1 call to Exporter::import
46322µs2198µs
# spent 103µs (9+94) within DBIx::Class::SQLMaker::BEGIN@46 which was called: # once (9µs+94µs) by base::import at line 46
use DBIx::Class::Carp;
# spent 103µs making 1 call to DBIx::Class::SQLMaker::BEGIN@46 # spent 94µs making 1 call to DBIx::Class::Carp::import
47319µs16µs
# spent 6µs within DBIx::Class::SQLMaker::BEGIN@47 which was called: # once (6µs+0s) by base::import at line 47
use DBIx::Class::Exception;
# spent 6µs making 1 call to DBIx::Class::SQLMaker::BEGIN@47
483110µs2352µs
# spent 180µs (7+173) within DBIx::Class::SQLMaker::BEGIN@48 which was called: # once (7µs+173µs) by base::import at line 48
use namespace::clean;
# spent 180µs making 1 call to DBIx::Class::SQLMaker::BEGIN@48 # spent 173µs making 1 call to namespace::clean::import
49
50140µs1233µs__PACKAGE__->mk_group_accessors (simple => qw/quote_char name_sep limit_dialect/);
# spent 233µs making 1 call to Class::Accessor::Grouped::mk_group_accessors
51
52# for when I need a normalized l/r pair
53
# spent 1.13ms within DBIx::Class::SQLMaker::_quote_chars which was called 147 times, avg 8µs/call: # 147 times (1.13ms+0s) by DBIx::Class::Storage::DBIHacks::_resolve_aliastypes_from_select_args at line 321 of DBIx/Class/Storage/DBIHacks.pm, avg 8µs/call
sub _quote_chars {
54 map
55 { defined $_ ? $_ : '' }
561471.14ms ( ref $_[0]->{quote_char} ? (@{$_[0]->{quote_char}}) : ( ($_[0]->{quote_char}) x 2 ) )
57 ;
58}
59
60# FIXME when we bring in the storage weaklink, check its schema
61# weaklink and channel through $schema->throw_exception
62sub throw_exception { DBIx::Class::Exception->throw($_[1]) }
63
64
# spent 248µs (33+214) within DBIx::Class::SQLMaker::BEGIN@64 which was called: # once (33µs+214µs) by base::import at line 81
BEGIN {
65 # reinstall the belch()/puke() functions of SQL::Abstract with custom versions
66 # that use DBIx::Class::Carp/DBIx::Class::Exception instead of plain Carp
673118µs250µs
# spent 30µs (10+20) within DBIx::Class::SQLMaker::BEGIN@67 which was called: # once (10µs+20µs) by base::import at line 67
no warnings qw/redefine/;
# spent 30µs making 1 call to DBIx::Class::SQLMaker::BEGIN@67 # spent 20µs making 1 call to warnings::unimport
68
69 *SQL::Abstract::belch = subname 'SQL::Abstract::belch' => sub (@) {
70 my($func) = (caller(1))[3];
71 carp "[$func] Warning: ", @_;
72337µs13µs };
# spent 3µs making 1 call to Sub::Name::subname
73
74 *SQL::Abstract::puke = subname 'SQL::Abstract::puke' => sub (@) {
75 my($func) = (caller(1))[3];
76 __PACKAGE__->throw_exception("[$func] Fatal: " . join ('', @_));
7712µs };
# spent 2µs making 1 call to Sub::Name::subname
78
79 # Current SQLA pollutes its namespace - clean for the time being
801209µs namespace::clean->clean_subroutines(qw/SQL::Abstract carp croak confess/);
# spent 209µs making 1 call to namespace::clean::clean_subroutines
8111.73ms1248µs}
# spent 248µs making 1 call to DBIx::Class::SQLMaker::BEGIN@64
82
83# the "oh noes offset/top without limit" constant
84# limited to 31 bits for sanity (and consistency,
85# since it may be handed to the like of sprintf %u)
86#
87# Also *some* builds of SQLite fail the test
88# some_column BETWEEN ? AND ?: 1, 4294967295
89# with the proper integer bind attrs
90#
91# Implemented as a method, since ::Storage::DBI also
92# refers to it (i.e. for the case of software_limit or
93# as the value to abuse with MSSQL ordered subqueries)
94sub __max_int () { 0x7FFFFFFF };
95
96# poor man's de-qualifier
97
# spent 1.77s (423ms+1.34) within DBIx::Class::SQLMaker::_quote which was called 63788 times, avg 28µs/call: # 36394 times (245ms+787ms) by DBIx::Class::SQLMaker::_recurse_fields at line 274, avg 28µs/call # 7879 times (48.7ms+149ms) by SQL::Abstract::_where_hashpair_SCALAR at line 858 of SQL/Abstract.pm, avg 25µs/call # 6853 times (38.5ms+127ms) by DBIx::Class::SQLMaker::_from_chunk_to_sql at line 445, avg 24µs/call # 6853 times (35.7ms+107ms) by DBIx::Class::SQLMaker::_from_chunk_to_sql at line 464, avg 21µs/call # 1952 times (17.8ms+56.6ms) by SQL::Abstract::_insert_HASHREF at line 175 of SQL/Abstract.pm, avg 38µs/call # 1313 times (20.1ms+64.8ms) by SQL::Abstract::__ANON__[/2home/ss5/perl5/perlbrew/perls/perl-5.12.3/lib/site_perl/5.12.3/SQL/Abstract.pm:1149] at line 1149 of SQL/Abstract.pm, avg 65µs/call # 992 times (10.1ms+30.9ms) by SQL::Abstract::update at line 288 of SQL/Abstract.pm, avg 41µs/call # 781 times (3.58ms+11.1ms) by SQL::Abstract::__ANON__[/2home/ss5/perl5/perlbrew/perls/perl-5.12.3/lib/site_perl/5.12.3/SQL/Abstract.pm:1098] at line 1098 of SQL/Abstract.pm, avg 19µs/call # 477 times (2.31ms+7.13ms) by SQL::Abstract::__ANON__[/2home/ss5/perl5/perlbrew/perls/perl-5.12.3/lib/site_perl/5.12.3/SQL/Abstract.pm:782] at line 778 of SQL/Abstract.pm, avg 20µs/call # 294 times (1.26ms+4.23ms) by DBIx::Class::SQLMaker::_where_op_IDENT at line 129, avg 19µs/call
sub _quote {
9863788315ms63788422ms $_[0]->next::method( ( $_[0]{_dequalify_idents} and ! ref $_[1] )
# spent 422ms making 63788 calls to next::method, avg 7µs/call
99 ? $_[1] =~ / ([^\.]+) $ /x
100 : $_[1]
101 );
102}
103
104
# spent 625µs (144+481) within DBIx::Class::SQLMaker::new which was called 5 times, avg 125µs/call: # 5 times (144µs+481µs) by DBIx::Class::Storage::DBI::sql_maker at line 985 of DBIx/Class/Storage/DBI.pm, avg 125µs/call
sub new {
10525138µs590µs my $self = shift->next::method(@_);
# spent 90µs making 5 calls to next::method, avg 18µs/call
106
107 # use the same coderefs, they are prepared to handle both cases
1081019µs my @extra_dbic_syntax = (
# spent 19µs making 10 calls to DBIx::Class::SQLMaker::CORE:qr, avg 2µs/call
109 { regex => qr/^ ident $/xi, handler => '_where_op_IDENT' },
110 { regex => qr/^ value $/xi, handler => '_where_op_VALUE' },
111 );
112
113 push @{$self->{special_ops}}, @extra_dbic_syntax;
114 push @{$self->{unary_ops}}, @extra_dbic_syntax;
115
116 $self;
117}
118
119
# spent 8.56ms (2.61+5.96) within DBIx::Class::SQLMaker::_where_op_IDENT which was called 147 times, avg 58µs/call: # 147 times (2.61ms+5.96ms) by SQL::Abstract::_where_hashpair_HASHREF at line 735 of SQL/Abstract.pm, avg 58µs/call
sub _where_op_IDENT {
12010292.19ms my $self = shift;
121 my ($op, $rhs) = splice @_, -2;
122 if (ref $rhs) {
123 $self->throw_exception("-$op takes a single scalar argument (a quotable identifier)");
124 }
125
126 # in case we are called as a top level special op (no '=')
127 my $lhs = shift;
128
1295885.96ms $_ = $self->_convert($self->_quote($_)) for ($lhs, $rhs);
# spent 5.49ms making 294 calls to DBIx::Class::SQLMaker::_quote, avg 19µs/call # spent 463µs making 294 calls to SQL::Abstract::_convert, avg 2µs/call
130
131 return $lhs
132 ? "$lhs = $rhs"
133 : $rhs
134 ;
135}
136
137sub _where_op_VALUE {
138 my $self = shift;
139 my ($op, $rhs) = splice @_, -2;
140
141 # in case we are called as a top level special op (no '=')
142 my $lhs = shift;
143
144 my @bind = [
145 ($lhs || $self->{_nested_func_lhs} || $self->throw_exception("Unable to find bindtype for -value $rhs") ),
146 $rhs
147 ];
148
149 return $lhs
150 ? (
151 $self->_convert($self->_quote($lhs)) . ' = ' . $self->_convert('?'),
152 @bind
153 )
154 : (
155 $self->_convert('?'),
156 @bind,
157 )
158 ;
159}
160
161sub _where_op_NEST {
162 carp_unique ("-nest in search conditions is deprecated, you most probably wanted:\n"
163 .q|{..., -and => [ \%cond0, \@cond1, \'cond2', \[ 'cond3', [ col => bind ] ], etc. ], ... }|
164 );
165
166 shift->next::method(@_);
167}
168
169# Handle limit-dialect selection
170
# spent 4.80s (208ms+4.59) within DBIx::Class::SQLMaker::select which was called 6706 times, avg 715µs/call: # 6706 times (208ms+4.59s) by DBIx::Class::Storage::DBI::_gen_sql_bind at line 1428 of DBIx/Class/Storage/DBI.pm, avg 715µs/call
sub select {
17173766133ms my ($self, $table, $fields, $where, $rs_attrs, $limit, $offset) = @_;
172
173
17467061.42s $fields = $self->_recurse_fields($fields);
# spent 1.42s making 6706 calls to DBIx::Class::SQLMaker::_recurse_fields, avg 212µs/call
175
176 if (defined $offset) {
177 $self->throw_exception('A supplied offset must be a non-negative integer')
178 if ( $offset =~ /\D/ or $offset < 0 );
179 }
180 $offset ||= 0;
181
182535µs if (defined $limit) {
18356µs $self->throw_exception('A supplied limit must be a positive integer')
# spent 6µs making 5 calls to DBIx::Class::SQLMaker::CORE:match, avg 1µs/call
184 if ( $limit =~ /\D/ or $limit <= 0 );
185 }
186 elsif ($offset) {
187 $limit = $self->__max_int;
188 }
189
190
191 my ($sql, @bind);
192671632.6ms if ($limit) {
193 # this is legacy code-flow from SQLA::Limit, it is not set in stone
194
195566µs ($sql, @bind) = $self->next::method ($table, $fields, $where);
# spent 66µs making 5 calls to next::method, avg 13µs/call
196
197 my $limiter =
198 $self->can ('emulate_limit') # also backcompat hook from SQLA::Limit
199 ||
2001069µs520µs do {
# spent 20µs making 5 calls to UNIVERSAL::can, avg 4µs/call
2012130µs my $dialect = $self->limit_dialect
# spent 128µs making 1 call to DBIx::Class::SQLMaker::limit_dialect # spent 3µs making 1 call to DBIx::Class::SQLMaker::SQLite::limit_dialect
202 or $self->throw_exception( "Unable to generate SQL-limit - no limit dialect specified on $self, and no emulate_limit method found" );
203513µs $self->can ("_$dialect")
# spent 13µs making 5 calls to UNIVERSAL::can, avg 3µs/call
204 or $self->throw_exception(__PACKAGE__ . " does not implement the requested dialect '$dialect'");
205 }
206 ;
207
208 $sql = $self->$limiter (
209 $sql,
21052.85ms { %{$rs_attrs||{}}, _selector_sql => $fields },
# spent 2.85ms making 5 calls to DBIx::Class::SQLMaker::LimitDialects::_LimitOffset, avg 570µs/call
211 $limit,
212 $offset
213 );
214 }
215 else {
216670144.8ms ($sql, @bind) = $self->next::method ($table, $fields, $where, $rs_attrs);
# spent 44.8ms making 6701 calls to next::method, avg 7µs/call
217 }
218
219 push @{$self->{where_bind}}, @bind;
220
221# this *must* be called, otherwise extra binds will remain in the sql-maker
222670659.1ms my @all_bind = $self->_assemble_binds;
# spent 59.1ms making 6706 calls to DBIx::Class::SQLMaker::_assemble_binds, avg 9µs/call
223
224 $sql .= $self->_lock_select ($rs_attrs->{for})
225 if $rs_attrs->{for};
226
227 return wantarray ? ($sql, @all_bind) : $sql;
228}
229
230
# spent 59.1ms within DBIx::Class::SQLMaker::_assemble_binds which was called 6706 times, avg 9µs/call: # 6706 times (59.1ms+0s) by DBIx::Class::SQLMaker::select at line 222, avg 9µs/call
sub _assemble_binds {
2311341268.3ms my $self = shift;
232 return map { @{ (delete $self->{"${_}_bind"}) || [] } } (qw/select from where group having order limit/);
233}
234
23512µsmy $for_syntax = {
236 update => 'FOR UPDATE',
237 shared => 'FOR SHARE',
238};
239sub _lock_select {
240 my ($self, $type) = @_;
241 my $sql = $for_syntax->{$type} || $self->throw_exception( "Unknown SELECT .. FOR type '$type' requested" );
242 return " $sql";
243}
244
245# Handle default inserts
246
# spent 431ms (8.16+423) within DBIx::Class::SQLMaker::insert which was called 449 times, avg 961µs/call: # 449 times (8.16ms+423ms) by DBIx::Class::Storage::DBI::_gen_sql_bind at line 1428 of DBIx/Class/Storage/DBI.pm, avg 961µs/call
sub insert {
247# optimized due to hotttnesss
248# my ($self, $table, $data, $options) = @_;
249
250 # SQLA will emit INSERT INTO $table ( ) VALUES ( )
251 # which is sadly understood only by MySQL. Change default behavior here,
252 # until SQLA2 comes with proper dialect support
2538985.47ms if (! $_[2] or (ref $_[2] eq 'HASH' and !keys %{$_[2]} ) ) {
254 my @bind;
255 my $sql = sprintf(
256 'INSERT INTO %s DEFAULT VALUES', $_[0]->_quote($_[1])
257 );
258
259 if ( ($_[3]||{})->{returning} ) {
260 my $s;
261 ($s, @bind) = $_[0]->_insert_returning ($_[3]);
262 $sql .= $s;
263 }
264
265 return ($sql, @bind);
266 }
267
2684499.18ms next::method(@_);
# spent 9.18ms making 449 calls to next::method, avg 20µs/call
269}
270
271
# spent 1.43s (392ms+1.04) within DBIx::Class::SQLMaker::_recurse_fields which was called 45197 times, avg 32µs/call: # 36394 times (201ms+-201ms) by DBIx::Class::SQLMaker::_recurse_fields at line 278, avg 0s/call # 6706 times (176ms+1.24s) by DBIx::Class::SQLMaker::select at line 174, avg 212µs/call # 1949 times (13.2ms+-13.2ms) by DBIx::Class::SQLMaker::_recurse_fields at line 300, avg 0s/call # 147 times (2.35ms+9.60ms) by DBIx::Class::Storage::DBIHacks::_resolve_aliastypes_from_select_args at line 333 of DBIx/Class/Storage/DBIHacks.pm, avg 81µs/call # once (5µs+21µs) by DBIx::Class::SQLMaker::_parse_rs_attrs at line 337
sub _recurse_fields {
272153197188ms my ($self, $fields) = @_;
273 my $ref = ref $fields;
274363941.03s return $self->_quote($fields) unless $ref;
# spent 1.03s making 36394 calls to DBIx::Class::SQLMaker::_quote, avg 28µs/call
275 return $$fields if $ref eq 'SCALAR';
276
2772049787.7ms if ($ref eq 'ARRAY') {
2783639475.6ms363940s return join(', ', map { $self->_recurse_fields($_) } @$fields);
# spent 1.25s making 36394 calls to DBIx::Class::SQLMaker::_recurse_fields, avg 34µs/call, recursion: max depth 1, sum of overlapping time 1.25s
279 }
280 elsif ($ref eq 'HASH') {
281 my %hash = %$fields; # shallow copy
282
283 my $as = delete $hash{-as}; # if supplied
284
285 my ($func, $args, @toomany) = %hash;
286
287 # there should be only one pair
288 if (@toomany) {
289 $self->throw_exception( "Malformed select argument - too many keys in hash: " . join (',', keys %$fields ) );
290 }
291
292 if (lc ($func) eq 'distinct' && ref $args eq 'ARRAY' && @$args > 1) {
293 $self->throw_exception (
294 'The select => { distinct => ... } syntax is not supported for multiple columns.'
295 .' Instead please use { group_by => [ qw/' . (join ' ', @$args) . '/ ] }'
296 .' or { select => [ qw/' . (join ' ', @$args) . '/ ], distinct => 1 }'
297 );
298 }
299
30038987.40ms my $select = sprintf ('%s( %s )%s',
# spent 7.40ms making 1949 calls to SQL::Abstract::_sqlcase, avg 4µs/call # spent 112ms making 1949 calls to DBIx::Class::SQLMaker::_recurse_fields, avg 57µs/call, recursion: max depth 2, sum of overlapping time 112ms
301 $self->_sqlcase($func),
302 $self->_recurse_fields($args),
303 $as
304 ? sprintf (' %s %s', $self->_sqlcase('as'), $self->_quote ($as) )
305 : ''
306 );
307
308 return $select;
309 }
310 # Is the second check absolutely necessary?
311 elsif ( $ref eq 'REF' and ref($$fields) eq 'ARRAY' ) {
312 push @{$self->{select_bind}}, @{$$fields}[1..$#$$fields];
313 return $$fields->[0];
314 }
315 else {
316 $self->throw_exception( $ref . qq{ unexpected in _recurse_fields()} );
317 }
318}
319
320
321# this used to be a part of _order_by but is broken out for clarity.
322# What we have been doing forever is hijacking the $order arg of
323# SQLA::select to pass in arbitrary pieces of data (first the group_by,
324# then pretty much the entire resultset attr-hash, as more and more
325# things in the SQLA space need to have mopre info about the $rs they
326# create SQL for. The alternative would be to keep expanding the
327# signature of _select with more and more positional parameters, which
328# is just gross. All hail SQLA2!
329
# spent 154ms (45.3+109) within DBIx::Class::SQLMaker::_parse_rs_attrs which was called 6853 times, avg 22µs/call: # 6701 times (44.4ms+106ms) by DBIx::Class::SQLMaker::_order_by at line 360, avg 22µs/call # 147 times (814µs+0s) by DBIx::Class::Storage::DBIHacks::_resolve_aliastypes_from_select_args at line 333 of DBIx/Class/Storage/DBIHacks.pm, avg 6µs/call # 5 times (77µs+2.63ms) by DBIx::Class::SQLMaker::LimitDialects::_LimitOffset at line 53 of DBIx/Class/SQLMaker/LimitDialects.pm, avg 542µs/call
sub _parse_rs_attrs {
3304111851.7ms my ($self, $arg) = @_;
331
332 my $sql = '';
333
33424µs if ($arg->{group_by}) {
335 # horible horrible, waiting for refactor
336 local $self->{select_bind};
33725µs126µs if (my $g = $self->_recurse_fields($arg->{group_by}) ) {
# spent 26µs making 1 call to DBIx::Class::SQLMaker::_recurse_fields
33813µs $sql .= $self->_sqlcase(' group by ') . $g;
# spent 3µs making 1 call to SQL::Abstract::_sqlcase
339 push @{$self->{group_bind} ||= []}, @{$self->{select_bind}||[]};
340 }
341 }
342
343 if (defined $arg->{having}) {
344 my ($frag, @bind) = $self->_recurse_where($arg->{having});
345 push(@{$self->{having_bind}}, @bind);
346 $sql .= $self->_sqlcase(' having ') . $frag;
347 }
348
3496292.63ms if (defined $arg->{order_by}) {
# spent 109ms making 629 calls to DBIx::Class::SQLMaker::_order_by, avg 173µs/call, recursion: max depth 1, sum of overlapping time 106ms
350 $sql .= $self->_order_by ($arg->{order_by});
351 }
352
353 return $sql;
354}
355
356
# spent 440ms (258+182) within DBIx::Class::SQLMaker::_order_by which was called 7330 times, avg 60µs/call: # 6701 times (251ms+186ms) by SQL::Abstract::where at line 403 of SQL/Abstract.pm, avg 65µs/call # 629 times (7.20ms+-4.57ms) by DBIx::Class::SQLMaker::_parse_rs_attrs at line 349, avg 4µs/call
sub _order_by {
3571466094.1ms my ($self, $arg) = @_;
358
359 # check that we are not called in legacy mode (order_by as 4th argument)
36081362195ms86176186ms if (ref $arg eq 'HASH' and not grep { $_ =~ /^-(?:desc|asc)/i } keys %$arg ) {
# spent 150ms making 6701 calls to DBIx::Class::SQLMaker::_parse_rs_attrs, avg 22µs/call # spent 36.0ms making 79475 calls to DBIx::Class::SQLMaker::CORE:match, avg 453ns/call
361 return $self->_parse_rs_attrs ($arg);
362 }
363 else {
3646293.44ms my ($sql, @bind) = $self->next::method($arg);
# spent 3.44ms making 629 calls to next::method, avg 5µs/call
365 push @{$self->{order_bind}}, @bind;
366 return $sql;
367 }
368}
369
370
# spent 1.01s (74.5ms+932ms) within DBIx::Class::SQLMaker::_table which was called 8019 times, avg 125µs/call: # 6706 times (53.2ms+713ms) by SQL::Abstract::select at line 354 of SQL/Abstract.pm, avg 114µs/call # 845 times (13.2ms+135ms) by SQL::Abstract::update at line 276 of SQL/Abstract.pm, avg 175µs/call # 449 times (7.68ms+80.0ms) by SQL::Abstract::insert at line 137 of SQL/Abstract.pm, avg 195µs/call # 19 times (460µs+4.38ms) by SQL::Abstract::delete at line 377 of SQL/Abstract.pm, avg 255µs/call
sub _table {
371# optimized due to hotttnesss
372# my ($self, $from) = @_;
3731603868.9ms if (my $ref = ref $_[1] ) {
3746706713ms if ($ref eq 'ARRAY') {
# spent 713ms making 6706 calls to DBIx::Class::SQLMaker::_recurse_from, avg 106µs/call
375 return $_[0]->_recurse_from(@{$_[1]});
376 }
377 elsif ($ref eq 'HASH') {
378 return $_[0]->_recurse_from($_[1]);
379 }
380 elsif ($ref eq 'REF' && ref ${$_[1]} eq 'ARRAY') {
381 my ($sql, @bind) = @{ ${$_[1]} };
382 push @{$_[0]->{from_bind}}, @bind;
383 return $sql
384 }
385 }
386131314.8ms return $_[0]->next::method ($_[1]);
# spent 14.8ms making 1313 calls to next::method, avg 11µs/call
387}
388
389
# spent 982µs within DBIx::Class::SQLMaker::_generate_join_clause which was called 147 times, avg 7µs/call: # 147 times (982µs+0s) by DBIx::Class::SQLMaker::_gen_from_blocks at line 422, avg 7µs/call
sub _generate_join_clause {
3904411.18ms my ($self, $join_type) = @_;
391
392 $join_type = $self->{_default_jointype}
393 if ! defined $join_type;
394
395 return sprintf ('%s JOIN ',
396 $join_type ? $self->_sqlcase($join_type) : ''
397 );
398}
399
400
# spent 713ms (49.2+663) within DBIx::Class::SQLMaker::_recurse_from which was called 6706 times, avg 106µs/call: # 6706 times (49.2ms+663ms) by DBIx::Class::SQLMaker::_table at line 374, avg 106µs/call
sub _recurse_from {
4011341245.9ms my $self = shift;
402
4036706663ms return join (' ', $self->_gen_from_blocks(@_) );
# spent 663ms making 6706 calls to DBIx::Class::SQLMaker::_gen_from_blocks, avg 99µs/call
404}
405
406
# spent 663ms (69.2+594) within DBIx::Class::SQLMaker::_gen_from_blocks which was called 6706 times, avg 99µs/call: # 6706 times (69.2ms+594ms) by DBIx::Class::SQLMaker::_recurse_from at line 403, avg 99µs/call
sub _gen_from_blocks {
4072682469.3ms my ($self, $from, @joins) = @_;
408
4096706553ms my @fchunks = $self->_from_chunk_to_sql($from);
# spent 553ms making 6706 calls to DBIx::Class::SQLMaker::_from_chunk_to_sql, avg 83µs/call
410
411 for (@joins) {
41214702.27ms my ($to, $on) = @$_;
413
414 # check whether a join type exists
415 my $to_jt = ref($to) eq 'ARRAY' ? $to->[0] : $to;
416 my $join_type;
417 if (ref($to_jt) eq 'HASH' and defined($to_jt->{-join_type})) {
418 $join_type = $to_jt->{-join_type};
419 $join_type =~ s/^\s+ | \s+$//xg;
420 }
421
422147982µs my @j = $self->_generate_join_clause( $join_type );
# spent 982µs making 147 calls to DBIx::Class::SQLMaker::_generate_join_clause, avg 7µs/call
423
424147255µs if (ref $to eq 'ARRAY') {
425 push(@j, '(', $self->_recurse_from(@$to), ')');
426 }
427 else {
4281479.10ms push(@j, $self->_from_chunk_to_sql($to));
# spent 9.10ms making 147 calls to DBIx::Class::SQLMaker::_from_chunk_to_sql, avg 62µs/call
429 }
430
43114730.7ms my ($sql, @bind) = $self->_join_condition($on);
# spent 30.7ms making 147 calls to DBIx::Class::SQLMaker::_join_condition, avg 209µs/call
432 push(@j, ' ON ', $sql);
433 push @{$self->{from_bind}}, @bind;
434
435 push @fchunks, join '', @j;
436 }
437
438 return @fchunks;
439}
440
441
# spent 563ms (231+332) within DBIx::Class::SQLMaker::_from_chunk_to_sql which was called 13706 times, avg 41µs/call: # 6853 times (40.3ms+-40.3ms) by DBIx::Class::SQLMaker::_from_chunk_to_sql at line 464, avg 0s/call # 6706 times (187ms+366ms) by DBIx::Class::SQLMaker::_gen_from_blocks at line 409, avg 83µs/call # 147 times (3.03ms+6.07ms) by DBIx::Class::SQLMaker::_gen_from_blocks at line 428, avg 62µs/call
sub _from_chunk_to_sql {
4422741262.9ms my ($self, $fromspec) = @_;
443
4441370633.9ms return join (' ', do {
4452055967.0ms6853166ms if (! ref $fromspec) {
# spent 166ms making 6853 calls to DBIx::Class::SQLMaker::_quote, avg 24µs/call
446 $self->_quote($fromspec);
447 }
448 elsif (ref $fromspec eq 'SCALAR') {
449 $$fromspec;
450 }
451 elsif (ref $fromspec eq 'REF' and ref $$fromspec eq 'ARRAY') {
452 push @{$self->{from_bind}}, @{$$fromspec}[1..$#$$fromspec];
453 $$fromspec->[0];
454 }
455 elsif (ref $fromspec eq 'HASH') {
456 my ($as, $table, $toomuch) = ( map
4572100023.3ms { $_ => $fromspec->{$_} }
# spent 23.3ms making 21000 calls to DBIx::Class::SQLMaker::CORE:match, avg 1µs/call
4582100076.5ms ( grep { $_ !~ /^\-/ } keys %$fromspec )
459 );
460
461 $self->throw_exception( "Only one table/as pair expected in from-spec but an exra '$toomuch' key present" )
462 if defined $toomuch;
463
46413706143ms ($self->_from_chunk_to_sql($table), $self->_quote($as) );
# spent 143ms making 6853 calls to DBIx::Class::SQLMaker::_quote, avg 21µs/call # spent 206ms making 6853 calls to DBIx::Class::SQLMaker::_from_chunk_to_sql, avg 30µs/call, recursion: max depth 1, sum of overlapping time 206ms
465 }
466 else {
467 $self->throw_exception('Unsupported from refkind: ' . ref $fromspec );
468 }
469 });
470}
471
472
# spent 30.7ms (1.57+29.1) within DBIx::Class::SQLMaker::_join_condition which was called 147 times, avg 209µs/call: # 147 times (1.57ms+29.1ms) by DBIx::Class::SQLMaker::_gen_from_blocks at line 431, avg 209µs/call
sub _join_condition {
4734411.60ms my ($self, $cond) = @_;
474
475 # Backcompat for the old days when a plain hashref
476 # { 't1.col1' => 't2.col2' } meant ON t1.col1 = t2.col2
477 # Once things settle we should start warning here so that
478 # folks unroll their hacks
479147114µs if (
# spent 114µs making 147 calls to DBIx::Class::SQLMaker::CORE:match, avg 776ns/call
480 ref $cond eq 'HASH'
481 and
482 keys %$cond == 1
483 and
484 (keys %$cond)[0] =~ /\./
485 and
486 ! ref ( (values %$cond)[0] )
487 ) {
488 $cond = { keys %$cond => { -ident => values %$cond } }
489 }
490 elsif ( ref $cond eq 'ARRAY' ) {
491 # do our own ORing so that the hashref-shim above is invoked
492 my @parts;
493 my @binds;
494 foreach my $c (@$cond) {
495 my ($sql, @bind) = $self->_join_condition($c);
496 push @binds, @bind;
497 push @parts, $sql;
498 }
499 return join(' OR ', @parts), @binds;
500 }
501
50214729.0ms return $self->_recurse_where($cond);
# spent 29.0ms making 147 calls to SQL::Abstract::_recurse_where, avg 197µs/call
503}
504
50516µs1;
506
507=head1 OPERATORS
508
509=head2 -ident
510
511Used to explicitly specify an SQL identifier. Takes a plain string as value
512which is then invariably treated as a column name (and is being properly
513quoted if quoting has been requested). Most useful for comparison of two
514columns:
515
516 my %where = (
517 priority => { '<', 2 },
518 requestor => { -ident => 'submitter' }
519 );
520
521which results in:
522
523 $stmt = 'WHERE "priority" < ? AND "requestor" = "submitter"';
524 @bind = ('2');
525
526=head2 -value
527
528The -value operator signals that the argument to the right is a raw bind value.
529It will be passed straight to DBI, without invoking any of the SQL::Abstract
530condition-parsing logic. This allows you to, for example, pass an array as a
531column value for databases that support array datatypes, e.g.:
532
533 my %where = (
534 array => { -value => [1, 2, 3] }
535 );
536
537which results in:
538
539 $stmt = 'WHERE array = ?';
540 @bind = ([1, 2, 3]);
541
542=head1 AUTHORS
543
544See L<DBIx::Class/CONTRIBUTORS>.
545
546=head1 LICENSE
547
548You may distribute this code under the same terms as Perl itself.
549
550116µs1333µs=cut
 
# spent 59.4ms within DBIx::Class::SQLMaker::CORE:match which was called 100627 times, avg 591ns/call: # 79475 times (36.0ms+0s) by DBIx::Class::SQLMaker::_order_by at line 360, avg 453ns/call # 21000 times (23.3ms+0s) by DBIx::Class::SQLMaker::_from_chunk_to_sql at line 457, avg 1µs/call # 147 times (114µs+0s) by DBIx::Class::SQLMaker::_join_condition at line 479, avg 776ns/call # 5 times (6µs+0s) by DBIx::Class::SQLMaker::select at line 183, avg 1µs/call
sub DBIx::Class::SQLMaker::CORE:match; # opcode
# spent 19µs within DBIx::Class::SQLMaker::CORE:qr which was called 10 times, avg 2µs/call: # 10 times (19µs+0s) by DBIx::Class::SQLMaker::new at line 108, avg 2µs/call
sub DBIx::Class::SQLMaker::CORE:qr; # opcode