Skip to content

Commit

Permalink
support use index caluse
Browse files Browse the repository at this point in the history
  • Loading branch information
xaicron committed Apr 22, 2012
1 parent 91c8598 commit 4bdd318
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 6 deletions.
49 changes: 43 additions & 6 deletions lib/SQL/Format.pm
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ my $SORT_OP_ALIAS = {
-DESC => 'DESC',
};

my $SUPPORTED_INDEX_TYPE_MAP = {
USE => 1,
FORCE => 1,
IGNORE => 1,
};

use constant {
_LIMIT_OFFSET => 1,
_LIMIT_XY => 2,
Expand Down Expand Up @@ -125,9 +131,7 @@ sub table {
my $v = $_;
my $ret;
if (ref $v eq 'HASH') {
$ret = join $DELIMITER, map {
_quote($_).' AS '._quote($v->{$_})
} sort keys %$v;
$ret = _complex_table_expr($v);
}
else {
$ret = _quote($v);
Expand All @@ -136,9 +140,7 @@ sub table {
} @$val;
}
elsif (ref $val eq 'HASH') {
$ret = join $DELIMITER, map {
_quote($_).' AS '._quote($val->{$_})
} sort keys %$val;
$ret = _complex_table_expr($val);
}
elsif (defined $val) {
$ret = _quote($val);
Expand Down Expand Up @@ -416,6 +418,35 @@ sub _quote {
} split /\Q$NAME_SEP\E/, $stuff;
}

sub _complex_table_expr {
my $stuff = shift;
my $ret = join $DELIMITER, map {
my ($k, $v) = ($_, $stuff->{$_});
my $ret = _quote($k);
if (ref $v eq 'HASH') {
$ret .= ' AS '._quote($v->{alias}) if $v->{alias};
if (exists $v->{index} && ref $v->{index}) {
my $type = uc($v->{index}{type} || 'USE');
croak "unkown index type: $type"
unless $SUPPORTED_INDEX_TYPE_MAP->{$type};
croak "keys field must be specified in index option"
unless defined $v->{index}{keys};
my $keys = $v->{index}{keys};
$keys = [ $keys ] unless ref $keys eq 'ARRAY';
$ret .= " $type INDEX (".join($DELIMITER,
map { _quote($_) } @$keys
).")";
}
}
else {
$ret .= ' AS '._quote($v);
}
$ret;
} sort keys %$stuff;

return $ret;
}

sub _sort_expr {
my $stuff = shift;
my $ret = '';
Expand Down Expand Up @@ -741,6 +772,12 @@ This format is a table name.
($stmt, @bind) = sqlf '%t', 'table_name'; # $stmt => `table_name`
($stmt, @bind) = sqlf '%t', [qw/tableA tableB/]; # $stmt => `tableA`, `tableB`
($stmt, @bind) = sqlf '%t', { tableA => 't1' }; # $stmt => `tableA` AS `t1`
($stmt, @bind) = sqlf '%t', {
tableA => {
index => { type => 'force', keys => [qw/key1 key2/] },
alias => 't1',
}; # $stmt: `tableA` AS `t1` FORCE INDEX (`key1`, `key2`)
=item %c
Expand Down
24 changes: 24 additions & 0 deletions lib/SQL/Format/Spec.pod
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,30 @@ For example:
SELECT foo FROM `t1`, `t2` AS `foo`, `t3` AS `bar`, `t4` AS `baz`
[]

# add index hint
SELECT foo FROM %t
{ table => { index => { type => 'force', keys => [qw/key1 key2/] } } }
SELECT foo FROM `table` FORCE INDEX (`key1`, `key2`)
[]

# add index hint (default type is USE INDEX)
SELECT foo FROM %t
{ table => { index => { keys => [qw/key1 key2/] } } }
SELECT foo FROM `table` USE INDEX (`key1`, `key2`)
[]

# add index hint (keys is scalar)
SELECT foo FROM %t
{ table => { index => { keys => 'key1' } } }
SELECT foo FROM `table` USE INDEX (`key1`)
[]

# add index hint with alias
SELECT foo FROM %t
{ table => { alias => 't1', index => { type => 'force', keys => [qw/key1 key2/] } } }
SELECT foo FROM `table` AS `t1` FORCE INDEX (`key1`, `key2`)
[]

=head2 where array in

# array
Expand Down

0 comments on commit 4bdd318

Please sign in to comment.