$self;
}
+sub _sqla_converter { shift->result_source->storage->sql_maker->converter }
+
+sub _order_by_dq {
+ my ($self) = @_;
+ if (my $o = $self->_resolved_attrs->{order_by}) {
+ return $self->_sqla_converter->_order_by_to_dq($o);
+ }
+ return undef;
+}
+
=head2 search
=over 4
use DBIx::Class::Carp;
use DBIx::Class::Exception;
+use Data::Query::Constants qw(DQ_IDENTIFIER);
+
# not importing first() as it will clash with our own method
use List::Util ();
# analyze the order_by, and see if it is done over a function/nonexistentcolumn
# if this is the case we will need to wrap a subquery since the result of RSC
# *must* be a single column select
- if (
- scalar grep
- { ! exists $colmap->{$_->[0]} }
- ( $rsrc->schema->storage->_extract_order_criteria ($orig_attrs->{order_by} ) )
- ) {
+
+ my $order_dq = $rs->_order_by_dq;
+ my $weirditude;
+
+ ORDER_DQ: while ($order_dq) {
+ if ($order_dq->{by}{type} eq DQ_IDENTIFIER) {
+ if (exists $colmap->{join '.', @{$order_dq->{by}{elements}}}) {
+ $order_dq = $order_dq->{from};
+ next ORDER_DQ;
+ }
+ }
+ $weirditude = 1;
+ last ORDER_DQ;
+ }
+
+ if ($weirditude) {
# nuke the prefetch before collapsing to sql
my $subq_rs = $rs->search;
$subq_rs->{attrs}{join} = $subq_rs->_merge_joinpref_attr( $subq_rs->{attrs}{join}, delete $subq_rs->{attrs}{prefetch} );
$limit = $self->__max_int;
}
-
- my ($sql, @bind);
- if ($limit) {
- # this is legacy code-flow from SQLA::Limit, it is not set in stone
-
- ($sql, @bind) = $self->next::method ($table, $fields, $where);
-
- my $limiter =
- $self->can ('emulate_limit') # also backcompat hook from SQLA::Limit
- ||
- do {
- my $dialect = $self->limit_dialect
- or $self->throw_exception( "Unable to generate SQL-limit - no limit dialect specified on $self, and no emulate_limit method found" );
- $self->can ("_$dialect")
- or $self->throw_exception(__PACKAGE__ . " does not implement the requested dialect '$dialect'");
- }
- ;
-
- $sql = $self->$limiter (
- $sql,
- { %{$rs_attrs||{}}, _selector_sql => $fields },
- $limit,
- $offset
- );
- }
- else {
- ($sql, @bind) = $self->next::method ($table, $fields, $where, $rs_attrs->{order_by}, $rs_attrs);
- }
-
- push @{$self->{where_bind}}, @bind;
-
-# this *must* be called, otherwise extra binds will remain in the sql-maker
- my @all_bind = $self->_assemble_binds;
+ my ($sql, @bind) = $self->next::method ($table, $fields, $where, $rs_attrs->{order_by}, { %{$rs_attrs}, limit => $limit, offset => $offset } );
$sql .= $self->_lock_select ($rs_attrs->{for})
if $rs_attrs->{for};
- return wantarray ? ($sql, @all_bind) : $sql;
+ return wantarray ? ($sql, @bind) : $sql;
}
sub _assemble_binds {
package DBIx::Class::SQLMaker::Converter;
-use Data::Query::Constants qw(DQ_ALIAS DQ_GROUP DQ_WHERE DQ_JOIN);
+use Data::Query::Constants qw(DQ_ALIAS DQ_GROUP DQ_WHERE DQ_JOIN DQ_SLICE);
use Moo;
extends 'SQL::Abstract::Converter';
+around _select_to_dq => sub {
+ my ($orig, $self) = (shift, shift);
+ my $attrs = $_[4];
+ my $orig_dq = $self->$orig(@_);
+ return $orig_dq unless $attrs->{limit};
+ +{
+ type => DQ_SLICE,
+ from => $orig_dq,
+ limit => $self->_value_to_dq($attrs->{limit}),
+ ($attrs->{offset}
+ ? (offset => $self->_value_to_dq($attrs->{offset}))
+ : ()
+ ),
+ };
+};
+
around _select_field_to_dq => sub {
my ($orig, $self) = (shift, shift);
my ($field) = @_;
use base qw( DBIx::Class::SQLMaker );
+sub renderer_class { 'Data::Query::Renderer::SQL::SQLite' }
+
#
# SQLite does not understand SELECT ... FOR UPDATE
# Disable it here
-sub _lock_select () { '' };
+sub _lock_select { '' };
1;
my $self = shift;
my ($from, $select, $where, $attrs) = @_;
- return $from unless $self->_use_join_optimizer;
+ # XXX disabled temporarily while I hunt bigger game -- mst
+ return $from; # unless $self->_use_join_optimizer;
if (ref $from ne 'ARRAY' || ref $from->[0] ne 'HASH' || ref $from->[1] ne 'ARRAY') {
return $from; # only standard {from} specs are supported