sub _RowNumberOver {
my ($self, $sql, $order, $rows, $offset ) = @_;
+ # get the select to make the final amount of columns equal the original one
+ my ($select) = $sql =~ /^ \s* SELECT \s+ (.+?) \s+ FROM/ix
+ or croak "Unrecognizable SELECT: $sql";
+
# get the order_by only (or make up an order if none exists)
my $order_by = $self->_order_by(
(delete $order->{order_by}) || $self->_rno_default_order
);
- # whatever is left
+ # whatever is left of the order_by
my $group_having = $self->_order_by($order);
- $sql = sprintf (<<'EOS', $order_by, $sql, $group_having, $offset + 1, $offset + $rows, );
+ my $qalias = $self->_quote ($self->{_dbic_rs_attrs}{alias});
-SELECT * FROM (
- SELECT orig_query.*, ROW_NUMBER() OVER(%s ) AS rno__row__index FROM (%s%s) orig_query
-) rno_subq WHERE rno__row__index BETWEEN %d AND %d
+ $sql = sprintf (<<EOS, $offset + 1, $offset + $rows, );
+
+SELECT $select FROM (
+ SELECT $qalias.*, ROW_NUMBER() OVER($order_by ) AS rno__row__index FROM (
+ ${sql}${group_having}
+ ) $qalias
+) $qalias WHERE rno__row__index BETWEEN %d AND %d
EOS
return undef;
}
+# Informix specific limit, almost like LIMIT/OFFSET
+sub _SkipFirst {
+ my ($self, $sql, $order, $rows, $offset) = @_;
+
+ $sql =~ s/^ \s* SELECT \s+ //ix
+ or croak "Unrecognizable SELECT: $sql";
+
+ return sprintf ('SELECT %s%s%s%s',
+ $offset
+ ? sprintf ('SKIP %d ', $offset)
+ : ''
+ ,
+ sprintf ('FIRST %d ', $rows),
+ $sql,
+ $self->_order_by ($order),
+ );
+}
+
+# Firebird specific limit, reverse of _SkipFirst for Informix
+sub _FirstSkip {
+ my ($self, $sql, $order, $rows, $offset) = @_;
+
+ $sql =~ s/^ \s* SELECT \s+ //ix
+ or croak "Unrecognizable SELECT: $sql";
+
+ return sprintf ('SELECT %s%s%s%s',
+ sprintf ('FIRST %d ', $rows),
+ $offset
+ ? sprintf ('SKIP %d ', $offset)
+ : ''
+ ,
+ $sql,
+ $self->_order_by ($order),
+ );
+}
+
# Crappy Top based Limit/Offset support. Legacy from MSSQL.
sub _Top {
my ( $self, $sql, $order, $rows, $offset ) = @_;
# which is sadly understood only by MySQL. Change default behavior here,
# until SQLA2 comes with proper dialect support
if (! $_[0] or (ref $_[0] eq 'HASH' and !keys %{$_[0]} ) ) {
- return "INSERT INTO ${table} DEFAULT VALUES"
+ my $sql = "INSERT INTO ${table} DEFAULT VALUES";
+
+ if (my $ret = ($_[1]||{})->{returning} ) {
+ $sql .= $self->_insert_returning ($ret);
+ }
+
+ return $sql;
}
$self->SUPER::insert($table, @_);
$self->_sqlcase($func),
$self->_recurse_fields($args),
$as
- ? sprintf (' %s %s', $self->_sqlcase('as'), $as)
+ ? sprintf (' %s %s', $self->_sqlcase('as'), $self->_quote ($as) )
: ''
);
}
}
+sub _generate_join_clause {
+ my ($self, $join_type) = @_;
+
+ return sprintf ('%s JOIN ',
+ $join_type ? ' ' . uc($join_type) : ''
+ );
+}
+
sub _recurse_from {
my ($self, $from, @join) = @_;
my @sqlf;
$join_type = $self->{_default_jointype} if not defined $join_type;
- my $join_clause = sprintf ('%s JOIN ',
- $join_type ? ' ' . uc($join_type) : ''
- );
- push @sqlf, $join_clause;
+ push @sqlf, $self->_generate_join_clause( $join_type );
if (ref $to eq 'ARRAY') {
push(@sqlf, '(', $self->_recurse_from(@$to), ')');