- Fix update/delete operations on resultsets *joining* the updated
table failing on MySQL. Resolves oversights in the fixes for
RT#81378 and RT#81897
+ - Stop Sybase ASE storage from generating invalid SQL in subselects
+ when a limit without offset is encountered
0.08210 2013-04-04 15:30 (UTC)
* New Features / Changes
return $sql;
}
-=head2 RowCountOrGenericSubQ
-
-This is not exactly a limit dialect, but more of a proxy for B<Sybase ASE>.
-If no $offset is supplied the limit is simply performed as:
-
- SET ROWCOUNT $limit
- SELECT ...
- SET ROWCOUNT 0
-
-Otherwise we fall back to L</GenericSubQ>
-
-=cut
-
-sub _RowCountOrGenericSubQ {
- my $self = shift;
- my ($sql, $rs_attrs, $rows, $offset) = @_;
-
- return $self->_GenericSubQ(@_) if $offset;
-
- return sprintf <<"EOF", $rows, $sql, $self->_parse_rs_attrs( $rs_attrs );
-SET ROWCOUNT %d
-%s %s
-SET ROWCOUNT 0
-EOF
-}
-
=head2 GenericSubQ
SELECT * FROM (
use Context::Preserve 'preserve_context';
use namespace::clean;
-__PACKAGE__->sql_limit_dialect ('RowCountOrGenericSubQ');
+__PACKAGE__->sql_limit_dialect ('GenericSubQ');
__PACKAGE__->sql_quote_char ([qw/[ ]/]);
__PACKAGE__->datetime_parser_type(
'DBIx::Class::Storage::DBI::Sybase::ASE::DateTime::Format'
}
sub _prep_for_execute {
- my $self = shift;
- my $ident = $_[1];
+ my ($self, $op, $ident, $args) = @_;
#
### This is commented out because all tests pass. However I am leaving it
# = $self->_parent_storage->_perform_autoinc_retrieval
#if ($op eq 'insert' or $op eq 'update') and $self->_parent_storage;
- my ($sql, $bind) = $self->next::method (@_);
+ my $limit; # extract and use shortcut on limit without offset
+ if ($op eq 'select' and ! $args->[4] and $limit = $args->[3]) {
+ $args = [ @$args ];
+ $args->[3] = undef;
+ }
+
+ my ($sql, $bind) = $self->next::method($op, $ident, $args);
+
+ # $limit is already sanitized by now
+ $sql = join( "\n",
+ "SET ROWCOUNT $limit",
+ $sql,
+ "SET ROWCOUNT 0",
+ ) if $limit;
if (my $identity_col = $self->_perform_autoinc_retrieval) {
$sql .= "\n" . $self->_fetch_identity_sql($ident, $identity_col)
],
},
- RowCountOrGenericSubQ => {
- limit => [
- '(
- SET ROWCOUNT 4
- SELECT me.id, owner.id, owner.name, ? * ?, ?
- FROM books me
- JOIN owners owner
- ON owner.id = me.owner
- WHERE source != ? AND me.title = ? AND source = ?
- GROUP BY avg(me.id / ?)
- HAVING ?
- ORDER BY me.id
- SET ROWCOUNT 0
- )',
- [
- @select_bind,
- @where_bind,
- @group_bind,
- @having_bind,
- ],
- ],
- limit_offset => [
- '(
- SELECT me.id, owner__id, owner__name, bar, baz
- FROM (
- SELECT me.id, owner.id AS owner__id, owner.name AS owner__name, ? * ? AS bar, ? AS baz
- FROM books me
- JOIN owners owner
- ON owner.id = me.owner
- WHERE source != ? AND me.title = ? AND source = ?
- GROUP BY avg( me.id / ? )
- HAVING ?
- ) me
- WHERE (
- SELECT COUNT( * )
- FROM books rownum__emulation
- WHERE rownum__emulation.id < me.id
- ) BETWEEN ? AND ?
- ORDER BY me.id
- )',
- [
- @select_bind,
- @where_bind,
- @group_bind,
- @having_bind,
- [ { sqlt_datatype => 'integer' } => 3 ],
- [ { sqlt_datatype => 'integer' } => 6 ],
- ],
- ],
- },
-
GenericSubQ => {
limit => [
'(