X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FSQL%2FAbstract%2FReference.pm;h=e1ed68a696791737d700d2a757ca629c1b720c8b;hb=d1e8cbe612ea656be0c9f6e8c20075a0088b5e0e;hp=67567ccf178971f5eab3c9b4da20ca20930f0ade;hpb=cc230faadb608351c7b6149b2b906687f8c23687;p=scpubgit%2FQ-Branch.git diff --git a/lib/SQL/Abstract/Reference.pm b/lib/SQL/Abstract/Reference.pm index 67567cc..e1ed68a 100644 --- a/lib/SQL/Abstract/Reference.pm +++ b/lib/SQL/Abstract/Reference.pm @@ -670,4 +670,188 @@ Expands the elements of the value arrayref: (?, foo, ?, ?) [ 1, 2, 3 ] +=head2 op + +If an expander is registered for the op name, delegates to the expander; if +not, expands the argument values: + + # expr + { -op => [ 'ident', 'foo.bar' ] } + + # aqt + { -ident => [ 'foo', 'bar' ] } + + # query + foo.bar + [] + + # expr + { -op => [ '=', { -ident => 'foo' }, 3 ] } + + # aqt + { -op => [ '=', { -ident => [ 'foo' ] }, { -bind => [ undef, 3 ] } ] } + + # query + foo = ? + [ 3 ] + +=head2 func + +Expands the argument values: + + # expr + { -func => [ 'coalesce', { -ident => 'thing' }, 'fallback' ] } + + # aqt + { -func => [ + 'coalesce', { -ident => [ 'thing' ] }, + { -bind => [ undef, 'fallback' ] }, + ] } + + # query + COALESCE(thing, ?) + [ 'fallback' ] + +=head2 values + +A hashref value is expanded as an expression: + + # expr + { -values => { -row => [ 1, 2 ] } } + + # aqt + { -values => [ + { -row => [ { -bind => [ undef, 1 ] }, { -bind => [ undef, 2 ] } ] } + ] } + + # query + VALUES (?, ?) + [ 1, 2 ] + +An arrayref value's elements are either expressions or arrayrefs to be +treated as rows: + + # expr + { -values => [ { -row => [ 1, 2 ] }, [ 3, 4 ] ] } + + # aqt + { -values => [ + { -row => [ { -bind => [ undef, 1 ] }, { -bind => [ undef, 2 ] } ] }, + { -row => [ { -bind => [ undef, 3 ] }, { -bind => [ undef, 4 ] } ] }, + ] } + + # query + VALUES (?, ?), (?, ?) + [ 1, 2, 3, 4 ] + +=head2 between op + +The RHS of between must either be a pair of exprs/plain values, or a single +literal expr: + + # expr + { -between => [ 'size', 3, { -ident => 'max_size' } ] } + + # aqt + { -op => [ + 'between', { -ident => [ 'size' ] }, { -bind => [ undef, 3 ] }, + { -ident => [ 'max_size' ] }, + ] } + + # query + ( size BETWEEN ? AND max_size ) + [ 3 ] + + # expr + { size => { -between => [ 3, { -ident => 'max_size' } ] } } + + # aqt + { -op => [ + 'between', { -ident => [ 'size' ] }, { -bind => [ 'size', 3 ] }, + { -ident => [ 'max_size' ] }, + ] } + + # query + ( size BETWEEN ? AND max_size ) + [ 3 ] + + # expr + { size => { -between => \"3 AND 7" } } + + # aqt + { -op => + [ + 'between', { -ident => [ 'size' ] }, + { -literal => [ '3 AND 7' ] }, + ] + } + + # query + ( size BETWEEN 3 AND 7 ) + [] + +not_between is also expanded: + + # expr + { size => { -not_between => [ 3, 7 ] } } + + # aqt + { -op => [ + 'not_between', { -ident => [ 'size' ] }, + { -bind => [ 'size', 3 ] }, { -bind => [ 'size', 7 ] }, + ] } + + # query + ( size NOT BETWEEN ? AND ? ) + [ 3, 7 ] + +=head2 in op + +The RHS of in/not_in is either an expr/value or an arrayref of +exprs/values: + + # expr + { foo => { -in => [ 1, 2 ] } } + + # aqt + { -op => [ + 'in', { -ident => [ 'foo' ] }, { -bind => [ 'foo', 1 ] }, + { -bind => [ 'foo', 2 ] }, + ] } + + # query + foo IN ( ?, ? ) + [ 1, 2 ] + + # expr + { bar => { -not_in => \"(1, 2)" } } + + # aqt + { -op => + [ 'not_in', { -ident => [ 'bar' ] }, { -literal => [ '1, 2' ] } ] + } + + # query + bar NOT IN ( 1, 2 ) + [] + +A non-trivial LHS is expanded with ident as the default rather than value: + + # expr + { -in => [ + { -row => [ 'x', 'y' ] }, { -row => [ 1, 2 ] }, + { -row => [ 3, 4 ] }, + ] } + + # aqt + { -op => [ + 'in', { -row => [ { -ident => [ 'x' ] }, { -ident => [ 'y' ] } ] }, + { -row => [ { -bind => [ undef, 1 ] }, { -bind => [ undef, 2 ] } ] }, + { -row => [ { -bind => [ undef, 3 ] }, { -bind => [ undef, 4 ] } ] }, + ] } + + # query + (x, y) IN ( (?, ?), (?, ?) ) + [ 1, 2, 3, 4 ] + =cut