| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Class::ReluctantORM::SQL::Parser; |
|
2
|
1
|
|
|
1
|
|
5
|
use strict; |
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
30
|
|
|
3
|
1
|
|
|
1
|
|
6
|
use warnings; |
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
24
|
|
|
4
|
|
|
|
|
|
|
|
|
5
|
1
|
|
|
1
|
|
5
|
use base 'SQL::Parser'; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
1329
|
|
|
6
|
|
|
|
|
|
|
|
|
7
|
1
|
|
|
1
|
|
65368
|
use Scalar::Util qw(blessed); |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
71
|
|
|
8
|
|
|
|
|
|
|
|
|
9
|
1
|
|
|
1
|
|
7
|
use Class::ReluctantORM::Utilities qw(install_method); |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
47
|
|
|
10
|
|
|
|
|
|
|
|
|
11
|
1
|
|
|
1
|
|
7
|
use Class::ReluctantORM::SQL::Aliases; |
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
150
|
|
|
12
|
|
|
|
|
|
|
|
|
13
|
1
|
|
|
1
|
|
1028
|
use SQL::Statement::TermFactory; |
|
|
1
|
|
|
|
|
124998
|
|
|
|
1
|
|
|
|
|
1011
|
|
|
14
|
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
our $DEBUG ||= 0; |
|
16
|
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
sub new { |
|
18
|
1
|
|
|
1
|
1
|
4
|
my $class = shift; |
|
19
|
1
|
|
|
|
|
11
|
my $self = $class->SUPER::new(@_); |
|
20
|
|
|
|
|
|
|
|
|
21
|
1
|
|
|
|
|
6143
|
$self->{RaiseError} = 1; |
|
22
|
1
|
|
|
|
|
3
|
$self->{PrintError} = 0; |
|
23
|
1
|
|
|
|
|
11
|
$self->feature('reserved_words', 'TRUE', 0); |
|
24
|
1
|
|
|
|
|
15
|
$self->feature('reserved_words', 'FALSE', 0); |
|
25
|
1
|
|
|
|
|
11
|
$self->feature('valid_data_types', 'BOOLEAN', 1); |
|
26
|
|
|
|
|
|
|
|
|
27
|
1
|
|
|
|
|
11
|
return $self; |
|
28
|
|
|
|
|
|
|
} |
|
29
|
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
sub LITERAL { |
|
31
|
0
|
|
|
0
|
0
|
|
my ( $self, $str ) = @_; |
|
32
|
0
|
0
|
|
|
|
|
return 'BOOLEAN' if ($str =~ m/^(TRUE|FALSE)$/); |
|
33
|
0
|
|
|
|
|
|
return $self->SUPER::LITERAL($str); |
|
34
|
|
|
|
|
|
|
} |
|
35
|
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
#==========================================================# |
|
38
|
|
|
|
|
|
|
# parse_where Support |
|
39
|
|
|
|
|
|
|
#==========================================================# |
|
40
|
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
our %SS_LITERAL_TYPES = map { uc($_) => 1 } qw(string number null boolean); |
|
44
|
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
sub __build_crit_from_parse_tree { |
|
46
|
0
|
|
|
0
|
|
|
my $parser = shift; |
|
47
|
0
|
|
|
|
|
|
my $stmt = shift; |
|
48
|
0
|
|
|
|
|
|
my $cro_where = shift; |
|
49
|
0
|
|
|
|
|
|
$parser->{__where_under_construction} = $cro_where; |
|
50
|
0
|
|
|
|
|
|
my $ss_where = $stmt->{where_clause}; # ENCAPSULATION VIOLATION into SQL::Parser v1.15 |
|
51
|
0
|
0
|
|
|
|
|
if ($DEBUG > 2) { print STDERR __PACKAGE__ . ':' . __LINE__ . "Have SQL::Statement parse tree as:\n" . Dumper($ss_where); } |
|
|
0
|
|
|
|
|
|
|
|
52
|
0
|
|
|
|
|
|
return $parser->__bcfpt_recursor($ss_where); |
|
53
|
|
|
|
|
|
|
} |
|
54
|
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
sub __bcfpt_recursor { |
|
56
|
0
|
|
|
0
|
|
|
my $parser = shift; |
|
57
|
0
|
|
|
|
|
|
my $ss_node = shift; |
|
58
|
|
|
|
|
|
|
|
|
59
|
0
|
|
|
|
|
|
my $is_ref = ref($ss_node); |
|
60
|
0
|
|
0
|
|
|
|
my $is_hash = $is_ref && (ref($ss_node) eq 'HASH'); |
|
61
|
0
|
|
0
|
|
|
|
my $is_operation = ($is_hash && exists $ss_node->{op}); |
|
62
|
0
|
|
0
|
|
|
|
my $is_param = $is_hash && $ss_node->{type} && $ss_node->{type} eq 'placeholder'; |
|
63
|
0
|
|
0
|
|
|
|
my $is_column = $is_hash && $ss_node->{type} && $ss_node->{type} eq 'column'; |
|
64
|
0
|
|
0
|
|
|
|
my $is_function = $is_ref && blessed($ss_node) && $ss_node->isa('SQL::Statement::Util::Function'); |
|
65
|
0
|
|
0
|
|
|
|
my $is_literal = $is_hash && exists($SS_LITERAL_TYPES{uc($ss_node->{type} || '')}); |
|
66
|
0
|
|
0
|
|
|
|
my $is_null = $is_literal && $ss_node->{type} eq 'null'; |
|
67
|
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
# Handle negations as a proper operation |
|
69
|
0
|
0
|
0
|
|
|
|
if ($is_hash && $ss_node->{neg}) { |
|
70
|
0
|
|
|
|
|
|
return Criterion->new('NOT', $parser->__bcfpt_recursor({%$ss_node, neg => 0})); |
|
71
|
|
|
|
|
|
|
} |
|
72
|
|
|
|
|
|
|
|
|
73
|
0
|
0
|
|
|
|
|
if ($is_operation) { |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
74
|
0
|
|
|
|
|
|
my @args = map { $parser->__bcfpt_recursor($ss_node->{$_}) } grep { /^arg/ } sort keys %$ss_node; |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
75
|
0
|
|
|
|
|
|
return Criterion->new($ss_node->{op}, @args); |
|
76
|
|
|
|
|
|
|
} elsif ($is_function) { |
|
77
|
0
|
|
|
|
|
|
my @args = map { $parser->__bcfpt_recursor($_) } @{$ss_node->args}; |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
78
|
0
|
|
|
|
|
|
my $func_name = $ss_node->{name}; |
|
79
|
0
|
|
|
|
|
|
Class::ReluctantORM::Exception::NotImplemented->throw('SQL functions not yet supported'); |
|
80
|
|
|
|
|
|
|
} elsif ($is_param) { |
|
81
|
0
|
|
|
|
|
|
return Param->new(); |
|
82
|
|
|
|
|
|
|
} elsif ($is_column) { |
|
83
|
0
|
|
|
|
|
|
return $parser->__bcfpt_boost_to_column($ss_node); |
|
84
|
|
|
|
|
|
|
} elsif ($is_literal) { |
|
85
|
0
|
0
|
|
|
|
|
return Literal->new(($is_null ? undef : $ss_node->{value}), uc($ss_node->{type})); |
|
86
|
|
|
|
|
|
|
} else { |
|
87
|
0
|
|
|
|
|
|
Class::ReluctantORM::Exception::Param::BadValue->croak(error => __PACKAGE__ . '::__boost cannot handle this arg: ' . ref($ss_node)); |
|
88
|
|
|
|
|
|
|
} |
|
89
|
|
|
|
|
|
|
} |
|
90
|
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
sub __bcfpt_boost_to_column { |
|
92
|
0
|
|
|
0
|
|
|
my $parser = shift; |
|
93
|
0
|
|
|
|
|
|
my $ss_node = shift; |
|
94
|
|
|
|
|
|
|
|
|
95
|
0
|
|
|
|
|
|
my ($table_name, $col_name) = split /\./, $ss_node->{value}; # DRIVER DEPENDENCY - table/column name separator |
|
96
|
0
|
0
|
|
|
|
|
if (!$col_name) { ($col_name, $table_name) = ($table_name, $col_name); } |
|
|
0
|
|
|
|
|
|
|
|
97
|
0
|
|
|
|
|
|
my ($col, $table); |
|
98
|
0
|
0
|
|
|
|
|
if ($table_name) { |
|
99
|
0
|
|
|
|
|
|
$table = $parser->{__where_under_construction}->find_table($table_name); |
|
100
|
0
|
0
|
|
|
|
|
unless ($table) { |
|
101
|
|
|
|
|
|
|
# Must not be a previously referenced table |
|
102
|
0
|
|
|
|
|
|
$table = Table->new(table => $table_name); |
|
103
|
|
|
|
|
|
|
} |
|
104
|
|
|
|
|
|
|
} |
|
105
|
0
|
|
|
|
|
|
$col = Column->new( |
|
106
|
|
|
|
|
|
|
table => $table, |
|
107
|
|
|
|
|
|
|
column => lc(__trim_quotes($col_name)), |
|
108
|
|
|
|
|
|
|
); |
|
109
|
0
|
|
|
|
|
|
return $col; |
|
110
|
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
} |
|
112
|
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
sub __trim_quotes { |
|
114
|
0
|
|
|
0
|
|
|
my $t = shift; |
|
115
|
0
|
|
|
|
|
|
$t =~ tr/'"[]//d; |
|
116
|
0
|
|
|
|
|
|
return $t; |
|
117
|
|
|
|
|
|
|
} |
|
118
|
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
1; |