Profile of DBIx/Class/SQLMaker.pm

← 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:24:07 2012

Filename | /2home/ss5/perl5/perlbrew/perls/perl-5.12.3/lib/site_perl/5.12.3/DBIx/Class/SQLMaker.pm
Statements | Executed 648511 statements in 1.68s

Subroutines
Calls | P | F | Exclusive Time | Inclusive Time | Subroutine
--- | --- | --- | --- | --- | ---
63788 | 10 | 2 | 423ms | 1.77s | DBIx::Class::SQLMaker::::_quoteDBIx::Class::SQLMaker::_quote
45197 | 5 | 2 | 392ms | 1.43s | DBIx::Class::SQLMaker::::_recurse_fieldsDBIx::Class::SQLMaker::_recurse_fields (recurses: max depth 2, inclusive time 1.36s)
7330 | 2 | 2 | 258ms | 440ms | DBIx::Class::SQLMaker::::_order_byDBIx::Class::SQLMaker::_order_by (recurses: max depth 1, inclusive time 106ms)
13706 | 3 | 1 | 231ms | 563ms | DBIx::Class::SQLMaker::::_from_chunk_to_sqlDBIx::Class::SQLMaker::_from_chunk_to_sql (recurses: max depth 1, inclusive time 206ms)
6706 | 1 | 1 | 208ms | 4.80s | DBIx::Class::SQLMaker::::selectDBIx::Class::SQLMaker::select
8019 | 4 | 1 | 74.5ms | 1.01s | DBIx::Class::SQLMaker::::_tableDBIx::Class::SQLMaker::_table
6706 | 1 | 1 | 69.2ms | 663ms | DBIx::Class::SQLMaker::::_gen_from_blocksDBIx::Class::SQLMaker::_gen_from_blocks
100627 | 4 | 1 | 59.4ms | 59.4ms | DBIx::Class::SQLMaker::::CORE:matchDBIx::Class::SQLMaker::CORE:match (opcode)
6706 | 1 | 1 | 59.1ms | 59.1ms | DBIx::Class::SQLMaker::::_assemble_bindsDBIx::Class::SQLMaker::_assemble_binds
6706 | 1 | 1 | 49.2ms | 713ms | DBIx::Class::SQLMaker::::_recurse_fromDBIx::Class::SQLMaker::_recurse_from
6853 | 3 | 3 | 45.3ms | 154ms | DBIx::Class::SQLMaker::::_parse_rs_attrsDBIx::Class::SQLMaker::_parse_rs_attrs
449 | 1 | 1 | 8.16ms | 431ms | DBIx::Class::SQLMaker::::insertDBIx::Class::SQLMaker::insert
147 | 1 | 1 | 2.61ms | 8.56ms | DBIx::Class::SQLMaker::::_where_op_IDENTDBIx::Class::SQLMaker::_where_op_IDENT
147 | 1 | 1 | 1.57ms | 30.7ms | DBIx::Class::SQLMaker::::_join_conditionDBIx::Class::SQLMaker::_join_condition
147 | 1 | 1 | 1.13ms | 1.13ms | DBIx::Class::SQLMaker::::_quote_charsDBIx::Class::SQLMaker::_quote_chars
147 | 1 | 1 | 982µs | 982µs | DBIx::Class::SQLMaker::::_generate_join_clauseDBIx::Class::SQLMaker::_generate_join_clause
5 | 1 | 1 | 144µs | 625µs | DBIx::Class::SQLMaker::::newDBIx::Class::SQLMaker::new
1 | 1 | 1 | 33µs | 248µs | DBIx::Class::SQLMaker::::BEGIN@64DBIx::Class::SQLMaker::BEGIN@64
10 | 1 | 1 | 19µs | 19µs | DBIx::Class::SQLMaker::::CORE:qrDBIx::Class::SQLMaker::CORE:qr (opcode)
1 | 1 | 1 | 14µs | 19µs | DBIx::Class::SQLMaker::::BEGIN@3DBIx::Class::SQLMaker::BEGIN@3
1 | 1 | 1 | 12µs | 24µs | DBIx::Class::SQLMaker::::BEGIN@43DBIx::Class::SQLMaker::BEGIN@43
1 | 1 | 1 | 12µs | 52µs | DBIx::Class::SQLMaker::::BEGIN@45DBIx::Class::SQLMaker::BEGIN@45
1 | 1 | 1 | 11µs | 28µs | DBIx::Class::SQLMaker::::BEGIN@4DBIx::Class::SQLMaker::BEGIN@4
1 | 1 | 1 | 10µs | 30µs | DBIx::Class::SQLMaker::::BEGIN@67DBIx::Class::SQLMaker::BEGIN@67
1 | 1 | 1 | 9µs | 103µs | DBIx::Class::SQLMaker::::BEGIN@46DBIx::Class::SQLMaker::BEGIN@46
1 | 1 | 1 | 9µs | 9.28ms | DBIx::Class::SQLMaker::::BEGIN@38DBIx::Class::SQLMaker::BEGIN@38
1 | 1 | 1 | 7µs | 180µs | DBIx::Class::SQLMaker::::BEGIN@48DBIx::Class::SQLMaker::BEGIN@48
1 | 1 | 1 | 6µs | 6µs | DBIx::Class::SQLMaker::::BEGIN@47DBIx::Class::SQLMaker::BEGIN@47
0 | 0 | 0 | 0s | 0s | DBIx::Class::SQLMaker::::__ANON__[:72]DBIx::Class::SQLMaker::__ANON__[:72]
0 | 0 | 0 | 0s | 0s | DBIx::Class::SQLMaker::::__ANON__[:77]DBIx::Class::SQLMaker::__ANON__[:77]
0 | 0 | 0 | 0s | 0s | DBIx::Class::SQLMaker::::_lock_selectDBIx::Class::SQLMaker::_lock_select
0 | 0 | 0 | 0s | 0s | DBIx::Class::SQLMaker::::_where_op_NESTDBIx::Class::SQLMaker::_where_op_NEST
0 | 0 | 0 | 0s | 0s | DBIx::Class::SQLMaker::::_where_op_VALUEDBIx::Class::SQLMaker::_where_op_VALUE
0 | 0 | 0 | 0s | 0s | DBIx::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
--- | --- | --- | --- | --- | ---
1 |  |  |  |  | package DBIx::Class::SQLMaker;
2 |  |  |  |  |
3 | 3 | 22µs | 2 | 24µ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
4 | 3 | 38µs | 2 | 45µ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 |  |  |  |  |
8 |  |  |  |  | DBIx::Class::SQLMaker - An SQL::Abstract-based SQL maker class
9 |  |  |  |  |
10 |  |  |  |  | =head1 DESCRIPTION
11 |  |  |  |  |
12 |  |  |  |  | This module is a subclass of L<SQL::Abstract> and includes a number of
13 |  |  |  |  | DBIC-specific workarounds, not yet suitable for inclusion into the
14 |  |  |  |  | L<SQL::Abstract> core. It also provides all (and more than) the functionality
15 |  |  |  |  | of L<SQL::Abstract::Limit>, see L<DBIx::Class::SQLMaker::LimitDialects> for
16 |  |  |  |  | more info.
17 |  |  |  |  |
18 |  |  |  |  | Currently 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 |  |  |  |  |
38 | 1 | 6µs | 1 | 0s | # 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
42 | 2 | 29µs | 1 | 9.28ms | /; # spent 9.28ms making 1 call to DBIx::Class::SQLMaker::BEGIN@38
43 | 3 | 23µs | 2 | 35µ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 |  |  |  |  |
45 | 3 | 24µs | 2 | 92µ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
46 | 3 | 22µs | 2 | 198µ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
47 | 3 | 19µs | 1 | 6µ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
48 | 3 | 110µs | 2 | 352µ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 |  |  |  |  |
50 | 1 | 40µs | 1 | 233µ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 $_ ? $_ : '' }
56 | 147 | 1.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
62 |  |  |  |  | sub 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
67 | 3 | 118µs | 2 | 50µ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: ", @_;
72 | 1 | 19µs | 1 | 3µ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 ('', @_));
77 | 1 | 12µs | 1 | 2µs | }; # spent 2µs making 1 call to Sub::Name::subname
78 |  |  |  |  |
79 |  |  |  |  | # Current SQLA pollutes its namespace - clean for the time being
80 | 1 | 6µs | 1 | 209µs | namespace::clean->clean_subroutines(qw/SQL::Abstract carp croak confess/); # spent 209µs making 1 call to namespace::clean::clean_subroutines
81 | 1 | 1.73ms | 1 | 248µ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)
94 |  |  |  |  | sub __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 {
98 | 63788 | 315ms | 63788 | 422ms | $_[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 {
105 | 5 | 30µs | 5 | 90µ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
108 | 5 | 73µs | 10 | 19µ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 | 5 | 6µs |  |  | push @{$self->{special_ops}}, @extra_dbic_syntax;
114 | 5 | 6µs |  |  | push @{$self->{unary_ops}}, @extra_dbic_syntax;
115 |  |  |  |  |
116 | 5 | 23µs |  |  | $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 {
120 | 147 | 96µs |  |  | my $self = shift;
121 | 147 | 339µs |  |  | my ($op, $rhs) = splice @_, -2;
122 | 147 | 63µs |  |  | 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 | 147 | 114µs |  |  | my $lhs = shift;
128 |  |  |  |  |
129 | 294 | 1.10ms | 588 | 5.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 | 147 | 481µs |  |  | return $lhs
132 |  |  |  |  | ? "$lhs = $rhs"
133 |  |  |  |  | : $rhs
134 |  |  |  |  | ;
135 |  |  |  |  | }
136 |  |  |  |  |
137 |  |  |  |  | sub _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 |  |  |  |  |
161 |  |  |  |  | sub _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 {
171 | 6706 | 13.5ms |  |  | my ($self, $table, $fields, $where, $rs_attrs, $limit, $offset) = @_;
172 |  |  |  |  |
173 |  |  |  |  |
174 | 6706 | 25.1ms | 6706 | 1.42s | $fields = $self->_recurse_fields($fields); # spent 1.42s making 6706 calls to DBIx::Class::SQLMaker::_recurse_fields, avg 212µs/call
175 |  |  |  |  |
176 | 6706 | 3.19ms |  |  | 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 | 6706 | 4.16ms |  |  | $offset ||= 0;
181 |  |  |  |  |
182 | 6706 | 3.56ms |  |  | if (defined $limit) {
183 | 5 | 35µs | 5 | 6µ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 | 6706 | 4.63ms |  |  | my ($sql, @bind);
192 | 6706 | 6.59ms |  |  | if ($limit) {
193 |  |  |  |  | # this is legacy code-flow from SQLA::Limit, it is not set in stone
194 |  |  |  |  |
195 | 5 | 29µs | 5 | 66µ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 |  |  |  |  | ||
200 | 5 | 49µs | 5 | 20µs | do { # spent 20µs making 5 calls to UNIVERSAL::can, avg 4µs/call
201 | 5 | 28µs | 2 | 130µ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" );
203 | 5 | 41µs | 5 | 13µ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,
210 | 5 | 87µs | 5 | 2.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 {
216 | 6701 | 32.5ms | 6701 | 44.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 | 6706 | 12.3ms |  |  | push @{$self->{where_bind}}, @bind;
220 |  |  |  |  |
221 |  |  |  |  | # this *must* be called, otherwise extra binds will remain in the sql-maker
222 | 6706 | 25.7ms | 6706 | 59.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 | 6706 | 5.09ms |  |  | $sql .= $self->_lock_select ($rs_attrs->{for})
225 |  |  |  |  | if $rs_attrs->{for};
226 |  |  |  |  |
227 | 6706 | 29.1ms |  |  | 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 {
231 | 6706 | 4.70ms |  |  | my $self = shift;
232 | 6706 | 63.6ms |  |  | return map { @{ (delete $self->{"${_}_bind"}) || [] } } (qw/select from where group having order limit/);
233 |  |  |  |  | }
234 |  |  |  |  |
235 | 1 | 2µs |  |  | my $for_syntax = {
236 |  |  |  |  | update => 'FOR UPDATE',
237 |  |  |  |  | shared => 'FOR SHARE',
238 |  |  |  |  | };
239 |  |  |  |  | sub _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
253 | 449 | 1.79ms |  |  | 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 |  |  |  |  |
268 | 449 | 3.68ms | 449 | 9.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 {
272 | 45197 | 26.9ms |  |  | my ($self, $fields) = @_;
273 | 45197 | 19.5ms |  |  | my $ref = ref $fields;
274 | 45197 | 131ms | 36394 | 1.03s | return $self->_quote($fields) unless $ref; # spent 1.03s making 36394 calls to DBIx::Class::SQLMaker::_quote, avg 28µs/call
275 | 8803 | 5.32ms |  |  | return $$fields if $ref eq 'SCALAR';
276 |  |  |  |  |
277 | 8803 | 5.89ms |  |  | if ($ref eq 'ARRAY') {
278 | 43248 | 121ms | 36394 | 0s | 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 | 1949 | 6.45ms |  |  | my %hash = %$fields; # shallow copy
282 |  |  |  |  |
283 | 1949 | 2.45ms |  |  | my $as = delete $hash{-as}; # if supplied
284 |  |  |  |  |
285 | 1949 | 3.46ms |  |  | my ($func, $args, @toomany) = %hash;
286 |  |  |  |  |
287 |  |  |  |  | # there should be only one pair
288 | 1949 | 864µs |  |  | if (@toomany) {
289 |  |  |  |  | $self->throw_exception( "Malformed select argument - too many keys in hash: " . join (',', keys %$fields ) );
290 |  |  |  |  | }
291 |  |  |  |  |
292 | 1949 | 2.89ms |  |  | 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 |  |  |  |  |
300 | 1949 | 19.2ms | 3898 | 7.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 | 1949 | 7.26ms |  |  | 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 {
330 | 6853 | 6.19ms |  |  | my ($self, $arg) = @_;
331 |  |  |  |  |
332 | 6853 | 5.54ms |  |  | my $sql = '';
333 |  |  |  |  |
334 | 6853 | 5.24ms |  |  | if ($arg->{group_by}) {
335 |  |  |  |  | # horible horrible, waiting for refactor
336 | 1 | 2µs |  |  | local $self->{select_bind};
337 | 1 | 2µs | 1 | 26µs | if (my $g = $self->_recurse_fields($arg->{group_by}) ) { # spent 26µs making 1 call to DBIx::Class::SQLMaker::_recurse_fields
338 | 1 | 3µs | 1 | 3µs | $sql .= $self->_sqlcase(' group by ') . $g; # spent 3µs making 1 call to SQL::Abstract::_sqlcase
339 | 1 | 2µs |  |  | push @{$self->{group_bind} ||= []}, @{$self->{select_bind}||[]};
340 |  |  |  |  | }
341 |  |  |  |  | }
342 |  |  |  |  |
343 | 6853 | 5.32ms |  |  | 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 |  |  |  |  |
349 | 6853 | 5.60ms | 629 | 2.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 | 6853 | 23.8ms |  |  | 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 {
357 | 7330 | 6.23ms |  |  | my ($self, $arg) = @_;
358 |  |  |  |  |
359 |  |  |  |  | # check that we are not called in legacy mode (order_by as 4th argument)
360 | 86805 | 278ms | 86176 | 186ms | 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 {
364 | 629 | 1.54ms | 629 | 3.44ms | my ($sql, @bind) = $self->next::method($arg); # spent 3.44ms making 629 calls to next::method, avg 5µs/call
365 | 629 | 781µs |  |  | push @{$self->{order_bind}}, @bind;
366 | 629 | 1.96ms |  |  | 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) = @_;
373 | 8019 | 10.4ms |  |  | if (my $ref = ref $_[1] ) {
374 | 6706 | 46.8ms | 6706 | 713ms | 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 |  |  |  |  | }
386 | 1313 | 11.8ms | 1313 | 14.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 {
390 | 147 | 81µs |  |  | my ($self, $join_type) = @_;
391 |  |  |  |  |
392 | 147 | 108µs |  |  | $join_type = $self->{_default_jointype}
393 |  |  |  |  | if ! defined $join_type;
394 |  |  |  |  |
395 | 147 | 990µs |  |  | 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 {
401 | 6706 | 3.89ms |  |  | my $self = shift;
402 |  |  |  |  |
403 | 6706 | 42.0ms | 6706 | 663ms | 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 {
407 | 6706 | 8.79ms |  |  | my ($self, $from, @joins) = @_;
408 |  |  |  |  |
409 | 6706 | 27.5ms | 6706 | 553ms | 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 | 6706 | 7.60ms |  |  | for (@joins) {
412 | 147 | 123µs |  |  | my ($to, $on) = @$_;
413 |  |  |  |  |
414 |  |  |  |  | # check whether a join type exists
415 | 147 | 162µs |  |  | my $to_jt = ref($to) eq 'ARRAY' ? $to->[0] : $to;
416 | 147 | 42µs |  |  | my $join_type;
417 | 147 | 214µs |  |  | 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 |  |  |  |  |
422 | 147 | 509µs | 147 | 982µ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 |  |  |  |  |
424 | 147 | 174µs |  |  | if (ref $to eq 'ARRAY') {
425 |  |  |  |  | push(@j, '(', $self->_recurse_from(@$to), ')');
426 |  |  |  |  | }
427 |  |  |  |  | else {
428 | 147 | 255µs | 147 | 9.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 |  |  |  |  |
431 | 147 | 412µs | 147 | 30.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 | 147 | 128µs |  |  | push(@j, ' ON ', $sql);
433 | 147 | 178µs |  |  | push @{$self->{from_bind}}, @bind;
434 |  |  |  |  |
435 | 147 | 326µs |  |  | push @fchunks, join '', @j;
436 |  |  |  |  | }
437 |  |  |  |  |
438 | 6706 | 25.4ms |  |  | 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 {
442 | 13706 | 9.55ms |  |  | my ($self, $fromspec) = @_;
443 |  |  |  |  |
444 | 13706 | 53.3ms |  |  | return join (' ', do {
445 | 13706 | 33.9ms | 6853 | 166ms | 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
457 | 21000 | 76.5ms | 21000 | 23.3ms | { $_ => $fromspec->{$_} } # spent 23.3ms making 21000 calls to DBIx::Class::SQLMaker::CORE:match, avg 1µs/call
458 | 6853 | 39.1ms |  |  | ( grep { $_ !~ /^\-/ } keys %$fromspec )
459 |  |  |  |  | );
460 |  |  |  |  |
461 | 6853 | 2.85ms |  |  | $self->throw_exception( "Only one table/as pair expected in from-spec but an exra '$toomuch' key present" )
462 |  |  |  |  | if defined $toomuch;
463 |  |  |  |  |
464 | 6853 | 25.1ms | 13706 | 143ms | ($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 {
473 | 147 | 112µs |  |  | 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
479 | 147 | 964µs | 147 | 114µ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 |  |  |  |  |
502 | 147 | 523µs | 147 | 29.0ms | return $self->_recurse_where($cond); # spent 29.0ms making 147 calls to SQL::Abstract::_recurse_where, avg 197µs/call
503 |  |  |  |  | }
504 |  |  |  |  |
505 | 1 | 6µs |  |  | 1;
506 |  |  |  |  |
507 |  |  |  |  | =head1 OPERATORS
508 |  |  |  |  |
509 |  |  |  |  | =head2 -ident
510 |  |  |  |  |
511 |  |  |  |  | Used to explicitly specify an SQL identifier. Takes a plain string as value
512 |  |  |  |  | which is then invariably treated as a column name (and is being properly
513 |  |  |  |  | quoted if quoting has been requested). Most useful for comparison of two
514 |  |  |  |  | columns:
515 |  |  |  |  |
516 |  |  |  |  | my %where = (
517 |  |  |  |  | priority => { '<', 2 },
518 |  |  |  |  | requestor => { -ident => 'submitter' }
519 |  |  |  |  | );
520 |  |  |  |  |
521 |  |  |  |  | which results in:
522 |  |  |  |  |
523 |  |  |  |  | $stmt = 'WHERE "priority" < ? AND "requestor" = "submitter"';
524 |  |  |  |  | @bind = ('2');
525 |  |  |  |  |
526 |  |  |  |  | =head2 -value
527 |  |  |  |  |
528 |  |  |  |  | The -value operator signals that the argument to the right is a raw bind value.
529 |  |  |  |  | It will be passed straight to DBI, without invoking any of the SQL::Abstract
530 |  |  |  |  | condition-parsing logic. This allows you to, for example, pass an array as a
531 |  |  |  |  | column value for databases that support array datatypes, e.g.:
532 |  |  |  |  |
533 |  |  |  |  | my %where = (
534 |  |  |  |  | array => { -value => [1, 2, 3] }
535 |  |  |  |  | );
536 |  |  |  |  |
537 |  |  |  |  | which results in:
538 |  |  |  |  |
539 |  |  |  |  | $stmt = 'WHERE array = ?';
540 |  |  |  |  | @bind = ([1, 2, 3]);
541 |  |  |  |  |
542 |  |  |  |  | =head1 AUTHORS
543 |  |  |  |  |
544 |  |  |  |  | See L<DBIx::Class/CONTRIBUTORS>.
545 |  |  |  |  |
546 |  |  |  |  | =head1 LICENSE
547 |  |  |  |  |
548 |  |  |  |  | You may distribute this code under the same terms as Perl itself.
549 |  |  |  |  |
550 | 1 | 16µs | 1 | 333µs | =cut # spent 333µs making 1 call to B::Hooks::EndOfScope::__ANON__[B/Hooks/EndOfScope.pm:26]
|  |  |  |  | # 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