no
warnings
'qw'
;
my
$sqla
= SQL::Abstract::More->new;
my
(
$sql
,
@bind
,
$join
);
(
$sql
,
@bind
) =
$sqla
->with_recursive(
-table
=>
'nodes'
,
-columns
=> [
qw/x/
],
-as_select
=> {
-from
=>
'DUAL'
,
-columns
=> [
qw/59/
],
-union_all
=> [
-from
=> [
-join
=>
qw/edge {bb=x} nodes/
],
-columns
=> [
qw/aa/
],
],
},
)->
select
(
-columns
=>
'x'
,
-from
=>
'nodes'
,
);
is_same_sql_bind(
$sql
, \
@bind
,
q{WITH RECURSIVE nodes(x) AS ( SELECT 59 FROM DUAL
UNION ALL SELECT aa FROM edge INNER JOIN nodes ON edge.bb=nodes.x)
SELECT x FROM nodes}
,
[],
"1-branch graph retrieval"
,
);
(
$sql
,
@bind
) =
$sqla
->with_recursive(
-table
=>
'nodes'
,
-columns
=> [
qw/x/
],
-as_select
=> {
-from
=>
'DUAL'
,
-columns
=> [
qw/59/
],
-union_all
=> [
-from
=> [
-join
=>
qw/edge {bb=x} nodes/
],
-columns
=> [
qw/aa/
],
-union_all
=> [
-from
=> [
-join
=>
qw/edge {aa=x} nodes/
],
-columns
=> [
qw/bb/
]],
],
},
)->
select
(
-columns
=>
'x'
,
-from
=>
'nodes'
,
);
is_same_sql_bind(
$sql
, \
@bind
,
q{WITH RECURSIVE nodes(x) AS ( SELECT 59 FROM DUAL
UNION ALL SELECT aa FROM edge INNER JOIN nodes ON edge.bb=nodes.x
UNION ALL SELECT bb FROM edge INNER JOIN nodes ON edge.aa=nodes.x)
SELECT x FROM nodes}
,
[],
"2-branch graph retrieval"
,
);
(
$sql
,
@bind
) =
$sqla
->with_recursive(
[
-table
=>
'parent_of'
,
-columns
=> [
qw/name parent/
],
-as_select
=> {
-columns
=> [
qw/name mom/
],
-from
=>
'family'
,
-where
=> {
age
=> {
'>'
=> 16.1}},
-union
=> [
-columns
=> [
qw/name dad/
],
-where
=> {
age
=> {
'>'
=> 16.2}},
-from
=>
'family'
]},
],
[
-table
=>
'ancestor_of_alice'
,
-columns
=> [
qw/name/
],
-as_select
=> {
-columns
=> [
qw/parent/
],
-from
=>
'parent_of'
,
-where
=> {
name
=>
'Alice'
},
-union_all
=> [
-columns
=> [
qw/parent/
],
-from
=> [
qw/-join parent_of {name} ancestor_of_alice/
]],
},
],
)->
select
(
-columns
=>
'family.name'
,
-from
=> [
qw/-join ancestor_of_alice {name} family/
],
-where
=> {
died
=>
undef
},
-order_by
=>
'born'
,
);
is_same_sql_bind(
$sql
, \
@bind
,
q{WITH RECURSIVE
parent_of(name, parent) AS
(SELECT name, mom FROM family WHERE age > ?
UNION SELECT name, dad FROM family WHERE age > ?),
ancestor_of_alice(name) AS
(SELECT parent FROM parent_of WHERE name = ?
UNION ALL
SELECT parent FROM parent_of INNER JOIN ancestor_of_alice USING(name))
SELECT family.name FROM ancestor_of_alice INNER JOIN family USING(name)
WHERE died IS NULL
ORDER BY born}
,
[16.1, 16.2,
'Alice'
],
"several CTEs in the same WITH clause"
,
);
my
$sqla2
=
$sqla
->with_recursive(
-table
=>
'nodes'
,
-columns
=> [
qw/x/
],
-as_select
=> {
-from
=>
'DUAL'
,
-columns
=> [
qw/59/
],
-union_all
=> [
-from
=> [
-join
=>
qw/edge {bb=x} nodes/
],
-columns
=> [
qw/aa/
],
],
},
);
(
$sql
,
@bind
) =
$sqla2
->insert(
-into
=>
"edge"
,
-columns
=> [
'aa'
],
-select
=> {
-columns
=>
'x'
,
-from
=>
"nodes"
},
);
is_same_sql_bind(
$sql
, \
@bind
,
q{WITH RECURSIVE nodes(x) AS ( SELECT 59 FROM DUAL
UNION ALL SELECT aa FROM edge INNER JOIN nodes ON edge.bb=nodes.x)
INSERT INTO edge(aa) SELECT x FROM nodes}
,
[],
"insert"
,
);
my
@subquery
=
$sqla
->
select
(
-columns
=>
'x'
,
-from
=>
"nodes"
);
(
$sql
,
@bind
) =
$sqla2
->update(
-table
=>
"edge"
,
-set
=> {
foo
=>
"bar"
},
-where
=> {
aa
=> {
-in
=> \\
@subquery
}}
);
is_same_sql_bind(
$sql
, \
@bind
,
q{WITH RECURSIVE nodes(x) AS ( SELECT 59 FROM DUAL
UNION ALL SELECT aa FROM edge INNER JOIN nodes ON edge.bb=nodes.x)
UPDATE edge SET foo = ?
WHERE aa IN (SELECT x FROM nodes)}
,
[
"bar"
],
"update"
,
);
(
$sql
,
@bind
) =
$sqla2
->
delete
(
-from
=>
"edge"
,
-where
=> {
aa
=> {
-in
=> \\
@subquery
}}
);
is_same_sql_bind(
$sql
, \
@bind
,
q{WITH RECURSIVE nodes(x) AS ( SELECT 59 FROM DUAL
UNION ALL SELECT aa FROM edge INNER JOIN nodes ON edge.bb=nodes.x)
DELETE FROM edge
WHERE aa IN (SELECT x FROM nodes)}
,
[],
"delete"
,
);
(
$sql
,
@bind
) =
$sqla
->with_recursive(
-table
=>
'nodes'
,
-columns
=> [
qw/x/
],
-as_select
=> {
-from
=>
'DUAL'
,
-columns
=> [
qw/59/
],
-union_all
=> [
-from
=> [
-join
=>
qw/edge {bb=x} nodes/
],
-columns
=> [
qw/aa/
],
],
},
-final_clause
=>
"CYCLE x SET is_cycle TO '1' DEFAULT '0'"
,
)->
select
(
-columns
=>
'x'
,
-from
=>
'nodes'
,
);
is_same_sql_bind(
$sql
, \
@bind
,
q{WITH RECURSIVE nodes(x) AS ( SELECT 59 FROM DUAL
UNION ALL SELECT aa FROM edge INNER JOIN nodes ON edge.bb=nodes.x)
CYCLE x SET is_cycle TO '1' DEFAULT '0'
SELECT x FROM nodes}
,
[],
"-final_clause"
,
);
(
$sql
,
@bind
) =
$sqla2
->
select
(
-columns
=> [
qw/a b/
],
-from
=>
"Foo"
,
-union
=> [
-columns
=> [
qw/c d/
],
-from
=>
'Bar'
]
);
is_same_sql_bind(
$sql
, \
@bind
,
q{WITH RECURSIVE nodes(x) AS ( SELECT 59 FROM DUAL
UNION ALL SELECT aa FROM edge INNER JOIN nodes ON edge.bb=nodes.x)
SELECT a, b FROM Foo UNION SELECT c, d FROM Bar}
,
[],
"subquery - union"
);
(
$sql
,
@bind
) =
$sqla2
->
select
(
-columns
=> [
qw/a count(*)/
],
-from
=>
"Foo"
,
-group_by
=>
"a"
,
-having
=> {
"count(*)"
=> {
">"
=> 1}},
);
is_same_sql_bind(
$sql
, \
@bind
,
q{WITH RECURSIVE nodes(x) AS ( SELECT 59 FROM DUAL
UNION ALL SELECT aa FROM edge INNER JOIN nodes ON edge.bb=nodes.x)
SELECT a, count(*) FROM Foo GROUP BY a HAVING count(*) > ?}
,
[1],
"subquery - group by"
);
done_testing();