my $inner_order = ($order_by_requested
? $requested_order
: [ map
- { join ('', $rs_attrs->{alias}, $self->{name_sep}||'.', $_ ) }
+ { "$rs_attrs->{alias}.$_" }
( $rs_attrs->{_rsroot_source_handle}->resolve->_pri_cols )
]
);
croak 'Limit dialect implementation usable only in the context of DBIC (missing $rs_attrs)'
unless ref ($rs_attrs) eq 'HASH';
- my ($re_sep, $re_alias) = map { quotemeta $_ } (
- $self->name_sep || '.',
- $rs_attrs->{alias},
- );
+ my ($re_sep, $re_alias) = map { quotemeta $_ } ( $self->{name_sep}, $rs_attrs->{alias} );
# correlate select and as, build selection index
my (@sel, $in_sel_index);
# for possible further chaining)
my (@in_sel, @out_sel, %renamed);
for my $node (@sel) {
- if (first { $_ =~ / (?<! ^ $re_alias ) $re_sep /x } ($node->{as}, $node->{unquoted_sql}) ) {
+ if (
+ $node->{as} =~ / (?<! ^ $re_alias ) \. /x
+ or
+ $node->{unquoted_sql} =~ / (?<! ^ $re_alias ) $re_sep /x
+ ) {
$node->{as} = $self->_unqualify_colname($node->{as});
my $quoted_as = $self->_quote($node->{as});
push @in_sel, sprintf '%s AS %s', $node->{sql}, $quoted_as;
sub _unqualify_colname {
my ($self, $fqcn) = @_;
- my $re_sep = quotemeta($self->name_sep || '.');
- $fqcn =~ s/ $re_sep /__/xg;
+ $fqcn =~ s/ \. /__/xg;
return $fqcn;
}
=item quote_char
-Specifies what characters to use to quote table and column names. If
-you use this you will want to specify L</name_sep> as well.
+Specifies what characters to use to quote table and column names.
C<quote_char> expects either a single character, in which case is it
is placed on either side of the table/column name, or an arrayref of length
=item name_sep
-This only needs to be used in conjunction with C<quote_char>, and is used to
+This parameter is only useful in conjunction with C<quote_char>, and is used to
specify the character that separates elements (schemas, tables, columns) from
-each other. In most cases this is simply a C<.>.
-
-The consequences of not supplying this value is that L<SQL::Abstract>
-will assume DBIx::Class' uses of aliases to be complete column
-names. The output will look like I<"me.name"> when it should actually
-be I<"me"."name">.
+each other. If unspecified it defaults to the most commonly used C<.>.
=item unsafe
'postgres',
'my_pg_password',
{ AutoCommit => 1 },
- { quote_char => q{"}, name_sep => q{.} },
+ { quote_char => q{"} },
]
);
bindtype=>'columns',
array_datatypes => 1,
limit_dialect => $dialect,
+ name_sep => '.',
%opts,
));
}
# set up a botched SQLA
my $sql_maker = $self->sql_maker;
- my $sep = quotemeta ($self->_sql_maker_opts->{name_sep} || '.');
- my ($orig_lquote, $orig_rquote) = map { quotemeta $_ } (do {
- if (ref $sql_maker->{quote_char} eq 'ARRAY') {
- @{$sql_maker->{quote_char}}
- }
- else {
- ($sql_maker->{quote_char} || '') x 2;
- }
- });
+ local $sql_maker->{having_bind}; # these are throw away results
+
+ # we can't scan properly without any quoting (\b doesn't cut it
+ # everywhere), so unless there is proper quoting set - use our
+ # own weird impossible character.
+ # Also in the case of no quoting, we need to explicitly disable
+ # name_sep, otherwise sorry nasty legacy syntax like
+ # { 'count(foo.id)' => { '>' => 3 } } will stop working >:(
+ local $sql_maker->{quote_char} = $sql_maker->{quote_char};
+ local $sql_maker->{name_sep} = $sql_maker->{name_sep};
+
+ unless (defined $sql_maker->{quote_char} and length $sql_maker->{quote_char}) {
+ $sql_maker->{quote_char} = "\x00";
+ $sql_maker->{name_sep} = '';
+ }
+
+ my ($lquote, $rquote, $sep) = map { quotemeta $_ } ($sql_maker->_quote_chars, $sql_maker->name_sep);
- local $sql_maker->{quote_char} = "\x00"; # so that we can regex away
# generate sql chunks
- local $sql_maker->{having_bind}; # these are throw away results
my $to_scan = {
restricting => [
$sql_maker->_recurse_where ($where),
# alias (should work even if they are in scalarrefs)
for my $alias (keys %$alias_list) {
my $al_re = qr/
- \x00 $alias \x00 $sep
+ $lquote $alias $rquote $sep
|
- \b $alias $sep
+ \b $alias \.
/x;
- # add matching for possible quoted literal sql
- $al_re = qr/ $al_re | $orig_lquote $alias $orig_rquote /x
- if ($orig_lquote && $orig_rquote);
-
-
for my $type (keys %$to_scan) {
for my $piece (@{$to_scan->{$type}}) {
$aliases_by_type->{$type}{$alias} = 1 if ($piece =~ $al_re);
# now loop through unqualified column names, and try to locate them within
# the chunks
for my $col (keys %$colinfo) {
- next if $col =~ $sep; # if column is qualified it was caught by the above
-
- my $col_re = qr/ \x00 $col \x00 /x;
+ next if $col =~ / \. /x; # if column is qualified it was caught by the above
- $col_re = qr/ $col_re | $orig_lquote $col $orig_rquote /x
- if ($orig_lquote && $orig_rquote);
+ my $col_re = qr/ $lquote $col $rquote /x;
for my $type (keys %$to_scan) {
for my $piece (@{$to_scan->{$type}}) {
my ($self, $ident, $colnames) = @_;
my ($alias2src, $root_alias) = $self->_resolve_ident_sources($ident);
- my $sep = $self->_sql_maker_opts->{name_sep} || '.';
- my $qsep = quotemeta $sep;
-
my (%return, %seen_cols, @auto_colnames);
# compile a global list of column names, to be able to properly
my $rsrc = $alias2src->{$alias};
for my $colname ($rsrc->columns) {
push @{$seen_cols{$colname}}, $alias;
- push @auto_colnames, "$alias$sep$colname" unless $colnames;
+ push @auto_colnames, "$alias.$colname" unless $colnames;
}
}
COLUMN:
foreach my $col (@$colnames) {
- my ($alias, $colname) = $col =~ m/^ (?: ([^$qsep]+) $qsep)? (.+) $/x;
+ my ($alias, $colname) = $col =~ m/^ (?: ([^\.]+) \. )? (.+) $/x;
unless ($alias) {
# see if the column was seen exactly once (so we know which rsrc it came from)