X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FSQL%2FAbstract%2FReference.pm;h=ad27a77f99cc4601b8b1f53d2b1266db531b7124;hb=77f800d538d194fb2ea795e0afe7434399e68a44;hp=d8f6763a733a0e756922ab300a151f0301e9d3ca;hpb=b3cccbdf531b1ddc5c198d07e837b6c31abdef1a;p=dbsrgits%2FSQL-Abstract.git diff --git a/lib/SQL/Abstract/Reference.pm b/lib/SQL/Abstract/Reference.pm index d8f6763..ad27a77 100644 --- a/lib/SQL/Abstract/Reference.pm +++ b/lib/SQL/Abstract/Reference.pm @@ -20,7 +20,7 @@ comment before a code block saying C<# expr>, this is what's being described. The explicit structure that an expression is converted into before it's rendered into SQL is referred to as an abstract query tree. If you see a variable with C in the name, or a comment before a code block saying -C<# aqt>#, this is what's being described. +C<# aqt>, this is what's being described. =head2 SQL and Bind Values (query) @@ -311,6 +311,18 @@ Converted to IS NULL : id IS NULL [] +(equivalent to the -is operator) : + + # expr + { id => { -is => undef } } + + # aqt + { -op => [ 'is_null', { -ident => [ 'id' ] } ] } + + # query + id IS NULL + [] + =head3 identifier hashpair w/literal RHS Directly appended to the key, remember you need to provide an operator: @@ -408,7 +420,7 @@ used as the top level logic op: Becomes equivalent to a -and over an arrayref of hashtriples constructed with the identifier as the key and each key/value pair of the original -hashref as the vlue: +hashref as the value: # expr { id => { '<' => 4, '>' => 3 } } @@ -424,6 +436,8 @@ hashref as the vlue: ( id < ? AND id > ? ) [ 4, 3 ] +is sugar for: + # expr { -and => [ { id => { '<' => 4 } }, { id => { '>' => 3 } } ] } @@ -438,4 +452,114 @@ hashref as the vlue: ( id < ? AND id > ? ) [ 4, 3 ] +=head2 operator hashpair types + +A hashpair whose key begins with a -, or whose key consists entirely of +nonword characters (thereby covering '=', '>', pg json ops, etc.) is +processed as an operator hashpair. + +=head3 operator hashpair w/node type + +If a node type expander is registered for the key, the hashpair is +treated as a L. + +=head3 operator hashpair w/registered op + +If an expander is registered for the op name, that's run and the +result returned: + + # expr + { -in => [ 'foo', 1, 2, 3 ] } + + # aqt + { -op => [ + 'in', { -ident => [ 'foo' ] }, { -bind => [ undef, 1 ] }, + { -bind => [ undef, 2 ] }, { -bind => [ undef, 3 ] }, + ] } + + # query + foo IN ( ?, ?, ? ) + [ 1, 2, 3 ] + +=head3 operator hashpair w/not prefix + +If the op name starts -not_ this is stripped and turned into a -not +wrapper around the result: + + # expr + { -not_ident => 'foo' } + + # aqt + { -op => [ 'not', { -ident => [ 'foo' ] } ] } + + # query + (NOT foo) + [] + +is equivalent to: + + # expr + { -not => { -ident => 'foo' } } + + # aqt + { -op => [ 'not', { -ident => [ 'foo' ] } ] } + + # query + (NOT foo) + [] + +=head3 operator hashpair with unknown op + +If the C option is set (which is recommended but +defaults to off for backwards compatibility reasons), an unknown op +expands into a C<-func> node: + + # expr + { -count => { -ident => '*' } } + + # aqt + { -func => [ 'count', { -ident => [ '*' ] } ] } + + # query + COUNT(*) + [] + +If not, an unknown op will expand into a C<-op> node. + +=head2 hashref expr + +A hashref with more than one pair becomes a C<-and> over its hashpairs, i.e. + + # expr + { x => 1, y => 2 } + + # aqt + { -op => [ + 'and', + { -op => [ '=', { -ident => [ 'x' ] }, { -bind => [ 'x', 1 ] } ] }, + { -op => [ '=', { -ident => [ 'y' ] }, { -bind => [ 'y', 2 ] } ] }, + ] } + + # query + ( x = ? AND y = ? ) + [ 1, 2 ] + +is short hand for: + + # expr + { -and => [ { x => 1 }, { y => 2 } ] } + + # aqt + { -op => [ + 'and', + { -op => [ '=', { -ident => [ 'x' ] }, { -bind => [ 'x', 1 ] } ] }, + { -op => [ '=', { -ident => [ 'y' ] }, { -bind => [ 'y', 2 ] } ] }, + ] } + + # query + ( x = ? AND y = ? ) + [ 1, 2 ] + +=head2 arrayref expr + =cut