|  line  | 
 stmt  | 
 bran  | 
 cond  | 
 sub  | 
 pod  | 
 time  | 
 code  | 
| 
1
 | 
  
 
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 package Neo4j::Cypher::Abstract::Peeler;  | 
| 
2
 | 
6
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
199246
 | 
 use Carp;  | 
| 
 
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
40
 | 
    | 
| 
 
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
481
 | 
    | 
| 
3
 | 
6
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
41
 | 
 use List::Util 1.33 qw(any);  | 
| 
 
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
139
 | 
    | 
| 
 
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
483
 | 
    | 
| 
4
 | 
6
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
36
 | 
 use Scalar::Util qw(looks_like_number blessed);  | 
| 
 
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
    | 
| 
 
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
314
 | 
    | 
| 
5
 | 
6
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
33
 | 
 use strict;  | 
| 
 
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
    | 
| 
 
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
201
 | 
    | 
| 
6
 | 
6
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
30
 | 
 use warnings;  | 
| 
 
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
    | 
| 
 
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1164
 | 
    | 
| 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # quoting logic:  | 
| 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # if config:bind = true  | 
| 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # if anon_placeholder (like ?) is in config, then return literals without  | 
| 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # quoting in array $obj->bind_values, and the placeholder in the statement  | 
| 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # if anon_placeholder is undef, then return literals quoted directly in the  | 
| 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # statement; return named parameters in $obj->parameters  | 
| 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #   | 
| 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # if config:bind false  | 
| 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # leave tokens and identifiers as-is, no bind_values or parameters  | 
| 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 our $VERSION = '0.1002';  | 
| 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my $SQL_ABSTRACT = 1;  | 
| 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub puke(@);  | 
| 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub belch(@);  | 
| 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my %config = (  | 
| 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   bind => 1,  | 
| 
26
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   anon_placeholder => undef, # '?',  | 
| 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   hash_op => '-and',  | 
| 
28
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   array_op => '-or',  | 
| 
29
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   list_braces => '[]',  | 
| 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   ineq_op => '<>',  | 
| 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   implicit_eq_op => '=',  | 
| 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   quote_lit => "'",  | 
| 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   esc_quote_lit => "\\",  | 
| 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   parameter_sigil => qw/^([:$?])|({[^}]+}$)/,  | 
| 
35
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   quote_fld => undef,  | 
| 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   safe_identifier => qw/[a-zA-Z_.]+/  | 
| 
37
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 );  | 
| 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
39
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # for each operator type (key in %type_table), there  | 
| 
40
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # should be a handler with the same name  | 
| 
41
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my %type_table = (  | 
| 
43
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   infix_binary => [qw{ - / %  =~ = <> < > <= >=  | 
| 
44
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		       -contains -starts_with -ends_with}],  | 
| 
45
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   infix_listarg => [qw{ -in } ],  | 
| 
46
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   infix_distributable => [qw{ + * -and -or }],  | 
| 
47
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   prefix => [qw{ -not }],  | 
| 
48
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   postfix => [qw{ -is_null -is_not_null }],  | 
| 
49
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   function => [qw{  | 
| 
50
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		   ()  | 
| 
51
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		   -abs -ceil -floor -rand -round -sign -degrees  | 
| 
52
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		   -e -exp -log -log10 -sqrt -acos -asin -atan -atan2  | 
| 
53
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		   -cos -cot -haversin -pi -radians -sin -tan  | 
| 
54
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		   -exists -toInt  | 
| 
55
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		   -left -lower -ltrim -replace -reverse -right  | 
| 
56
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		   -rtrim -split -substring -toString -trim -upper  | 
| 
57
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		   -length -size -type -id -coalesce -head -last  | 
| 
58
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		   -labels -nodes -relationships -keys -tail -range  | 
| 
59
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		   -collect -count -max -min -percentileCont  | 
| 
60
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		   -percentileDisc -stDev -stDevP -sum  | 
| 
61
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		   -shortestPath -allShortestPaths  | 
| 
62
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	       }],  | 
| 
63
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   predicate => [qw{ -all -any -none -single -filter}],  | 
| 
64
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   extract => [qw{ -extract }],  | 
| 
65
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   reduce => [qw{ -reduce }],  | 
| 
66
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   list => [qw( -list )], # returns args in list format  | 
| 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   bind => [qw( -bind )], # handles parameters and literal quoting  | 
| 
68
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   thing => [qw( -thing )], # the literal thing itself  | 
| 
69
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  );  | 
| 
70
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
71
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my %dispatch;  | 
| 
72
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 foreach my $type (keys %type_table) {  | 
| 
73
 | 
6
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
39
 | 
   no strict 'refs';  | 
| 
 
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
    | 
| 
 
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20794
 | 
    | 
| 
74
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   my @ops = @{$type_table{$type}};  | 
| 
75
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   @dispatch{@ops} = ( *${type}{CODE} ) x @ops;  | 
| 
76
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
77
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub new {  | 
| 
79
 | 
36
 | 
 
 | 
 
 | 
  
36
  
 | 
  
0
  
 | 
2924
 | 
   my $class = shift;  | 
| 
80
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
59
 | 
   my %args = @_;  | 
| 
81
 | 
36
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
97
 | 
   if ($args{dispatch} and !(ref $args{dispatch} eq 'HASH')) {  | 
| 
82
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     puke "dispatch must be hashref mapping operators to coderefs (or absent)"  | 
| 
83
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
84
 | 
36
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
80
 | 
   if ($args{config} and !(ref $args{config} eq 'HASH')) {  | 
| 
85
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     puke "config must be hashref defining peeler options"  | 
| 
86
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
87
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   my $self = {  | 
| 
88
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     dispatch => $args{dispatch} || \%dispatch,  | 
| 
89
 | 
36
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
197
 | 
     config => $args{config} || \%config  | 
| 
 
 | 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
90
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    };  | 
| 
91
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # update config elts according to constructor args  | 
| 
92
 | 
36
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
111
 | 
   if (length scalar keys %args) {  | 
| 
93
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
151
 | 
     for (keys %config) {  | 
| 
94
 | 
432
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
645
 | 
       defined $args{$_} and $self->{config}{$_} = $args{$_};  | 
| 
95
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
96
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
97
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
127
 | 
   bless $self, $class;  | 
| 
98
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
99
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub belch (@) {  | 
| 
101
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
0
 | 
   my($func) = (caller(1))[3];  | 
| 
102
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   Carp::carp "[$func] Warning: ", @_;  | 
| 
103
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
104
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
105
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub puke (@) {  | 
| 
106
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
0
 | 
   my($func) = (caller(1))[3];  | 
| 
107
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   Carp::croak "[$func] Fatal: ", @_;  | 
| 
108
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
109
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
110
 | 
32
 | 
  
100
  
 | 
 
 | 
  
32
  
 | 
  
1
  
 | 
102
 | 
 sub bind_values { $_[0]->{bind_values} ? @{$_[0]->{bind_values}} : return ; }  | 
| 
 
 | 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
58
 | 
    | 
| 
111
 | 
32
 | 
  
 50
  
 | 
 
 | 
  
32
  
 | 
  
1
  
 | 
90
 | 
 sub parameters { $_[0]->{parameters} ? @{$_[0]->{parameters}} : return ; }  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
112
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
113
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _dispatch {  | 
| 
114
 | 
252
 | 
 
 | 
 
 | 
  
252
  
 | 
 
 | 
635
 | 
   $_[0]->{dispatch}{$_[1]}->(@_);  | 
| 
115
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
116
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
117
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _quote_lit {  | 
| 
118
 | 
171
 | 
 
 | 
 
 | 
  
171
  
 | 
 
 | 
249
 | 
   my $arg = "$_[1]";  | 
| 
119
 | 
171
 | 
 
 | 
 
 | 
 
 | 
 
 | 
248
 | 
   my $q = $_[0]->{config}{quote_lit};  | 
| 
120
 | 
171
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
1263
 | 
   if (looks_like_number $arg or  | 
| 
 
 | 
 
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
121
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	$arg =~ /^\s*$q(.*)$q\s*$/ or  | 
| 
122
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	$arg =~ $_[0]->{config}{parameter_sigil} or  | 
| 
123
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	blessed($_[1])  | 
| 
124
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
        ) {  | 
| 
125
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # numeric, already quoted, a parameter, or an object  | 
| 
126
 | 
72
 | 
 
 | 
 
 | 
 
 | 
 
 | 
178
 | 
     return "$arg";  | 
| 
127
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
128
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   else {  | 
| 
129
 | 
99
 | 
 
 | 
 
 | 
 
 | 
 
 | 
177
 | 
     my $e = $_[0]->{config}{esc_quote_lit};  | 
| 
130
 | 
99
 | 
 
 | 
 
 | 
 
 | 
 
 | 
190
 | 
     $arg =~ s/$q/$e$q/g;  | 
| 
131
 | 
99
 | 
 
 | 
 
 | 
 
 | 
 
 | 
305
 | 
     return "$q$arg$q";  | 
| 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
133
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
134
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
135
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _quote_fld { # noop  | 
| 
136
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
   return $_[1];  | 
| 
137
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
138
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
139
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub express {  | 
| 
140
 | 
32
 | 
 
 | 
 
 | 
  
32
  
 | 
  
1
  
 | 
44
 | 
   my $self = shift;  | 
| 
141
 | 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
40
 | 
   my $x = $_[0];  | 
| 
142
 | 
32
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
54
 | 
   if ($SQL_ABSTRACT) {  | 
| 
143
 | 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
72
 | 
     $x = $self->canonize($x);  | 
| 
144
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
145
 | 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
84
 | 
   return $self->peel($x);  | 
| 
146
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
147
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
148
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub config {  | 
| 
149
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
  
1
  
 | 
2
 | 
   my $self = shift;  | 
| 
150
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
   my ($key, $val) = @_;  | 
| 
151
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
4
 | 
   if (!defined $key) {  | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
152
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return %{$self->{config}};  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
153
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
154
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   elsif (!defined $val) {  | 
| 
155
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return $self->{config}{$key};  | 
| 
156
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
157
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   else {  | 
| 
158
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
     return $self->{config}{$key} = $val;  | 
| 
159
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
160
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
161
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
162
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
163
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # canonize - rewrite mixed hash/array expressions in canonical lispy  | 
| 
164
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # array format - interpret like SQL::A  | 
| 
165
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub canonize {  | 
| 
166
 | 
71
 | 
 
 | 
 
 | 
  
71
  
 | 
  
1
  
 | 
35581
 | 
   my $self = shift;  | 
| 
167
 | 
71
 | 
 
 | 
 
 | 
 
 | 
 
 | 
141
 | 
   my ($expr) = @_;  | 
| 
168
 | 
71
 | 
 
 | 
 
 | 
 
 | 
 
 | 
115
 | 
   my $ret = [];  | 
| 
169
 | 
71
 | 
 
 | 
 
 | 
 
 | 
 
 | 
111
 | 
   my ($do,$is_op);  | 
| 
170
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $is_op = sub {  | 
| 
171
 | 
546
 | 
  
100
  
 | 
  
 66
  
 | 
  
546
  
 | 
 
 | 
1556
 | 
     if (!defined $_[0] || ref $_[0]) {  | 
| 
172
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
26
 | 
       return 0;  | 
| 
173
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
174
 | 
538
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
782
 | 
     if (!$_[1]) {  | 
| 
175
 | 
215
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
508
 | 
       if (defined $self->{dispatch}{$_[0]}) {  | 
| 
176
 | 
63
 | 
 
 | 
 
 | 
 
 | 
 
 | 
137
 | 
 	1;  | 
| 
177
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
178
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       else {  | 
| 
179
 | 
152
 | 
  
 50
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
755
 | 
 	puke "Unknown operator '$_[0]'" if (  | 
| 
 
 | 
 
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
180
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  $_[0] !~ /$$self{config}{safe_identifier}/ and  | 
| 
181
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  $_[0]=~/^-|[[:punct:]]/ and !looks_like_number($_[0])  | 
| 
182
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	 );  | 
| 
183
 | 
152
 | 
 
 | 
 
 | 
 
 | 
 
 | 
574
 | 
 	0;  | 
| 
184
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
185
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
186
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     else {  | 
| 
187
 | 
323
 | 
 
 | 
 
 | 
 
 | 
 
 | 
383
 | 
       grep /^\Q$_[0]\E$/, @{$type_table{$_[1]}};  | 
| 
 
 | 
323
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5396
 | 
    | 
| 
188
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
189
 | 
71
 | 
 
 | 
 
 | 
 
 | 
 
 | 
250
 | 
   };  | 
| 
190
 | 
71
 | 
 
 | 
 
 | 
 
 | 
 
 | 
117
 | 
   my $level=0;  | 
| 
191
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $do = sub {  | 
| 
192
 | 
346
 | 
 
 | 
 
 | 
  
346
  
 | 
 
 | 
1051
 | 
     my ($expr, $lhs, $arg_of) = @_;  | 
| 
193
 | 
346
 | 
 
 | 
 
 | 
 
 | 
 
 | 
809
 | 
     for (ref $expr) {  | 
| 
194
 | 
346
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
1238
 | 
       ($_ eq '' or blessed($expr)) && do {  | 
| 
195
 | 
113
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
184
 | 
 	if (defined $expr) {  | 
| 
196
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  # literal (value?)  | 
| 
197
 | 
113
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
765
 | 
 	  return $self->{config}{bind} ? [ -bind => $expr ] : $expr;  | 
| 
198
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
199
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	else {  | 
| 
200
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	  puke "undef not interpretable";  | 
| 
201
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
202
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       };  | 
| 
203
 | 
233
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
812
 | 
       /REF|SCALAR/ && do { # literals  | 
| 
204
 | 
22
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
54
 | 
 	if ($_ eq 'SCALAR') {  | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
205
 | 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
88
 | 
 	  return [-thing => $$expr] ; # never bind  | 
| 
206
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
207
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	elsif (ref $$expr eq 'ARRAY') {  | 
| 
208
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  # very SQL:A thing, but we'll do it  | 
| 
209
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
 	  my @a = @$$expr;  | 
| 
210
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
 	  my $thing = shift @a;  | 
| 
211
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
 	  @a = map { $self->_quote_lit($_) } @a;  | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
    | 
| 
212
 | 
5
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
16
 | 
 	  if ($self->{config}{bind}) {  | 
| 
213
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	    push @{$self->{bind_values}}, @a;  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
214
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  }  | 
| 
215
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  else {  | 
| 
216
 | 
5
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
10
 | 
 	    if ($self->{config}{anon_placeholder}) {  | 
| 
217
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
37
 | 
 	      ($thing =~ s/\Q$$self{config}{anon_placeholder}\E/$_/) for @a;  | 
| 
218
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    }  | 
| 
219
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  }  | 
| 
220
 | 
5
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
61
 | 
 	  return $lhs ? [-thing => $lhs, [-thing => $thing]] : [-thing => $thing];  | 
| 
221
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
222
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       };  | 
| 
223
 | 
211
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
395
 | 
       /ARRAY/ && do {  | 
| 
224
 | 
32
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
69
 | 
 	if ($is_op->($$expr[0],'infix_distributable')) {  | 
| 
225
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  # handle implicit equality pairs in an array  | 
| 
226
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
32
 | 
 	  my $op = shift @$expr;  | 
| 
227
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
25
 | 
 	  my (@args,@flat);  | 
| 
228
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  # flatten  | 
| 
229
 | 
12
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
41
 | 
 	  if (@$expr == 1) {  | 
| 
230
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
39
 | 
 	    for (ref($$expr[0])) {  | 
| 
231
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
30
 | 
 	      /ARRAY/ && do {  | 
| 
232
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
 		@flat = @{$$expr[0]};  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
    | 
| 
233
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
 		last;  | 
| 
234
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	      };  | 
| 
235
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	      /HASH/ && do {  | 
| 
236
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		@flat = %{$$expr[0]};  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
237
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		last;  | 
| 
238
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	      };  | 
| 
239
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	      puke 'Huh?';  | 
| 
240
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    };  | 
| 
241
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  }  | 
| 
242
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  else {  | 
| 
243
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34
 | 
 	    @flat = @$expr; # already flat  | 
| 
244
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  }  | 
| 
245
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
39
 | 
 	  while (@flat) {  | 
| 
246
 | 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
42
 | 
 	    my $elt = shift @flat;  | 
| 
247
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #	    $DB::single=1 if !defined($elt);  | 
| 
248
 | 
25
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
55
 | 
 	    if (!ref $elt) { # scalar means lhs of a pair or another op  | 
| 
249
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
127
 | 
 	      push @args, $do->({$elt => shift @flat},$lhs,$op);  | 
| 
250
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    }  | 
| 
251
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    else {  | 
| 
252
 | 
11
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
81
 | 
 	      next if (ref $elt eq 'ARRAY') && ! scalar @$elt or  | 
| 
 
 | 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
253
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		(ref $elt eq 'HASH') && ! scalar %$elt;   | 
| 
254
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
105
 | 
 	      push @args, $do->($elt,$lhs,$op);  | 
| 
255
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    }  | 
| 
256
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  }  | 
| 
257
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
61
 | 
  	  return [$op => @args];  | 
| 
258
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
259
 | 
20
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
49
 | 
 	if ($is_op->($$expr[0]) and !$is_op->($$expr[0],'infix_distributable')) {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
260
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  # some other op  | 
| 
261
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  return [ $$expr[0] => map {  | 
| 
262
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
 	    $do->($_,undef,$$expr[0])  | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
54
 | 
    | 
| 
263
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  } @$expr[1..$#$expr] ];  | 
| 
264
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
265
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	elsif (ref $$expr[0] eq 'HASH') { #?  | 
| 
266
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  return [ $self->{config}{array_op} =>  | 
| 
267
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
 		     map { $do->($_,$lhs,$self->{config}{array_op}) } @$expr ];  | 
| 
 
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
40
 | 
    | 
| 
268
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
269
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	else { # is a plain list  | 
| 
270
 | 
13
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
31
 | 
 	  if ($lhs) {  | 
| 
271
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    # implicit equality over array default op  | 
| 
272
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    return [ $self->{config}{array_op} => map {  | 
| 
273
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
 	      defined() ?  | 
| 
274
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		[ $self->{config}{implicit_eq_op} => $lhs,  | 
| 
275
 | 
13
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
70
 | 
 		  $do->($_,undef,$self->{config}{implicit_eq_op}) ] :  | 
| 
276
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		[ -is_null => $lhs ]  | 
| 
277
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    } @$expr ];  | 
| 
278
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  }  | 
| 
279
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  else {  | 
| 
280
 | 
9
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
57
 | 
 	    if ($arg_of and any { $is_op->($arg_of, $_) }  | 
| 
 
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
32
 | 
    | 
| 
281
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		  qw/function infix_listarg predicate reduce/  | 
| 
282
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	       ) {  | 
| 
283
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	      # function argument - return list itself  | 
| 
284
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
 	      return [ -list => map { $do->($_) } @$expr ];  | 
| 
 
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
137
 | 
    | 
| 
285
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    }  | 
| 
286
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    else {  | 
| 
287
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	      # distribute $array_op over implicit equality  | 
| 
288
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
54
 | 
 	      return $do->([ $self->{config}{array_op} => @$expr ]);  | 
| 
289
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    }  | 
| 
290
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  }  | 
| 
291
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
292
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       };  | 
| 
293
 | 
179
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
449
 | 
       /HASH/ && do {  | 
| 
294
 | 
179
 | 
 
 | 
 
 | 
 
 | 
 
 | 
589
 | 
 	my @k = keys %$expr;  | 
| 
295
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	#######  | 
| 
296
 | 
179
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
731
 | 
 	if (@k == 1) {  | 
| 
297
 | 
156
 | 
 
 | 
 
 | 
 
 | 
 
 | 
246
 | 
 	  my $k = $k[0];  | 
| 
298
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  # single hashpair  | 
| 
299
 | 
156
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
295
 | 
 	  if ($is_op->($k)) {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
300
 | 
59
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
97
 | 
 	    $is_op->($k,'infix_binary') && do {  | 
| 
301
 | 
33
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
87
 | 
 	      puke "Expected LHS for $k" unless $lhs;  | 
| 
302
 | 
33
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
98
 | 
 	      if (ref $$expr{$k} eq 'ARRAY') {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
303
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		# apply binary operator and join with array default op  | 
| 
304
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		return [ $self->{config}{array_op} => map {  | 
| 
305
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		  defined() ?  | 
| 
306
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		    [ $k => $lhs, $do->($_)] :  | 
| 
307
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		    { $self->{config}{ineq_op} => [-is_not_null => $lhs],  | 
| 
308
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		      $self->{config}{implicit_eq_op} => [-is_null => $lhs]  | 
| 
309
 | 
2
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
23
 | 
 		     }->{$k}  | 
| 
310
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
 		   } @{$$expr{$k}} ]  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
    | 
| 
311
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	      }  | 
| 
312
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	      elsif (defined $$expr{$k}) {  | 
| 
313
 | 
29
 | 
 
 | 
 
 | 
 
 | 
 
 | 
462
 | 
 		return [ $k => $lhs, $do->($$expr{$k},undef,$k) ]; #?  | 
| 
314
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	      }  | 
| 
315
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	      else { # IS (NOT) NULL  | 
| 
316
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
21
 | 
 		$k eq $self->{config}{ineq_op} && do {  | 
| 
317
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
 		  return [ -is_not_null => $lhs ];  | 
| 
318
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		};  | 
| 
319
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$k eq $self->{config}{implicit_eq_op} && do {  | 
| 
320
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		  return [ -is_null => $lhs ];  | 
| 
321
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		};  | 
| 
322
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		puke "Can't handle undef as argument to $k";  | 
| 
323
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	      }  | 
| 
324
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    };  | 
| 
325
 | 
26
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
67
 | 
 	    $is_op->($k,'function') && do {  | 
| 
326
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
122
 | 
 	      return [ $k => $do->($$expr{$k},undef,$k) ];  | 
| 
327
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    };  | 
| 
328
 | 
20
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
47
 | 
 	    $is_op->($k,'infix_listarg') && do {  | 
| 
329
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
65
 | 
 	      return [ $k => $lhs, $do->($$expr{$k},undef,$k) ];  | 
| 
330
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    };  | 
| 
331
 | 
16
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
33
 | 
 	    $is_op->($k,'prefix') && do {  | 
| 
332
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
126
 | 
 	      return [ $k => $do->($$expr{$k}) ];  | 
| 
333
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    };  | 
| 
334
 | 
8
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
27
 | 
 	    $is_op->($k,'infix_distributable') && do {  | 
| 
335
 | 
4
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
32
 | 
 	      if (!ref $$expr{$k} && $lhs) {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
336
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		return [ $k => $lhs, $do->($$expr{$k}) ];  | 
| 
337
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	      }  | 
| 
338
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	      elsif ( ref $$expr{$k} eq 'HASH' ) {  | 
| 
339
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
 		my @ar = %{$$expr{$k}};  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
    | 
| 
340
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
 		return $do->([$k=>@ar]); #?  | 
| 
341
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	      }  | 
| 
342
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	      elsif ( ref $$expr{$k} eq 'ARRAY') {  | 
| 
343
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
45
 | 
 		return  $do->([$k => $$expr{$k}]);  | 
| 
344
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	      }  | 
| 
345
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	      else {  | 
| 
346
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		puke "arg type '".ref($$expr{$k})."' not expected for op '$k'";  | 
| 
347
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	      }  | 
| 
348
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    };  | 
| 
349
 | 
4
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
10
 | 
 	    $is_op->($k,'predicate') && do {  | 
| 
350
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	      puke "predicate function '$k' requires an length 3 arrayref argument"  | 
| 
351
 | 
2
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
7
 | 
 		unless ref $$expr{$k} eq 'ARRAY' and @{$$expr{$k}} == 3;  | 
| 
 
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
    | 
| 
352
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	      return [ $k => [-thing => $$expr{$k}->[0]],  | 
| 
353
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			      $do->($$expr{$k}->[1], undef, $k),  | 
| 
354
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
31
 | 
 			      $do->($$expr{$k}->[2], undef, $k) ];  | 
| 
355
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    };  | 
| 
356
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
5
 | 
 	    $is_op->($k,'reduce') && do {  | 
| 
357
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	      puke "reduce function '$k' requires an length 5 arrayref argument"  | 
| 
358
 | 
2
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
8
 | 
 		unless ref $$expr{$k} eq 'ARRAY' and @{$$expr{$k}} == 5;  | 
| 
 
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
    | 
| 
359
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	      return [ $k => [-thing => $$expr{$k}->[0]],  | 
| 
360
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		       $do->($$expr{$k}->[1], undef, $k),  | 
| 
361
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		       [-thing => $$expr{$k}->[2]],  | 
| 
362
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		       $do->($$expr{$k}->[3], undef, $k),  | 
| 
363
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
36
 | 
 		       $do->($$expr{$k}->[4], undef, $k)];  | 
| 
364
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    };  | 
| 
365
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	    puke "Operator $k not expected";  | 
| 
366
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  }  | 
| 
367
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  elsif (ref($$expr{$k}) && ref($$expr{$k}) ne 'SCALAR') {  | 
| 
368
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    # $k is an LHS  | 
| 
369
 | 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
545
 | 
 	    return $do->($$expr{$k}, $k, undef);  | 
| 
370
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  }  | 
| 
371
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  else {  | 
| 
372
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    # implicit equality  | 
| 
373
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    return defined $$expr{$k} ?  | 
| 
374
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	      [ $self->{config}{implicit_eq_op} => $k,  | 
| 
375
 | 
59
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
586
 | 
 		$do->($$expr{$k},undef,$self->{config}{implicit_eq_op}) ] :  | 
| 
376
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	      [ -is_null => $k ];  | 
| 
377
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  }  | 
| 
378
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
379
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	#######  | 
| 
380
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	else {  | 
| 
381
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  # >1 hashpair  | 
| 
382
 | 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
36
 | 
 	  my @args;  | 
| 
383
 | 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
45
 | 
 	  for my $k (@k) {  | 
| 
384
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    # all keys are ops, or none is - otherwise barf  | 
| 
385
 | 
52
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
103
 | 
 	    if ( $is_op->($k, 'infix_binary') ) {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
386
 | 
6
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
22
 | 
 	      puke "No LHS provided for implicit $$self{config}{hash_op}" unless defined $lhs;  | 
| 
387
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
33
 | 
 	      push @args, $do->({$k => $$expr{$k}},$lhs);  | 
| 
388
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    }  | 
| 
389
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    elsif ( $is_op->($k, 'prefix') || $is_op->($k,'function') ) {  | 
| 
390
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
23
 | 
 		push @args, [ $k => $do->($$expr{$k},undef, $k) ];  | 
| 
391
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	      }  | 
| 
392
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	      elsif (!$is_op->($k)) {  | 
| 
393
 | 
43
 | 
 
 | 
 
 | 
 
 | 
 
 | 
333
 | 
 		push @args, $do->({$k => $$expr{$k}});  | 
| 
394
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	      }  | 
| 
395
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    else {  | 
| 
396
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	      puke "Problem handling operator '$k'";  | 
| 
397
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    }  | 
| 
398
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  }  | 
| 
399
 | 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
99
 | 
 	  return [ $self->{config}{hash_op} => @args ];  | 
| 
400
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
401
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       };  | 
| 
402
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
403
 | 
71
 | 
 
 | 
 
 | 
 
 | 
 
 | 
820
 | 
   };  | 
| 
404
 | 
71
 | 
 
 | 
 
 | 
 
 | 
 
 | 
188
 | 
   $ret = $do->($expr);  | 
| 
405
 | 
71
 | 
 
 | 
 
 | 
 
 | 
 
 | 
255
 | 
   return $ret;  | 
| 
406
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
407
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
408
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # peel - recurse $args = [ -op, @args ] to create complete production  | 
| 
409
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub peel {  | 
| 
410
 | 
445
 | 
 
 | 
 
 | 
  
445
  
 | 
  
1
  
 | 
644
 | 
   my ($self, $args) = @_;  | 
| 
411
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
412
 | 
445
 | 
  
 50
  
 | 
  
100
  
 | 
 
 | 
 
 | 
1385
 | 
   if (!defined $args) {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
413
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return '';  | 
| 
414
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
415
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   elsif (!ref $args or blessed($args)) { # single literal argument  | 
| 
416
 | 
193
 | 
 
 | 
 
 | 
 
 | 
 
 | 
500
 | 
     return $args;  | 
| 
417
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
418
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   elsif (ref $args eq 'ARRAY') {  | 
| 
419
 | 
252
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
473
 | 
     return '' unless (@$args);  | 
| 
420
 | 
252
 | 
 
 | 
 
 | 
 
 | 
 
 | 
359
 | 
     my $op = shift @$args;  | 
| 
421
 | 
252
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
529
 | 
     puke "'$op' : unknown operator" unless $self->{dispatch}{$op};  | 
| 
422
 | 
252
 | 
 
 | 
 
 | 
 
 | 
 
 | 
369
 | 
     my $expr = $self->_dispatch( $op, [map { $self->peel($_) } @$args] );  | 
| 
 
 | 
389
 | 
 
 | 
 
 | 
 
 | 
 
 | 
640
 | 
    | 
| 
423
 | 
252
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
486
 | 
     if (grep /\Q$op\E/, @{$type_table{infix_distributable}}) {  | 
| 
 
 | 
252
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2418
 | 
    | 
| 
424
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       # group  | 
| 
425
 | 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
167
 | 
       return "($expr)"  | 
| 
426
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
427
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     else {  | 
| 
428
 | 
218
 | 
 
 | 
 
 | 
 
 | 
 
 | 
703
 | 
       return $expr;  | 
| 
429
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
430
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
431
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   else {  | 
| 
432
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     puke "Can only peel() arrayrefs, scalars or literals";  | 
| 
433
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
434
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
435
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
436
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ### writers  | 
| 
437
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
438
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub infix_binary {  | 
| 
439
 | 
78
 | 
 
 | 
 
 | 
  
78
  
 | 
  
0
  
 | 
203
 | 
   my ($self, $op, $args) = @_;  | 
| 
440
 | 
78
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
474
 | 
   unless ($op and $args and !ref($op)  | 
| 
 
 | 
 
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
441
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    and ref($args) eq 'ARRAY'){  | 
| 
442
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     puke "arg1 must be scalar, arg2 must be arrayref";  | 
| 
443
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
444
 | 
78
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
161
 | 
   unless ( @$args == 2 ) {  | 
| 
445
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     puke "For $op, arg2 must have length 2";  | 
| 
446
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
447
 | 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
164
 | 
   return '('.join(" ", $$args[0], _write_op($op), $$args[1]).')';  | 
| 
448
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
449
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
450
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
  
0
  
 | 
7
 | 
 sub infix_listarg { infix_binary(@_) }  | 
| 
451
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
452
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub infix_distributable {  | 
| 
453
 | 
35
 | 
 
 | 
 
 | 
  
35
  
 | 
  
0
  
 | 
73
 | 
   my ($self, $op, $args) = @_;  | 
| 
454
 | 
35
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
241
 | 
   unless ($op and $args and !ref($op)  | 
| 
 
 | 
 
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
455
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    and ref($args) eq 'ARRAY'){  | 
| 
456
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     puke "arg1 must be scalar, arg2 must be arrayref";  | 
| 
457
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
458
 | 
35
 | 
 
 | 
 
 | 
 
 | 
 
 | 
78
 | 
   $op = _write_op($op);  | 
| 
459
 | 
35
 | 
 
 | 
 
 | 
 
 | 
 
 | 
156
 | 
   return join(" $op ", @$args);  | 
| 
460
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
461
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
462
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub prefix {  | 
| 
463
 | 
12
 | 
 
 | 
 
 | 
  
12
  
 | 
  
0
  
 | 
25
 | 
   my ($self, $op, $args) = @_;  | 
| 
464
 | 
12
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
113
 | 
   unless ($op and $args and !ref($op)  | 
| 
 
 | 
 
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
465
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    and ref($args) eq 'ARRAY'){  | 
| 
466
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     puke "arg1 must be scalar, arg2 must be arrayref";  | 
| 
467
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
468
 | 
12
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
32
 | 
   unless (@$args == 1) {  | 
| 
469
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     puke "For $op, arg2 must have length 1"  | 
| 
470
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
471
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
25
 | 
   return _write_op($op)." ".$$args[0];  | 
| 
472
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
473
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
474
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub postfix {  | 
| 
475
 | 
6
 | 
 
 | 
 
 | 
  
6
  
 | 
  
0
  
 | 
12
 | 
   my ($self, $op, $args) = @_;  | 
| 
476
 | 
6
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
63
 | 
   unless ($op and $args and !ref($op)  | 
| 
 
 | 
 
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
477
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    and ref($args) eq 'ARRAY'){  | 
| 
478
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     puke "arg1 must be scalar, arg2 must be arrayref";  | 
| 
479
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
480
 | 
6
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
20
 | 
   unless (@$args == 1) {  | 
| 
481
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     puke "For $op, arg2 must have length 1"  | 
| 
482
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
483
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
29
 | 
   return $$args[0]." "._write_op($op);  | 
| 
484
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
485
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
486
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub function {  | 
| 
487
 | 
6
 | 
 
 | 
 
 | 
  
6
  
 | 
  
0
  
 | 
15
 | 
   my ($self, $op, $args) = @_;  | 
| 
488
 | 
6
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
70
 | 
   unless ($op and $args and !ref($op)  | 
| 
 
 | 
 
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
489
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    and ref($args) eq 'ARRAY'){  | 
| 
490
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     puke "arg1 must be scalar, arg2 must be arrayref";  | 
| 
491
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
492
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
   return _write_op($op).'('.join(',',@$args).')';  | 
| 
493
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
494
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
495
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub predicate {  | 
| 
496
 | 
2
 | 
 
 | 
 
 | 
  
2
  
 | 
  
0
  
 | 
5
 | 
   my ($self, $op, $args) = @_;  | 
| 
497
 | 
2
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
15
 | 
   unless ($op and $args and !ref($op)  | 
| 
 
 | 
 
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
498
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    and ref($args) eq 'ARRAY'){  | 
| 
499
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     puke "arg1 must be scalar, arg2 must be arrayref";  | 
| 
500
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
501
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
4
 | 
   unless ( @$args == 3 ) {  | 
| 
502
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     puke "For $op, arg2 must have length 3";  | 
| 
503
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
504
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
   return _write_op($op)."("."$$args[0] IN $$args[1] WHERE $$args[2]".")";  | 
| 
505
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
506
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
507
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub extract {  | 
| 
508
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
0
 | 
   my ($self, $op, $args) = @_;  | 
| 
509
 | 
  
0
  
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
   unless ($op and $args and !ref($op)  | 
| 
 
 | 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
510
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    and ref($args) eq 'ARRAY'){  | 
| 
511
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     puke "arg1 must be scalar, arg2 must be arrayref";  | 
| 
512
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
513
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   unless ( @$args == 3 ) {  | 
| 
514
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     puke "For $op, arg2 must have length 3";  | 
| 
515
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
516
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   return _write_op($op)."("."$$args[0] IN $$args[1] | $$args[2]".")";  | 
| 
517
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
518
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
519
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub reduce {  | 
| 
520
 | 
2
 | 
 
 | 
 
 | 
  
2
  
 | 
  
0
  
 | 
5
 | 
   my ($self, $op, $args) = @_;  | 
| 
521
 | 
2
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
18
 | 
   unless ($op and $args and !ref($op)  | 
| 
 
 | 
 
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
522
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    and ref($args) eq 'ARRAY'){  | 
| 
523
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     puke "arg1 must be scalar, arg2 must be arrayref";  | 
| 
524
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
525
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
5
 | 
   unless ( @$args == 5 ) {  | 
| 
526
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     puke "For $op, arg2 must have length 5";  | 
| 
527
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
528
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
   return _write_op($op)."("."$$args[0] = $$args[1], $$args[2] IN $$args[3] | $$args[4]".")";  | 
| 
529
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
530
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
531
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # bind either:  | 
| 
532
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # - pulls out literals, pushes them into {bind_values}, and replaces them  | 
| 
533
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #   with '?' in the produced statement (a la SQL:A), -or-  | 
| 
534
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # - identifies named parameters in the expression and pushes these into  | 
| 
535
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #   {parameters}, leaving them in the produced statement  | 
| 
536
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub bind { # special  | 
| 
537
 | 
83
 | 
 
 | 
 
 | 
  
83
  
 | 
  
0
  
 | 
148
 | 
   my ($self, $op, $args) = @_;  | 
| 
538
 | 
83
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
442
 | 
   unless ($op and $args and !ref($op)  | 
| 
 
 | 
 
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
539
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    and ref($args) eq 'ARRAY'){  | 
| 
540
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     puke "arg1 must be scalar, arg2 must be arrayref";  | 
| 
541
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
542
 | 
83
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
485
 | 
   if ($$args[0] =~ $self->{config}{parameter_sigil}) {  | 
| 
543
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     push @{$self->{parameters}}, $$args[0];  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
544
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
545
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   else {  | 
| 
546
 | 
83
 | 
 
 | 
 
 | 
 
 | 
 
 | 
274
 | 
     push @{$self->{bind_values}},  | 
| 
547
 | 
83
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
179
 | 
       $self->{config}{anon_placeholder} ? $$args[0] :  | 
| 
548
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       $self->_quote_lit($$args[0]);  | 
| 
549
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
550
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   return $self->{config}{anon_placeholder} ?  | 
| 
551
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $self->{config}{anon_placeholder} :  | 
| 
552
 | 
83
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
211
 | 
     $self->_quote_lit($$args[0]);  | 
| 
553
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
554
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
555
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub list { # special  | 
| 
556
 | 
5
 | 
 
 | 
 
 | 
  
5
  
 | 
  
0
  
 | 
20
 | 
   my ($self, $op, $args) = @_;  | 
| 
557
 | 
5
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
50
 | 
   unless ($op and $args and !ref($op)  | 
| 
 
 | 
 
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
558
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    and ref($args) eq 'ARRAY'){  | 
| 
559
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     puke "arg1 must be scalar, arg2 must be arrayref";  | 
| 
560
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
561
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22
 | 
   my ($l,$r) = split '',$self->{config}{list_braces};  | 
| 
562
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
   return $l.join(',',@$args).$r;  | 
| 
563
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
564
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
565
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub thing { # special  | 
| 
566
 | 
29
 | 
 
 | 
 
 | 
  
29
  
 | 
  
0
  
 | 
47
 | 
   my ($self, $op, $args) = @_;  | 
| 
567
 | 
29
 | 
 
 | 
 
 | 
 
 | 
 
 | 
71
 | 
   return join(' ',@$args);  | 
| 
568
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
569
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
570
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _write_op {  | 
| 
571
 | 
141
 | 
 
 | 
 
 | 
  
141
  
 | 
 
 | 
221
 | 
   my ($op) = @_;  | 
| 
572
 | 
141
 | 
 
 | 
 
 | 
 
 | 
 
 | 
354
 | 
   $op =~ s/^-//;  | 
| 
573
 | 
141
 | 
 
 | 
 
 | 
 
 | 
 
 | 
723
 | 
   my $c = (caller(1))[3];  | 
| 
574
 | 
141
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
339
 | 
   return '' if ($op eq '()');  | 
| 
575
 | 
141
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
320
 | 
   return join(' ', map { ($c=~/infix|prefix|postfix/) ? uc $_ : $_ } split /_/,$op);  | 
| 
 
 | 
155
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1074
 | 
    | 
| 
576
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
577
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
578
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 NAME  | 
| 
579
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
580
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Neo4j::Cypher::Abstract::Peeler - Parse Perl structures as expressions  | 
| 
581
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
582
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 SYNOPSIS  | 
| 
583
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
584
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 DESCRIPTION  | 
| 
585
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
586
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 C allows the user to write L
 | 
| 
587
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Cypher|https://neo4j.com/docs/developer-manual/current/cypher/> query  | 
| 
588
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 language expressions as Perl data structures. The interpretation of  | 
| 
589
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 data structures follows L very closely, but attempts to  | 
| 
590
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 be more systematic and general.  | 
| 
591
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
592
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 C only produces expressions, typically used as arguments to  | 
| 
593
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 C clauses. It is integrated into L,  | 
| 
594
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 which produces full Cypher statements.  | 
| 
595
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
596
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Like L, C translates scalars, scalar refs,  | 
| 
597
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 array refs, and hash refs syntactically to create expression  | 
| 
598
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 components such as functions and operators. The contents of the  | 
| 
599
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 scalars or references are generally operators or the arguments to  | 
| 
600
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 operators or functions.  | 
| 
601
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
602
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Contents of scalar references are always treated as literals and  | 
| 
603
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 inserted into the expression verbatim.  | 
| 
604
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
605
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 Expressing Expressions  | 
| 
606
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
607
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =over  | 
| 
608
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
609
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item * Functions  | 
| 
610
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
611
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Ordinary functions in Cypher are written as the name of the function  | 
| 
612
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 preceded by a dash. They can be expressed as follows:  | 
| 
613
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
614
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  { -func => $arg }  | 
| 
615
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  [ -func => $arg ]  | 
| 
616
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  \"func($arg)"  | 
| 
617
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
618
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  { -sin => $pi/2 }  | 
| 
619
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  # returns sin(/2)  | 
| 
620
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
621
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item * Infix Operators  | 
| 
622
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
623
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Infix operators, like equality (C<=>), inequality (CE>),  | 
| 
624
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 binary operations (C<+,-,*,/>), and certain string operators  | 
| 
625
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 (C<-contains>, C<-starts_with>, C) are expressed as follows:  | 
| 
626
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
627
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  { $expr1 => { $infix_op => $expr2 } }  | 
| 
628
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
629
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  { 'n.name'  => { '<>' => 'Fred' } }  | 
| 
630
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  # returns n.name <> "Fred"  | 
| 
631
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
632
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This may seem like overkill, but comes in handy for...  | 
| 
633
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
634
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item * AND and OR  | 
| 
635
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
636
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 C implements the L convention that hash refs  | 
| 
637
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 represent conditions joined by C and array refs represent  | 
| 
638
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 conditions joined by C. Key-value pairs and array value pairs are  | 
| 
639
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 interpreted as an implicit equalities to be ANDed or ORed.  | 
| 
640
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
641
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  { $lhs1 => $rhs1, $lhs2 => $rhs2 }  | 
| 
642
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  { al => 'king', 'eddie' => 'prince', vicky => 'queen' }  | 
| 
643
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  # returns al = "king" AND eddie = "prince" AND vicky = "queen"  | 
| 
644
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
645
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  [ $lhs1 => $rhs1, $lhs2 => $rhs2 ]  | 
| 
646
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  [ 'a.name' => 'Fred', 'a.name' => 'Barney']  | 
| 
647
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  # returns a.name = "Fred" OR a.name = "Barney"  | 
| 
648
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
649
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 A single left-hand side can be "distributed" over a set of conditions,  | 
| 
650
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 with corresponding conjunction:  | 
| 
651
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
652
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  { zzyxx => [ 'narf', 'boog', 'frelb' ] } # implicit equality, OR  | 
| 
653
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  # returns zzyxx = "narf" OR zzyxx = "boog" OR zzyxx = "frelb"  | 
| 
654
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  { zzyxx => { '<>' =>  'narf', '<>' => 'boog' } } # explicit infix, AND  | 
| 
655
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  # returns zzyxx <> "narf" AND zzyxx <> "boog"  | 
| 
656
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  { zzyxx => [ '<>' =>  'narf', -contains => 'boog' ] } # explicit infix, OR  | 
| 
657
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  # returns zzyxx <> "narf" OR zzyxx CONTAINS "boog"  | 
| 
658
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
659
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item * Expressing null  | 
| 
660
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
661
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 C can be used to express NULL mostly as in L so  | 
| 
662
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 that the following are equivalent  | 
| 
663
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
664
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  { a.name => { '<>' => undef}, b.name => undef}  | 
| 
665
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  { -is_not_null => 'a.name', -is_null => 'b.name' }  | 
| 
666
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  # returns a.name IS NOT NULL  AND b.name IS NULL  | 
| 
667
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
668
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item * Predicates: -all, -any, -none, -single, -filter  | 
| 
669
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
670
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 These Cypher functions have the form  | 
| 
671
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
672
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  func(variable IN list WHERE predicate)  | 
| 
673
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
674
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 To render these, provide an array ref of the three arguments in order:  | 
| 
675
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
676
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  { -all => ['x', [1,2,3], {'x' => 3}] }  | 
| 
677
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  # returns all(x IN [1,2,3] WHERE x = 3)  | 
| 
678
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
679
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item * List arguments  | 
| 
680
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
681
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 For cypher expressions that accept lists (arrays in square brackets), use arrayrefs:  | 
| 
682
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
683
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  { 'n.name' => { -in => ['fred','wilma','pebbles'] }}  | 
| 
684
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  # returns n.name IN ['fred','wilma','pebbles']  | 
| 
685
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
686
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =back  | 
| 
687
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
688
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 Parameters and Bind Values  | 
| 
689
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
690
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Cypher parameters (which use the '$' sigil) may be included in  | 
| 
691
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 expressions (with the dollar sign appropriately escaped). These are  | 
| 
692
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 collected during parsing and can be reported in order with the the  | 
| 
693
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 C method.  | 
| 
694
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
695
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 L automatically collects literal values and replaces  | 
| 
696
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 them with anonymous placeholders (C>), returning an array of values  | 
| 
697
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 for binding in L. C will collect values and report them  | 
| 
698
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 with the C method. If the config key  | 
| 
699
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 C is set:  | 
| 
700
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
701
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  $peeler->{config}{anon_placeholder} = '?'  | 
| 
702
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
703
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 then C will also do the replacement in the final expression  | 
| 
704
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 production like L.  | 
| 
705
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
706
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The real reason to pay attention to literal values is to be able to  | 
| 
707
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 appropriately quote them in the final production. When  | 
| 
708
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 C is not set (default), then an attempt is made to  | 
| 
709
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 correctly quote string values and such.  | 
| 
710
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
711
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 GUTS  | 
| 
712
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
713
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  TBD  | 
| 
714
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
715
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 The config hash  | 
| 
716
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
717
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The C object property C<{config}> is a hashref containing  | 
| 
718
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 various defaults to make Peeler output sound like Cypher. One could  | 
| 
719
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 customize it to make output sound like SQL (someday).  | 
| 
720
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
721
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Keys/values are as follows:  | 
| 
722
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
723
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  bind => 1,  | 
| 
724
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  anon_placeholder => undef, # '?',  | 
| 
725
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  hash_op => '-and',  | 
| 
726
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  array_op => '-or',  | 
| 
727
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  list_braces => '[]',  | 
| 
728
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  ineq_op => '<>',  | 
| 
729
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  implicit_eq_op => '=',  | 
| 
730
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  quote_lit => "'",  | 
| 
731
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  esc_quote_lit => "\\",  | 
| 
732
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  parameter_sigil => qw/^([:$?])|({[^}]+}$)/,  | 
| 
733
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  quote_fld => undef,  | 
| 
734
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  safe_identifier => qw/[a-zA-Z_.]+/  | 
| 
735
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
736
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 METHODS  | 
| 
737
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
738
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =over  | 
| 
739
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
740
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item express()  | 
| 
741
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
742
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Canonize, then peel. Returns scalar string (the expression).  | 
| 
743
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
744
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item canonize()  | 
| 
745
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
746
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Render SQL:A-like expression into a canonical lisp-like array  | 
| 
747
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 tree. Returns an arrayref.  | 
| 
748
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
749
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item peel()  | 
| 
750
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
751
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Render a canonical tree as a Cypher string expression. Returns scalar  | 
| 
752
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 string.  | 
| 
753
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
754
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item parameters()  | 
| 
755
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
756
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Get a list in order of all named parameters.  | 
| 
757
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
758
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item bind_values()  | 
| 
759
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
760
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Get a list of bind values in order that were replaced by the anonymous  | 
| 
761
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 placeholder.  | 
| 
762
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
763
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =back  | 
| 
764
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
765
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 SEE ALSO  | 
| 
766
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
767
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 L, L.  | 
| 
768
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
769
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 AUTHOR  | 
| 
770
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
771
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  Mark A. Jensen  | 
| 
772
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  CPAN: MAJENSEN  | 
| 
773
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  majensen -at- cpan -dot- org  | 
| 
774
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
775
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 LICENSE  | 
| 
776
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
777
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This software is provided for use under the terms of Perl itself.  | 
| 
778
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
779
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 COPYRIGHT  | 
| 
780
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
781
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  (c) 2017 Mark A. Jensen  | 
| 
782
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
783
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =cut  | 
| 
784
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
785
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 1;  |