| ... | ... | 
                  @@ -407,9 +407,13 @@ sub execute {
                 | 
              
| 407 | 407 | 
                  my ($self, $query, %args) = @_;  | 
              
| 408 | 408 | 
                   | 
              
| 409 | 409 | 
                  # Arguments  | 
              
| 410 | 
                  -    my $params = delete $args{param} || {};
                 | 
              |
| 410 | 
                  +    my $param  = delete $args{param} || {};
                 | 
              |
| 411 | 411 | 
                       my $tables = delete $args{table} || [];
                 | 
              
| 412 | 412 | 
                  $tables = [$tables] unless ref $tables eq 'ARRAY';  | 
              
| 413 | 
                  +    my $filter = delete $args{filter};
                 | 
              |
| 414 | 
                  + $filter = DBIx::Custom::Util::array_to_hash($filter);  | 
              |
| 415 | 
                  +    my $type = delete $args{type};
                 | 
              |
| 416 | 
                  + $type = DBIx::Custom::Util::array_to_hash($type);  | 
              |
| 413 | 417 | 
                   | 
              
| 414 | 418 | 
                  # Check argument names  | 
              
| 415 | 419 | 
                       foreach my $name (keys %args) {
                 | 
              
| ... | ... | 
                  @@ -419,10 +423,10 @@ sub execute {
                 | 
              
| 419 | 423 | 
                   | 
              
| 420 | 424 | 
                  # Create query  | 
              
| 421 | 425 | 
                  $query = $self->create_query($query) unless ref $query;  | 
              
| 426 | 
                  + $filter ||= $query->filter;  | 
              |
| 422 | 427 | 
                   | 
              
| 423 | 428 | 
                  # Tables  | 
              
| 424 | 429 | 
                       unshift @$tables, @{$query->tables};
                 | 
              
| 425 | 
                  -    my %table_set = map {defined $_ ? ($_ => 1) : ()} @$tables;
                 | 
              |
| 426 | 430 | 
                  my $main_table = pop @$tables;  | 
              
| 427 | 431 | 
                  $tables = $self->_remove_duplicate_table($tables, $main_table);  | 
              
| 428 | 432 | 
                       if (my $q = $self->reserved_word_quote) {
                 | 
              
| ... | ... | 
                  @@ -449,78 +453,69 @@ sub execute {
                 | 
              
| 449 | 453 | 
                  my $filter_name_alias = $filter_name;  | 
              
| 450 | 454 | 
                  $filter_name_alias =~ s/^$alias\./$table\./;  | 
              
| 451 | 455 | 
                                   $filter_name_alias =~ s/^${alias}__/${table}__/; 
                 | 
              
| 452 | 
                  -  | 
              |
| 453 | 456 | 
                                   $self->{filter}{$type}{$table}{$filter_name_alias}
                 | 
              
| 454 | 457 | 
                                     = $self->{filter}{$type}{$alias}{$filter_name}
                 | 
              
| 455 | 458 | 
                  }  | 
              
| 456 | 459 | 
                  }  | 
              
| 457 | 460 | 
                  }  | 
              
| 458 | 
                  -  | 
              |
| 459 | 
                  - # Filters  | 
              |
| 460 | 
                  -    my $filter = {};
                 | 
              |
| 461 | 
                  +  | 
              |
| 462 | 
                  + # Applied filter  | 
              |
| 463 | 
                  +    my $applied_filter = {};
                 | 
              |
| 461 | 464 | 
                       foreach my $table (@$tables) {
                 | 
              
| 462 | 
                  - next unless $table;  | 
              |
| 463 | 
                  -        $filter = {
                 | 
              |
| 464 | 
                  - %$filter,  | 
              |
| 465 | 
                  +        $applied_filter = {
                 | 
              |
| 466 | 
                  + %$applied_filter,  | 
              |
| 465 | 467 | 
                               %{$self->{filter}{out}->{$table} || {}}
                 | 
              
| 466 | 468 | 
                  }  | 
              
| 467 | 469 | 
                  }  | 
              
| 470 | 
                  +    $filter = {%$applied_filter, %$filter};
                 | 
              |
| 468 | 471 | 
                   | 
              
| 469 | 
                  - # Filter argument  | 
              |
| 470 | 
                  -    my $f = DBIx::Custom::Util::array_to_hash($args{filter})
                 | 
              |
| 471 | 
                  -         || $query->filter || {};
                 | 
              |
| 472 | 
                  -    foreach my $column (keys %$f) {
                 | 
              |
| 473 | 
                  -        my $fname = $f->{$column};
                 | 
              |
| 474 | 
                  -        if (!defined $fname) {
                 | 
              |
| 475 | 
                  -            $f->{$column} = undef;
                 | 
              |
| 472 | 
                  + # Replace filter name to code  | 
              |
| 473 | 
                  +    foreach my $column (keys %$filter) {
                 | 
              |
| 474 | 
                  +        my $name = $filter->{$column};
                 | 
              |
| 475 | 
                  +        if (!defined $name) {
                 | 
              |
| 476 | 
                  +            $filter->{$column} = undef;
                 | 
              |
| 476 | 477 | 
                  }  | 
              
| 477 | 
                  -        elsif (ref $fname ne 'CODE') {
                 | 
              |
| 478 | 
                  -          croak qq{Filter "$fname" is not registered"}
                 | 
              |
| 479 | 
                  -            unless exists $self->filters->{$fname};
                 | 
              |
| 480 | 
                  -  | 
              |
| 481 | 
                  -          $f->{$column} = $self->filters->{$fname};
                 | 
              |
| 478 | 
                  +        elsif (ref $name ne 'CODE') {
                 | 
              |
| 479 | 
                  +          croak qq{Filter "$name" is not registered"}
                 | 
              |
| 480 | 
                  +            unless exists $self->filters->{$name};
                 | 
              |
| 481 | 
                  +          $filter->{$column} = $self->filters->{$name};
                 | 
              |
| 482 | 482 | 
                  }  | 
              
| 483 | 483 | 
                  }  | 
              
| 484 | 
                  -    $filter = {%$filter, %$f};
                 | 
              |
| 485 | 484 | 
                   | 
              
| 486 | 
                  - # Type  | 
              |
| 487 | 
                  -    my $type = DBIx::Custom::Util::array_to_hash($args{type});
                 | 
              |
| 488 | 
                  -  | 
              |
| 489 | 
                  - # Bind  | 
              |
| 490 | 
                  - my $bind = $self->_bind($params, $query->columns, $filter, $type);  | 
              |
| 485 | 
                  + # Create bind values  | 
              |
| 486 | 
                  + my $bind = $self->_create_bind_values(  | 
              |
| 487 | 
                  + $param,  | 
              |
| 488 | 
                  + $query->columns,  | 
              |
| 489 | 
                  + $filter,  | 
              |
| 490 | 
                  + $type  | 
              |
| 491 | 
                  + );  | 
              |
| 491 | 492 | 
                   | 
              
| 492 | 493 | 
                  # Execute  | 
              
| 493 | 494 | 
                  my $sth = $query->sth;  | 
              
| 494 | 495 | 
                  my $affected;  | 
              
| 495 | 496 | 
                       eval {
                 | 
              
| 496 | 497 | 
                           for (my $i = 0; $i < @$bind; $i++) {
                 | 
              
| 497 | 
                  -            if (my $type = $bind->[$i]->{type}) {
                 | 
              |
| 498 | 
                  -                $sth->bind_param($i + 1, $bind->[$i]->{value}, $type);
                 | 
              |
| 499 | 
                  - }  | 
              |
| 500 | 
                  -            else {
                 | 
              |
| 501 | 
                  -                $sth->bind_param($i + 1, $bind->[$i]->{value});
                 | 
              |
| 502 | 
                  - }  | 
              |
| 498 | 
                  +            my $type = $bind->[$i]->{type};
                 | 
              |
| 499 | 
                  +            $sth->bind_param($i + 1, $bind->[$i]->{value}, $type ? $type : ());
                 | 
              |
| 503 | 500 | 
                  }  | 
              
| 504 | 501 | 
                  $affected = $sth->execute;  | 
              
| 505 | 502 | 
                  };  | 
              
| 506 | 503 | 
                       $self->_croak($@, qq{. Following SQL is executed. "$query->{sql}"}) if $@;
                 | 
              
| 507 | 504 | 
                   | 
              
| 508 | 
                  - # Return resultset if select statement is executed  | 
              |
| 505 | 
                  + # Select statement  | 
              |
| 509 | 506 | 
                       if ($sth->{NUM_OF_FIELDS}) {
                 | 
              
| 510 | 507 | 
                   | 
              
| 511 | 
                  - # Result in and end filter  | 
              |
| 512 | 
                  -        my $in_filter  = {};
                 | 
              |
| 513 | 
                  -        my $end_filter = {};
                 | 
              |
| 508 | 
                  + # Filter  | 
              |
| 509 | 
                  +        my $filter = {};
                 | 
              |
| 510 | 
                  +        $filter->{in}  = {};
                 | 
              |
| 511 | 
                  +        $filter->{end} = {};
                 | 
              |
| 514 | 512 | 
                           foreach my $table (@$tables) {
                 | 
              
| 515 | 
                  - next unless $table;  | 
              |
| 516 | 
                  -            $in_filter = {
                 | 
              |
| 517 | 
                  - %$in_filter,  | 
              |
| 518 | 
                  -                %{$self->{filter}{in}{$table} || {}}
                 | 
              |
| 519 | 
                  - };  | 
              |
| 520 | 
                  -            $end_filter = {
                 | 
              |
| 521 | 
                  - %$end_filter,  | 
              |
| 522 | 
                  -                %{$self->{filter}{end}{$table} || {}}
                 | 
              |
| 523 | 
                  - };  | 
              |
| 513 | 
                  +            foreach my $way (qw/in end/) {
                 | 
              |
| 514 | 
                  +                $filter->{$way} = {
                 | 
              |
| 515 | 
                  +                    %{$filter->{$way}},
                 | 
              |
| 516 | 
                  +                    %{$self->{filter}{$way}{$table} || {}}
                 | 
              |
| 517 | 
                  + };  | 
              |
| 518 | 
                  + }  | 
              |
| 524 | 519 | 
                  }  | 
              
| 525 | 520 | 
                   | 
              
| 526 | 521 | 
                  # Result  | 
              
| ... | ... | 
                  @@ -529,13 +524,15 @@ sub execute {
                 | 
              
| 529 | 524 | 
                  filters => $self->filters,  | 
              
| 530 | 525 | 
                  filter_check => $self->filter_check,  | 
              
| 531 | 526 | 
                               default_filter => $self->{default_in_filter},
                 | 
              
| 532 | 
                  -            filter         => $in_filter || {},
                 | 
              |
| 533 | 
                  -            end_filter     => $end_filter || {}
                 | 
              |
| 527 | 
                  +            filter         => $filter->{in} || {},
                 | 
              |
| 528 | 
                  +            end_filter     => $filter->{end} || {}
                 | 
              |
| 534 | 529 | 
                  );  | 
              
| 535 | 530 | 
                   | 
              
| 536 | 531 | 
                  return $result;  | 
              
| 537 | 532 | 
                  }  | 
              
| 538 | 
                  - return $affected;  | 
              |
| 533 | 
                  +  | 
              |
| 534 | 
                  + # Not select statement  | 
              |
| 535 | 
                  +    else { return $affected }
                 | 
              |
| 539 | 536 | 
                  }  | 
              
| 540 | 537 | 
                   | 
              
| 541 | 538 | 
                   our %INSERT_ARGS = map { $_ => 1 } @COMMON_ARGS, qw/param append/;
                 | 
              
| ... | ... | 
                  @@ -1181,7 +1178,7 @@ sub where {
                 | 
              
| 1181 | 1178 | 
                  );  | 
              
| 1182 | 1179 | 
                  }  | 
              
| 1183 | 1180 | 
                   | 
              
| 1184 | 
                  -sub _bind {
                 | 
              |
| 1181 | 
                  +sub _create_bind_values {
                 | 
              |
| 1185 | 1182 | 
                  my ($self, $params, $columns, $filter, $type) = @_;  | 
              
| 1186 | 1183 | 
                   | 
              
| 1187 | 1184 | 
                  # bind values  |