github.com/vescale/zgraph@v0.0.0-20230410094002-959c02d50f95/parser/parser_test.go (about) 1 package parser_test 2 3 import ( 4 "fmt" 5 "strings" 6 "testing" 7 8 "github.com/stretchr/testify/require" 9 "github.com/vescale/zgraph/parser" 10 "github.com/vescale/zgraph/parser/format" 11 ) 12 13 type testCase struct { 14 src string 15 ok bool 16 restore string 17 } 18 19 func TestQuery(t *testing.T) { 20 table := []testCase{ 21 {"SELECT label(n) AS lbl, COUNT(*) FROM MATCH (n) GROUP BY lbl ORDER BY COUNT(*) DESC", true, "SELECT LABEL(`n`) AS `lbl`,COUNT(1) FROM MATCH (`n`) GROUP BY `lbl` ORDER BY COUNT(1) DESC"}, 22 {`SELECT label(n) AS srcLbl, label(e) AS edgeLbl, label(m) AS dstLbl, COUNT(*) 23 FROM MATCH (n) -[e]-> (m) 24 GROUP BY srcLbl, edgeLbl, dstLbl 25 ORDER BY COUNT(*) DESC`, true, "SELECT LABEL(`n`) AS `srcLbl`,LABEL(`e`) AS `edgeLbl`,LABEL(`m`) AS `dstLbl`,COUNT(1) FROM MATCH (`n`) -[`e`]-> (`m`) GROUP BY `srcLbl`,`edgeLbl`,`dstLbl` ORDER BY COUNT(1) DESC"}, 26 {"SELECT n.name, n.dob FROM MATCH (n:Person)", true, "SELECT `n`.`name`,`n`.`dob` FROM MATCH (`n`:`Person`)"}, 27 {"SELECT a.name AS a, b.name AS b FROM MATCH (a:Person) -[e:knows]-> (b:Person)", true, "SELECT `a`.`name` AS `a`,`b`.`name` AS `b` FROM MATCH (`a`:`Person`) -[`e`:`knows`]-> (`b`:`Person`)"}, 28 {"SELECT n.name, n.dob FROM MATCH (n:Person|University)", true, "SELECT `n`.`name`,`n`.`dob` FROM MATCH (`n`:`Person`|`University`)"}, 29 {"SELECT n.name, n.dob FROM MATCH (n)", true, "SELECT `n`.`name`,`n`.`dob` FROM MATCH (`n`)"}, 30 {"SELECT n.name, n.dob FROM MATCH (n) WHERE n.dob > DATE '1995-01-01'", true, "SELECT `n`.`name`,`n`.`dob` FROM MATCH (`n`) WHERE `n`.`dob`>DATE '1995-01-01'"}, 31 {"SELECT m.name AS name, m.dob AS dob FROM MATCH (n) -[e]-> (m) WHERE n.name = 'Kathrine' AND n.dob <= m.dob", true, "SELECT `m`.`name` AS `name`,`m`.`dob` AS `dob` FROM MATCH (`n`) -[`e`]-> (`m`) WHERE `n`.`name`='Kathrine' AND `n`.`dob`<=`m`.`dob`"}, 32 {"SELECT p2.name AS friend, u.name AS university FROM MATCH (u:University) <-[:studentOf]- (p1:Person) -[:knows]-> (p2:Person) -[:studentOf]-> (u) WHERE p1.name = 'Lee'", true, "SELECT `p2`.`name` AS `friend`,`u`.`name` AS `university` FROM MATCH (`u`:`University`) <-[:`studentOf`]- (`p1`:`Person`) -[:`knows`]-> (`p2`:`Person`) -[:`studentOf`]-> (`u`) WHERE `p1`.`name`='Lee'"}, 33 {`SELECT p2.name AS friend, u.name AS university 34 FROM MATCH (p1:Person) -[:knows]-> (p2:Person) 35 , MATCH (p1) -[:studentOf]-> (u:University) 36 , MATCH (p2) -[:studentOf]-> (u) 37 WHERE p1.name = 'Lee'`, true, "SELECT `p2`.`name` AS `friend`,`u`.`name` AS `university` FROM MATCH (`p1`:`Person`) -[:`knows`]-> (`p2`:`Person`),MATCH (`p1`) -[:`studentOf`]-> (`u`:`University`),MATCH (`p2`) -[:`studentOf`]-> (`u`) WHERE `p1`.`name`='Lee'"}, 38 {`SELECT p1.name AS p1, p2.name AS p2, p3.name AS p3 39 FROM MATCH (p1:Person) -[:knows]-> (p2:Person) -[:knows]-> (p3:Person) 40 WHERE p1.name = 'Lee'`, true, "SELECT `p1`.`name` AS `p1`,`p2`.`name` AS `p2`,`p3`.`name` AS `p3` FROM MATCH (`p1`:`Person`) -[:`knows`]-> (`p2`:`Person`) -[:`knows`]-> (`p3`:`Person`) WHERE `p1`.`name`='Lee'"}, 41 {`SELECT p1.name AS p1, p2.name AS p2, p3.name AS p3 42 FROM MATCH (p1:Person) -[:knows]-> (p2:Person) -[:knows]-> (p3:Person) 43 WHERE p1.name = 'Lee' AND p1 <> p3`, true, "SELECT `p1`.`name` AS `p1`,`p2`.`name` AS `p2`,`p3`.`name` AS `p3` FROM MATCH (`p1`:`Person`) -[:`knows`]-> (`p2`:`Person`) -[:`knows`]-> (`p3`:`Person`) WHERE `p1`.`name`='Lee' AND `p1`<>`p3`"}, 44 {`SELECT p1.name AS p1, p2.name AS p2, p3.name AS p3 45 FROM MATCH (p1:Person) -[:knows]-> (p2:Person) -[:knows]-> (p3:Person) 46 WHERE p1.name = 'Lee' AND ALL_DIFFERENT(p1, p3)`, true, "SELECT `p1`.`name` AS `p1`,`p2`.`name` AS `p2`,`p3`.`name` AS `p3` FROM MATCH (`p1`:`Person`) -[:`knows`]-> (`p2`:`Person`) -[:`knows`]-> (`p3`:`Person`) WHERE `p1`.`name`='Lee' AND ALL_DIFFERENT(`p1`, `p3`)"}, 47 {`SELECT p1.name AS p1, p2.name AS p2, e1 = e2 48 FROM MATCH (p1:Person) -[e1:knows]-> (riya:Person) 49 , MATCH (p2:Person) -[e2:knows]-> (riya) 50 WHERE riya.name = 'Riya'`, true, "SELECT `p1`.`name` AS `p1`,`p2`.`name` AS `p2`,`e1`=`e2` FROM MATCH (`p1`:`Person`) -[`e1`:`knows`]-> (`riya`:`Person`),MATCH (`p2`:`Person`) -[`e2`:`knows`]-> (`riya`) WHERE `riya`.`name`='Riya'"}, 51 {"SELECT * FROM MATCH (n) -[e1]- (m) -[e2]- (o)", true, "SELECT * FROM MATCH (`n`) -[`e1`]- (`m`) -[`e2`]- (`o`)"}, 52 {"SELECT n, m, n.age AS age FROM MATCH (n:Person) -[e:friend_of]-> (m:Person)", true, "SELECT `n`,`m`,`n`.`age` AS `age` FROM MATCH (`n`:`Person`) -[`e`:`friend_of`]-> (`m`:`Person`)"}, 53 {"SELECT n.age * 2 - 1 AS pivot, n.name, n FROM MATCH (n:Person) -> (m:Car) ORDER BY pivot", true, "SELECT `n`.`age`*2-1 AS `pivot`,`n`.`name`,`n` FROM MATCH (`n`:`Person`) -> (`m`:`Car`) ORDER BY `pivot`"}, 54 {"SELECT * FROM MATCH (n:Person) -> (m) -> (w), MATCH (n) -> (w) -> (m)", true, "SELECT * FROM MATCH (`n`:`Person`) -> (`m`) -> (`w`),MATCH (`n`) -> (`w`) -> (`m`)"}, 55 {"SELECT n, m, w FROM MATCH (n:Person) -> (m) -> (w), MATCH (n) -> (w) -> (m)", true, "SELECT `n`,`m`,`w` FROM MATCH (`n`:`Person`) -> (`m`) -> (`w`),MATCH (`n`) -> (`w`) -> (`m`)"}, 56 {`SELECT p.first_name, p.last_name 57 FROM MATCH (p:Person) ON my_graph 58 ORDER BY p.first_name, p.last_name`, true, "SELECT `p`.`first_name`,`p`.`last_name` FROM MATCH (`p`:`Person`) ON `my_graph` ORDER BY `p`.`first_name`,`p`.`last_name`"}, 59 {"SELECT p.first_name, p.last_name FROM MATCH (p:Person) ORDER BY p.first_name, p.last_name", true, "SELECT `p`.`first_name`,`p`.`last_name` FROM MATCH (`p`:`Person`) ORDER BY `p`.`first_name`,`p`.`last_name`"}, 60 {"SELECT * FROM MATCH (n) -[e1]-> (m1), MATCH (n) -[e2]-> (m2)", true, "SELECT * FROM MATCH (`n`) -[`e1`]-> (`m1`),MATCH (`n`) -[`e2`]-> (`m2`)"}, 61 {"SELECT * FROM MATCH (n1) -[e1]-> (n2) -[e2]-> (n3) -[e3]-> (n4)", true, "SELECT * FROM MATCH (`n1`) -[`e1`]-> (`n2`) -[`e2`]-> (`n3`) -[`e3`]-> (`n4`)"}, 62 {"SELECT * FROM MATCH (n1) -[e1]-> (n2), MATCH (n2) -[e2]-> (n3), MATCH (n3) -[e3]-> (n4)", true, "SELECT * FROM MATCH (`n1`) -[`e1`]-> (`n2`),MATCH (`n2`) -[`e2`]-> (`n3`),MATCH (`n3`) -[`e3`]-> (`n4`)"}, 63 {"SELECT * FROM MATCH (n1) -[e1]-> (n2) <-[e2]- (n3)", true, "SELECT * FROM MATCH (`n1`) -[`e1`]-> (`n2`) <-[`e2`]- (`n3`)"}, 64 {"SELECT * FROM MATCH (n1) -> (m1), MATCH (n2) -> (m2)", true, "SELECT * FROM MATCH (`n1`) -> (`m1`),MATCH (`n2`) -> (`m2`)"}, 65 {"SELECT * FROM MATCH (x:Person) -[e:likes|knows]-> (y:Person)", true, "SELECT * FROM MATCH (`x`:`Person`) -[`e`:`likes`|`knows`]-> (`y`:`Person`)"}, 66 {"SELECT * FROM MATCH (:Person) -[:likes|knows]-> (:Person)", true, "SELECT * FROM MATCH (:`Person`) -[:`likes`|`knows`]-> (:`Person`)"}, 67 {"SELECT y.name FROM MATCH (x) -> (y) WHERE x.name = 'Jake' AND y.age > 25", true, "SELECT `y`.`name` FROM MATCH (`x`) -> (`y`) WHERE `x`.`name`='Jake' AND `y`.`age`>25"}, 68 {"SELECT y.name FROM MATCH (x) -> (y) WHERE y.age > 25 AND x.name = 'Jake'", true, "SELECT `y`.`name` FROM MATCH (`x`) -> (`y`) WHERE `y`.`age`>25 AND `x`.`name`='Jake'"}, 69 {"SELECT n.first_name, COUNT(*), AVG(n.age) FROM MATCH (n:Person) GROUP BY n.first_name", true, "SELECT `n`.`first_name`,COUNT(1),AVG(`n`.`age`) FROM MATCH (`n`:`Person`) GROUP BY `n`.`first_name`"}, 70 {"SELECT n.first_name, n.last_name, COUNT(*) FROM MATCH (n:Person) GROUP BY n.first_name, n.last_name", true, "SELECT `n`.`first_name`,`n`.`last_name`,COUNT(1) FROM MATCH (`n`:`Person`) GROUP BY `n`.`first_name`,`n`.`last_name`"}, 71 {`SELECT n.prop1, n.prop2, COUNT(*) 72 FROM MATCH (n) 73 GROUP BY n.prop1, n.prop2 74 HAVING n.prop1 IS NOT NULL AND n.prop2 IS NOT NULL`, true, "SELECT `n`.`prop1`,`n`.`prop2`,COUNT(1) FROM MATCH (`n`) GROUP BY `n`.`prop1`,`n`.`prop2` HAVING `n`.`prop1` IS NOT NULL AND `n`.`prop2` IS NOT NULL"}, 75 {" SELECT n.age, COUNT(*) FROM MATCH (n) GROUP BY n.age ORDER BY n.age", true, "SELECT `n`.`age`,COUNT(1) FROM MATCH (`n`) GROUP BY `n`.`age` ORDER BY `n`.`age`"}, 76 {`SELECT label(owner), 77 COUNT(*) AS numTransactions, 78 SUM(out.amount) AS totalOutgoing, 79 LISTAGG(out.amount, ', ') AS amounts 80 FROM MATCH (a:Account) -[:owner]-> (owner:Person|Company) 81 , MATCH (a) -[out:transaction]-> (:Account) 82 GROUP BY label(owner) 83 ORDER BY label(owner)`, true, "SELECT LABEL(`owner`),COUNT(1) AS `numTransactions`,SUM(`out`.`amount`) AS `totalOutgoing`,LISTAGG(`out`.`amount`, ', ') AS `amounts` FROM MATCH (`a`:`Account`) -[:`owner`]-> (`owner`:`Person`|`Company`),MATCH (`a`) -[`out`:`transaction`]-> (:`Account`) GROUP BY LABEL(`owner`) ORDER BY LABEL(`owner`)"}, 84 {`SELECT COUNT(*) AS numTransactions, 85 SUM(out.amount) AS totalOutgoing, 86 LISTAGG(out.amount, ', ') AS amounts 87 FROM MATCH (a:Account) -[:owner]-> (owner:Person|Company) 88 , MATCH (a) -[out:transaction]-> (:Account)`, true, "SELECT COUNT(1) AS `numTransactions`,SUM(`out`.`amount`) AS `totalOutgoing`,LISTAGG(`out`.`amount`, ', ') AS `amounts` FROM MATCH (`a`:`Account`) -[:`owner`]-> (`owner`:`Person`|`Company`),MATCH (`a`) -[`out`:`transaction`]-> (:`Account`)"}, 89 {"SELECT COUNT(*) FROM MATCH (m:Person)", true, "SELECT COUNT(1) FROM MATCH (`m`:`Person`)"}, 90 {"SELECT AVG(DISTINCT m.age) FROM MATCH (m:Person)", true, "SELECT AVG(DISTINCT `m`.`age`) FROM MATCH (`m`:`Person`)"}, 91 {"SELECT n.name FROM MATCH (n) -[:has_friend]-> (m) GROUP BY n HAVING COUNT(m) > 10", true, "SELECT `n`.`name` FROM MATCH (`n`) -[:`has_friend`]-> (`m`) GROUP BY `n` HAVING COUNT(`m`)>10"}, 92 {"SELECT n.name FROM MATCH (n:Person) ORDER BY n.age ASC", true, "SELECT `n`.`name` FROM MATCH (`n`:`Person`) ORDER BY `n`.`age` ASC"}, 93 {"SELECT f.name FROM MATCH (f:Person) ORDER BY f.age ASC, f.salary DESC", true, "SELECT `f`.`name` FROM MATCH (`f`:`Person`) ORDER BY `f`.`age` ASC,`f`.`salary` DESC"}, 94 {"SELECT n FROM MATCH (n) LIMIT 10 OFFSET 5", true, "SELECT `n` FROM MATCH (`n`) LIMIT 5,10"}, 95 {`SELECT a.number AS a, 96 b.number AS b, 97 COUNT(e) AS pathLength, 98 ARRAY_AGG(e.amount) AS amounts 99 FROM MATCH ANY SHORTEST (a:Account) -[e:transaction]->* (b:Account) 100 WHERE a.number = 10039 AND b.number = 2090`, true, "SELECT `a`.`number` AS `a`,`b`.`number` AS `b`,COUNT(`e`) AS `pathLength`,ARRAY_AGG(`e`.`amount`) AS `amounts` FROM MATCH ANY SHORTEST (`a`:`Account`) -[`e`:`transaction`]->* (`b`:`Account`) WHERE `a`.`number`=10039 AND `b`.`number`=2090"}, 101 {`SELECT dst.number 102 FROM MATCH ANY (src:Account) -[e]->+ (dst:Account) 103 WHERE src.number = 8021 104 ORDER BY dst.number`, true, "SELECT `dst`.`number` FROM MATCH ANY (`src`:`Account`) -[`e`]->+ (`dst`:`Account`) WHERE `src`.`number`=8021 ORDER BY `dst`.`number`"}, 105 {`SELECT dst.number, LISTAGG(e.amount, ' + ') || ' = ', SUM(e.amount) 106 FROM MATCH ANY (src:Account) -[e]->+ (dst:Account) 107 WHERE src.number = 8021 108 ORDER BY dst.number`, true, "SELECT `dst`.`number`,LISTAGG(`e`.`amount`, ' + ')||' = ',SUM(`e`.`amount`) FROM MATCH ANY (`src`:`Account`) -[`e`]->+ (`dst`:`Account`) WHERE `src`.`number`=8021 ORDER BY `dst`.`number`"}, 109 {`SELECT c.name 110 FROM MATCH (c:Class) -/:subclass_of*/-> (arrayList:Class) 111 WHERE arrayList.name = 'ArrayList'`, true, "SELECT `c`.`name` FROM MATCH (`c`:`Class`) -/:`subclass_of`*/-> (`arrayList`:`Class`) WHERE `arrayList`.`name`='ArrayList'"}, 112 {`SELECT y.name 113 FROM MATCH (x:Person) -/:likes*/-> (y) 114 WHERE x.name = 'Amy'`, true, "SELECT `y`.`name` FROM MATCH (`x`:`Person`) -/:`likes`*/-> (`y`) WHERE `x`.`name`='Amy'"}, 115 {`SELECT y.name 116 FROM MATCH (x:Person) -/:likes+/-> (y) 117 WHERE x.name = 'Amy'`, true, "SELECT `y`.`name` FROM MATCH (`x`:`Person`) -/:`likes`+/-> (`y`) WHERE `x`.`name`='Amy'"}, 118 {`SELECT y.name 119 FROM MATCH (x:Person) -/:knows+/-> (y) 120 WHERE x.name = 'Judith'`, true, "SELECT `y`.`name` FROM MATCH (`x`:`Person`) -/:`knows`+/-> (`y`) WHERE `x`.`name`='Judith'"}, 121 {`SELECT y.name 122 FROM MATCH (x:Person) -/:knows?/-> (y) 123 WHERE x.name = 'Judith'`, true, "SELECT `y`.`name` FROM MATCH (`x`:`Person`) -/:`knows`?/-> (`y`) WHERE `x`.`name`='Judith'"}, 124 {`SELECT y.name 125 FROM MATCH (x:Person) -/:likes{2}/-> (y) 126 WHERE x.name = 'Amy'`, true, "SELECT `y`.`name` FROM MATCH (`x`:`Person`) -/:`likes`{2}/-> (`y`) WHERE `x`.`name`='Amy'"}, 127 {`SELECT y.name 128 FROM MATCH (x:Person) -/:likes{2,}/-> (y) 129 WHERE x.name = 'Amy'`, true, "SELECT `y`.`name` FROM MATCH (`x`:`Person`) -/:`likes`{2,}/-> (`y`) WHERE `x`.`name`='Amy'"}, 130 {`SELECT y.name 131 FROM MATCH (x:Person) -/:likes{1,2}/-> (y) 132 WHERE x.name = 'Amy'`, true, "SELECT `y`.`name` FROM MATCH (`x`:`Person`) -/:`likes`{1,2}/-> (`y`) WHERE `x`.`name`='Amy'"}, 133 {`SELECT y.name 134 FROM MATCH (x:Person) -/:knows{,2}/-> (y) 135 WHERE x.name = 'Judith'`, true, "SELECT `y`.`name` FROM MATCH (`x`:`Person`) -/:`knows`{,2}/-> (`y`) WHERE `x`.`name`='Judith'"}, 136 {`SELECT src, SUM(e.weight), dst 137 FROM MATCH ANY SHORTEST (src) -[e]->* (dst) 138 WHERE src.age < dst.age`, true, "SELECT `src`,SUM(`e`.`weight`),`dst` FROM MATCH ANY SHORTEST (`src`) -[`e`]->* (`dst`) WHERE `src`.`age`<`dst`.`age`"}, 139 {`SELECT src, ARRAY_AGG(e.weight), dst 140 FROM MATCH ANY SHORTEST (src) (-[e]-> WHERE e.weight > 10)* (dst)`, true, "SELECT `src`,ARRAY_AGG(`e`.`weight`),`dst` FROM MATCH ANY SHORTEST (`src`) (-[`e`]-> WHERE `e`.`weight`>10)* (`dst`)"}, 141 {`SELECT src, ARRAY_AGG(e.weight), dst 142 FROM MATCH ANY SHORTEST (src) -[e]->* (dst) WHERE SUM(e.cost) < 100`, true, "SELECT `src`,ARRAY_AGG(`e`.`weight`),`dst` FROM MATCH ANY SHORTEST (`src`) -[`e`]->* (`dst`) WHERE SUM(`e`.`cost`)<100"}, 143 {`SELECT LISTAGG(e.amount, ' + ') || ' = ', SUM(e.amount) AS total_amount 144 FROM MATCH ALL SHORTEST (a:Account) -[e:transaction]->* (b:Account) 145 WHERE a.number = 10039 AND b.number = 2090 146 ORDER BY total_amount`, true, "SELECT LISTAGG(`e`.`amount`, ' + ')||' = ',SUM(`e`.`amount`) AS `total_amount` FROM MATCH ALL SHORTEST (`a`:`Account`) -[`e`:`transaction`]->* (`b`:`Account`) WHERE `a`.`number`=10039 AND `b`.`number`=2090 ORDER BY `total_amount`"}, 147 {`SELECT src, SUM(e.weight), dst 148 FROM MATCH TOP 3 SHORTEST (src) -[e]->* (dst) 149 WHERE src.age < dst.age`, true, "SELECT `src`,SUM(`e`.`weight`),`dst` FROM MATCH TOP 3 SHORTEST (`src`) -[`e`]->* (`dst`) WHERE `src`.`age`<`dst`.`age`"}, 150 {`SELECT src, ARRAY_AGG(e.weight), ARRAY_AGG(v1.age), ARRAY_AGG(v2.age), dst 151 FROM MATCH TOP 3 SHORTEST (src) ((v1) -[e]-> (v2))* (dst) 152 WHERE src.age < dst.age`, true, "SELECT `src`,ARRAY_AGG(`e`.`weight`),ARRAY_AGG(`v1`.`age`),ARRAY_AGG(`v2`.`age`),`dst` FROM MATCH TOP 3 SHORTEST (`src`) ((`v1`) -[`e`]-> (`v2`))* (`dst`) WHERE `src`.`age`<`dst`.`age`"}, 153 {`SELECT ARRAY_AGG(e1.weight), ARRAY_AGG(e2.weight) 154 FROM MATCH (start) -> (src) 155 , MATCH TOP 3 SHORTEST (src) (-[e1]->)* (mid) 156 , MATCH ANY SHORTEST (mid) (-[e2]->)* (dst) 157 , MATCH (dst) -> (end)`, true, "SELECT ARRAY_AGG(`e1`.`weight`),ARRAY_AGG(`e2`.`weight`) FROM MATCH (`start`) -> (`src`),MATCH TOP 3 SHORTEST (`src`) -[`e1`]->* (`mid`),MATCH ANY SHORTEST (`mid`) -[`e2`]->* (`dst`),MATCH (`dst`) -> (`end`)"}, 158 {`SELECT COUNT(e) AS num_hops 159 , SUM(e.amount) AS total_amount 160 , ARRAY_AGG(e.amount) AS amounts_along_path 161 FROM MATCH TOP 7 SHORTEST (a:Account) -[e:transaction]->* (b:Account) 162 WHERE a.number = 10039 AND a = b 163 ORDER BY num_hops, total_amount`, true, "SELECT COUNT(`e`) AS `num_hops`,SUM(`e`.`amount`) AS `total_amount`,ARRAY_AGG(`e`.`amount`) AS `amounts_along_path` FROM MATCH TOP 7 SHORTEST (`a`:`Account`) -[`e`:`transaction`]->* (`b`:`Account`) WHERE `a`.`number`=10039 AND `a`=`b` ORDER BY `num_hops`,`total_amount`"}, 164 {`SELECT COUNT(e) AS num_hops 165 , SUM(e.amount) AS total_amount 166 , ARRAY_AGG(e.amount) AS amounts_along_path 167 FROM MATCH TOP 7 SHORTEST (a:Account) -[e:transaction]->* (b:Account) 168 WHERE a.number = 10039 AND a = b AND COUNT(DISTINCT e) = COUNT(e) AND COUNT(e) > 0 169 ORDER BY num_hops, total_amount`, true, "SELECT COUNT(`e`) AS `num_hops`,SUM(`e`.`amount`) AS `total_amount`,ARRAY_AGG(`e`.`amount`) AS `amounts_along_path` FROM MATCH TOP 7 SHORTEST (`a`:`Account`) -[`e`:`transaction`]->* (`b`:`Account`) WHERE `a`.`number`=10039 AND `a`=`b` AND COUNT(DISTINCT `e`)=COUNT(`e`) AND COUNT(`e`)>0 ORDER BY `num_hops`,`total_amount`"}, 170 {`SELECT COUNT(e) AS num_hops 171 , SUM(e.amount) AS total_amount 172 , ARRAY_AGG(e.amount) AS amounts_along_path 173 FROM MATCH ANY CHEAPEST (a:Account) (-[e:transaction]-> COST e.amount)* (b:Account) 174 WHERE a.number = 10039 AND b.number = 2090`, true, "SELECT COUNT(`e`) AS `num_hops`,SUM(`e`.`amount`) AS `total_amount`,ARRAY_AGG(`e`.`amount`) AS `amounts_along_path` FROM MATCH ANY CHEAPEST (`a`:`Account`) (-[`e`:`transaction`]-> COST `e`.`amount`)* (`b`:`Account`) WHERE `a`.`number`=10039 AND `b`.`number`=2090"}, 175 {`SELECT COUNT(e) AS num_hops 176 , SUM(e.amount) AS total_amount 177 , ARRAY_AGG(e.amount) AS amounts_along_path 178 FROM MATCH ANY CHEAPEST (a:Account) (-[e:transaction]- COST e.amount)* (b:Account) 179 WHERE a.number = 10039 AND b.number = 2090`, true, "SELECT COUNT(`e`) AS `num_hops`,SUM(`e`.`amount`) AS `total_amount`,ARRAY_AGG(`e`.`amount`) AS `amounts_along_path` FROM MATCH ANY CHEAPEST (`a`:`Account`) (-[`e`:`transaction`]- COST `e`.`amount`)* (`b`:`Account`) WHERE `a`.`number`=10039 AND `b`.`number`=2090"}, 180 {`SELECT COUNT(e) AS num_hops 181 , SUM(e.amount) AS total_amount 182 , ARRAY_AGG(e.amount) AS amounts_along_path 183 FROM MATCH ANY CHEAPEST (p1:Person) (-[e:owner|transaction]- 184 COST CASE 185 WHEN e.amount IS NULL THEN 1 186 ELSE e.amount 187 END)* (p2:Person) 188 WHERE p1.name = 'Nikita' AND p2.name = 'Liam'`, true, "SELECT COUNT(`e`) AS `num_hops`,SUM(`e`.`amount`) AS `total_amount`,ARRAY_AGG(`e`.`amount`) AS `amounts_along_path` FROM MATCH ANY CHEAPEST (`p1`:`Person`) (-[`e`:`owner`|`transaction`]- COST CASE WHEN `e`.`amount` IS NULL THEN 1 ELSE `e`.`amount` END)* (`p2`:`Person`) WHERE `p1`.`name`='Nikita' AND `p2`.`name`='Liam'"}, 189 {`SELECT COUNT(e) AS num_hops 190 , SUM(e.amount) AS total_amount 191 , ARRAY_AGG(e.amount) AS amounts_along_path 192 FROM MATCH TOP 3 CHEAPEST (a:Account) (-[e:transaction]-> COST e.amount)* (a) 193 WHERE a.number = 10039 194 ORDER BY total_amount`, true, "SELECT COUNT(`e`) AS `num_hops`,SUM(`e`.`amount`) AS `total_amount`,ARRAY_AGG(`e`.`amount`) AS `amounts_along_path` FROM MATCH TOP 3 CHEAPEST (`a`:`Account`) (-[`e`:`transaction`]-> COST `e`.`amount`)* (`a`) WHERE `a`.`number`=10039 ORDER BY `total_amount`"}, 195 {`SELECT COUNT(e) AS num_hops 196 , ARRAY_AGG( CASE label(n_x) 197 WHEN 'Person' THEN n_x.name 198 WHEN 'Company' THEN n_x.name 199 WHEN 'Account' THEN CAST(n_x.number AS STRING) 200 END ) AS names_or_numbers 201 , SUM( CASE label(n_x) WHEN 'Person' THEN 8 ELSE 1 END ) AS total_cost 202 FROM MATCH TOP 4 CHEAPEST 203 (a:Account) 204 (-[e]- (n_x) COST CASE label(n_x) WHEN 'Person' THEN 3 ELSE 1 END)* 205 (c:Company) 206 WHERE a.number = 10039 AND c.name = 'Oracle' 207 ORDER BY total_cost`, true, "SELECT COUNT(`e`) AS `num_hops`,ARRAY_AGG(CASE LABEL(`n_x`) WHEN 'Person' THEN `n_x`.`name` WHEN 'Company' THEN `n_x`.`name` WHEN 'Account' THEN CAST(`n_x`.`number` AS STRING) END) AS `names_or_numbers`,SUM(CASE LABEL(`n_x`) WHEN 'Person' THEN 8 ELSE 1 END) AS `total_cost` FROM MATCH TOP 4 CHEAPEST (`a`:`Account`) (-[`e`]- (`n_x`) COST CASE LABEL(`n_x`) WHEN 'Person' THEN 3 ELSE 1 END)* (`c`:`Company`) WHERE `a`.`number`=10039 AND `c`.`name`='Oracle' ORDER BY `total_cost`"}, 208 {`SELECT LISTAGG(e.amount, ' + ') || ' = ', SUM(e.amount) AS total_amount 209 FROM MATCH ALL (a:Account) -[e:transaction]->{,7} (b:Account) 210 WHERE a.number = 10039 AND b.number = 2090 211 ORDER BY total_amount`, true, "SELECT LISTAGG(`e`.`amount`, ' + ')||' = ',SUM(`e`.`amount`) AS `total_amount` FROM MATCH ALL (`a`:`Account`) -[`e`:`transaction`]->{,7} (`b`:`Account`) WHERE `a`.`number`=10039 AND `b`.`number`=2090 ORDER BY `total_amount`"}, 212 {`SELECT SUM(COUNT(e)) AS sumOfPathLengths 213 FROM MATCH ANY SHORTEST (a:Account) -[e:transaction]->* (b:Account) 214 WHERE a.number = 10039 AND (b.number = 1001 OR b.number = 2090)`, true, "SELECT SUM(COUNT(`e`)) AS `sumOfPathLengths` FROM MATCH ANY SHORTEST (`a`:`Account`) -[`e`:`transaction`]->* (`b`:`Account`) WHERE `a`.`number`=10039 AND (`b`.`number`=1001 OR `b`.`number`=2090)"}, 215 {`SELECT b.number AS b, 216 COUNT(e) AS pathLength, 217 ARRAY_AGG(e.amount) AS transactions 218 FROM MATCH ANY SHORTEST (a:Account) -[e:transaction]->* (b:Account) 219 WHERE a.number = 10039 AND 220 (b.number = 8021 OR b.number = 1001 OR b.number = 2090) AND 221 COUNT(e) <= 2 222 ORDER BY pathLength`, true, "SELECT `b`.`number` AS `b`,COUNT(`e`) AS `pathLength`,ARRAY_AGG(`e`.`amount`) AS `transactions` FROM MATCH ANY SHORTEST (`a`:`Account`) -[`e`:`transaction`]->* (`b`:`Account`) WHERE `a`.`number`=10039 AND (`b`.`number`=8021 OR `b`.`number`=1001 OR `b`.`number`=2090) AND COUNT(`e`)<=2 ORDER BY `pathLength`"}, 223 {`SELECT COUNT(e) AS pathLength, 224 COUNT(*) AS cnt 225 FROM MATCH ANY SHORTEST (a:Account) -[e:transaction]->* (b:Account) 226 WHERE (a.number = 10039 OR a.number = 8021) AND 227 (b.number = 1001 OR b.number = 2090) 228 GROUP BY COUNT(e) 229 ORDER BY pathLength`, true, "SELECT COUNT(`e`) AS `pathLength`,COUNT(1) AS `cnt` FROM MATCH ANY SHORTEST (`a`:`Account`) -[`e`:`transaction`]->* (`b`:`Account`) WHERE (`a`.`number`=10039 OR `a`.`number`=8021) AND (`b`.`number`=1001 OR `b`.`number`=2090) GROUP BY COUNT(`e`) ORDER BY `pathLength`"}, 230 {`SELECT fof.name, COUNT(friend) AS num_common_friends 231 FROM MATCH (p:Person) -[:has_friend]-> (friend:Person) -[:has_friend]-> (fof:Person) 232 WHERE NOT EXISTS ( SELECT * FROM MATCH (p) -[:has_friend]-> (fof) )`, true, "SELECT `fof`.`name`,COUNT(`friend`) AS `num_common_friends` FROM MATCH (`p`:`Person`) -[:`has_friend`]-> (`friend`:`Person`) -[:`has_friend`]-> (`fof`:`Person`) WHERE NOT EXISTS (SELECT * FROM MATCH (`p`) -[:`has_friend`]-> (`fof`))"}, 233 {`SELECT a.name 234 FROM MATCH (a) 235 WHERE a.age > ( SELECT AVG(b.age) FROM MATCH (a) -[:friendOf]-> (b) )`, true, "SELECT `a`.`name` FROM MATCH (`a`) WHERE `a`.`age`>(SELECT AVG(`b`.`age`) FROM MATCH (`a`) -[:`friendOf`]-> (`b`))"}, 236 {`SELECT p.name AS name 237 , ( SELECT SUM(t.amount) 238 FROM MATCH (a) <-[t:transaction]- (:Account) 239 ON financial_transactions 240 ) AS sum_incoming 241 , ( SELECT SUM(t.amount) 242 FROM MATCH (a) -[t:transaction]-> (:Account) 243 ON financial_transactions 244 ) AS sum_outgoing 245 , ( SELECT COUNT(DISTINCT p2) 246 FROM MATCH (a) -[t:transaction]- (:Account) -[:owner]-> (p2:Person) 247 ON financial_transactions 248 WHERE p2 <> p 249 ) AS num_persons_transacted_with 250 , ( SELECT COUNT(DISTINCT c) 251 FROM MATCH (a) -[t:transaction]- (:Account) -[:owner]-> (c:Company) 252 ON financial_transactions 253 ) AS num_companies_transacted_with 254 FROM MATCH (p:Person) <-[:owner]- (a:Account) ON financial_transactions 255 ORDER BY sum_outgoing + sum_incoming DESC`, true, "SELECT `p`.`name` AS `name`,(SELECT SUM(`t`.`amount`) FROM MATCH (`a`) <-[`t`:`transaction`]- (:`Account`) ON `financial_transactions`) AS `sum_incoming`,(SELECT SUM(`t`.`amount`) FROM MATCH (`a`) -[`t`:`transaction`]-> (:`Account`) ON `financial_transactions`) AS `sum_outgoing`,(SELECT COUNT(DISTINCT `p2`) FROM MATCH (`a`) -[`t`:`transaction`]- (:`Account`) -[:`owner`]-> (`p2`:`Person`) ON `financial_transactions` WHERE `p2`<>`p`) AS `num_persons_transacted_with`,(SELECT COUNT(DISTINCT `c`) FROM MATCH (`a`) -[`t`:`transaction`]- (:`Account`) -[:`owner`]-> (`c`:`Company`) ON `financial_transactions`) AS `num_companies_transacted_with` FROM MATCH (`p`:`Person`) <-[:`owner`]- (`a`:`Account`) ON `financial_transactions` ORDER BY `sum_outgoing`+`sum_incoming` DESC"}, 256 {`SELECT p.name AS name 257 , ( SELECT SUM(t.amount) 258 FROM MATCH (a) <-[t:transaction]- (:Account) 259 ) AS sum_incoming 260 , ( SELECT SUM(t.amount) 261 FROM MATCH (a) -[t:transaction]-> (:Account) 262 ) AS sum_outgoing 263 , ( SELECT COUNT(DISTINCT p2) 264 FROM MATCH (a) -[t:transaction]- (:Account) -[:owner]-> (p2:Person) 265 WHERE p2 <> p 266 ) AS num_persons_transacted_with 267 , ( SELECT COUNT(DISTINCT c) 268 FROM MATCH (a) -[t:transaction]- (:Account) -[:owner]-> (c:Company) 269 ) AS num_companies_transacted_with 270 FROM MATCH (p:Person) <-[:owner]- (a:Account) 271 ORDER BY sum_outgoing + sum_incoming DESC`, true, "SELECT `p`.`name` AS `name`,(SELECT SUM(`t`.`amount`) FROM MATCH (`a`) <-[`t`:`transaction`]- (:`Account`)) AS `sum_incoming`,(SELECT SUM(`t`.`amount`) FROM MATCH (`a`) -[`t`:`transaction`]-> (:`Account`)) AS `sum_outgoing`,(SELECT COUNT(DISTINCT `p2`) FROM MATCH (`a`) -[`t`:`transaction`]- (:`Account`) -[:`owner`]-> (`p2`:`Person`) WHERE `p2`<>`p`) AS `num_persons_transacted_with`,(SELECT COUNT(DISTINCT `c`) FROM MATCH (`a`) -[`t`:`transaction`]- (:`Account`) -[:`owner`]-> (`c`:`Company`)) AS `num_companies_transacted_with` FROM MATCH (`p`:`Person`) <-[:`owner`]- (`a`:`Account`) ORDER BY `sum_outgoing`+`sum_incoming` DESC"}, 272 {`PATH has_parent AS () -[:has_father|has_mother]-> (:Person) 273 SELECT ancestor.name 274 FROM MATCH (p1:Person) -/:has_parent+/-> (ancestor) 275 , MATCH (p2:Person) -/:has_parent+/-> (ancestor) 276 WHERE p1.name = 'Mario' 277 AND p2.name = 'Luigi'`, true, "PATH `has_parent` AS () -[:`has_father`|`has_mother`]-> (:`Person`) SELECT `ancestor`.`name` FROM MATCH (`p1`:`Person`) -/:`has_parent`+/-> (`ancestor`),MATCH (`p2`:`Person`) -/:`has_parent`+/-> (`ancestor`) WHERE `p1`.`name`='Mario' AND `p2`.`name`='Luigi'"}, 278 {`PATH connects_to AS (:Generator) -[:has_connector]-> (c:Connector) <-[:has_connector]- (:Generator) 279 WHERE c.status = 'OPERATIONAL' 280 SELECT generatorA.location, generatorB.location 281 FROM MATCH (generatorA) -/:connects_to+/-> (generatorB)`, true, "PATH `connects_to` AS (:`Generator`) -[:`has_connector`]-> (`c`:`Connector`) <-[:`has_connector`]- (:`Generator`) WHERE `c`.`status`='OPERATIONAL' SELECT `generatorA`.`location`,`generatorB`.`location` FROM MATCH (`generatorA`) -/:`connects_to`+/-> (`generatorB`)"}, 282 {`PATH macro1 AS (v1:Generator) -[e1:has_connector]-> (v2:Connector) 283 SELECT COUNT(*) 284 FROM MATCH (generatorA) <-/:macro1+/- (generatorB) 285 WHERE generatorA.name = 'AEH382'`, true, "PATH `macro1` AS (`v1`:`Generator`) -[`e1`:`has_connector`]-> (`v2`:`Connector`) SELECT COUNT(1) FROM MATCH (`generatorA`) <-/:`macro1`+/- (`generatorB`) WHERE `generatorA`.`name`='AEH382'"}, 286 {`PATH macro1 AS (v2:Connector) <-[e1:has_connector]- (v1:Generator) 287 SELECT COUNT(*) 288 FROM MATCH (generatorA) -/:macro1+/-> (generatorB) 289 WHERE generatorA.name = 'AEH382'`, true, "PATH `macro1` AS (`v2`:`Connector`) <-[`e1`:`has_connector`]- (`v1`:`Generator`) SELECT COUNT(1) FROM MATCH (`generatorA`) -/:`macro1`+/-> (`generatorB`) WHERE `generatorA`.`name`='AEH382'"}, 290 } 291 RunTest(t, table) 292 } 293 294 func TestLiteral(t *testing.T) { 295 table := []testCase{ 296 {"SELECT DATE '2017-01-01' FROM MATCH ()", true, "SELECT DATE '2017-01-01' FROM MATCH ()"}, 297 {"SELECT TIME '12:34:56' FROM MATCH ()", true, "SELECT TIME '12:34:56' FROM MATCH ()"}, 298 {"SELECT TIME '12:34:56+01:00' FROM MATCH ()", true, "SELECT TIME '12:34:56+01:00' FROM MATCH ()"}, 299 {"SELECT TIME '12:34:56-07:00' FROM MATCH ()", true, "SELECT TIME '12:34:56-07:00' FROM MATCH ()"}, 300 {"SELECT TIMESTAMP '2017-01-01 12:34:56' FROM MATCH ()", true, "SELECT TIMESTAMP '2017-01-01 12:34:56' FROM MATCH ()"}, 301 {"SELECT TIMESTAMP '2017-01-01 12:34:56+01:00' FROM MATCH ()", true, "SELECT TIMESTAMP '2017-01-01 12:34:56+01:00' FROM MATCH ()"}, 302 {"SELECT TIMESTAMP '2017-01-01 12:34:56-07:00' FROM MATCH ()", true, "SELECT TIMESTAMP '2017-01-01 12:34:56-07:00' FROM MATCH ()"}, 303 {"SELECT INTERVAL 1 YEAR FROM MATCH ()", true, "SELECT INTERVAL 1 YEAR FROM MATCH ()"}, 304 {"SELECT INTERVAL 2 MONTH FROM MATCH ()", true, "SELECT INTERVAL 2 MONTH FROM MATCH ()"}, 305 {"SELECT INTERVAL 3 DAY FROM MATCH ()", true, "SELECT INTERVAL 3 DAY FROM MATCH ()"}, 306 {"SELECT INTERVAL 4 HOUR FROM MATCH ()", true, "SELECT INTERVAL 4 HOUR FROM MATCH ()"}, 307 {"SELECT INTERVAL 5 MINUTE FROM MATCH ()", true, "SELECT INTERVAL 5 MINUTE FROM MATCH ()"}, 308 } 309 RunTest(t, table) 310 } 311 312 func TestDDL(t *testing.T) { 313 table := []testCase{ 314 { 315 "CREATE GRAPH g1", 316 true, 317 "CREATE GRAPH `g1`", 318 }, 319 { 320 "DROP GRAPH g1", 321 true, 322 "DROP GRAPH `g1`", 323 }, 324 { 325 `CREATE LABEL l`, 326 true, 327 "CREATE LABEL `l`", 328 }, 329 { 330 `Drop LABEL l`, 331 true, 332 "DROP LABEL `l`", 333 }, 334 { 335 `show graphs`, 336 true, 337 "SHOW GRAPHS", 338 }, 339 { 340 `show labels`, 341 true, 342 "SHOW LABELS", 343 }, 344 { 345 `show labels in g1`, 346 true, 347 "SHOW LABELS IN `g1`", 348 }, 349 } 350 RunTest(t, table) 351 } 352 353 func TestModify(t *testing.T) { 354 table := []testCase{ 355 { 356 "INSERT VERTEX x, VERTEX x", 357 true, 358 "INSERT VERTEX `x`,VERTEX `x`", 359 }, 360 { 361 "INSERT VERTEX x LABELS ( Male, Female ) PROPERTIES ( x.age = 22 )", 362 true, 363 "INSERT VERTEX `x` LABELS (`Male`, `Female`) PROPERTIES (`x`.`age` = 22)", 364 }, 365 { 366 "INSERT VERTEX x LABELS ( Male ) PROPERTIES ( x.age = y.age ) FROM MATCH (y:Male)", 367 true, 368 "INSERT VERTEX `x` LABELS (`Male`) PROPERTIES (`x`.`age` = `y`.`age`) FROM MATCH (`y`:`Male`)", 369 }, 370 { 371 `INSERT VERTEX x LABELS ( Profession ) PROPERTIES ( x.name = y.profession ) 372 FROM MATCH (y:Person) 373 GROUP BY y.profession`, 374 true, 375 "INSERT VERTEX `x` LABELS (`Profession`) PROPERTIES (`x`.`name` = `y`.`profession`) FROM MATCH (`y`:`Person`) GROUP BY `y`.`profession`", 376 }, 377 { 378 `INSERT EDGE e BETWEEN x AND y 379 FROM MATCH (x) 380 , MATCH (y) 381 WHERE id(x) = 1 AND id(y) = 2 `, 382 true, 383 "INSERT EDGE `e` BETWEEN `x` AND `y` FROM MATCH (`x`),MATCH (`y`) WHERE ID(`x`)=1 AND ID(`y`)=2", 384 }, 385 { 386 `INSERT EDGE e BETWEEN x AND y LABELS ( knows ) 387 FROM MATCH (x:Person) 388 , MATCH (y:Person) 389 WHERE id(x) = 1 AND id(y) = 2`, 390 true, 391 "INSERT EDGE `e` BETWEEN `x` AND `y` LABELS (`knows`) FROM MATCH (`x`:`Person`),MATCH (`y`:`Person`) WHERE ID(`x`)=1 AND ID(`y`)=2", 392 }, 393 { 394 "INSERT VERTEX v PROPERTIES ( v.age = 22 )", 395 true, 396 "INSERT VERTEX `v` PROPERTIES (`v`.`age` = 22)", 397 }, 398 { 399 `INSERT EDGE e BETWEEN x AND y LABELS ( knows ) PROPERTIES ( e.since = DATE '2017-09-21' ) 400 FROM MATCH (x:Person) 401 , MATCH (y:Person) 402 WHERE id(x) = 1 AND id(y) = 2`, 403 true, 404 "INSERT EDGE `e` BETWEEN `x` AND `y` LABELS (`knows`) PROPERTIES (`e`.`since` = DATE '2017-09-21') FROM MATCH (`x`:`Person`),MATCH (`y`:`Person`) WHERE ID(`x`)=1 AND ID(`y`)=2", 405 }, 406 { 407 `INSERT 408 VERTEX v LABELS ( Male ) PROPERTIES ( v.age = 23, v.name = 'John' ), 409 VERTEX u LABELS ( Female ) PROPERTIES ( u.age = 24, u.name = 'Jane' )`, 410 true, 411 "INSERT VERTEX `v` LABELS (`Male`) PROPERTIES (`v`.`age` = 23, `v`.`name` = 'John'),VERTEX `u` LABELS (`Female`) PROPERTIES (`u`.`age` = 24, `u`.`name` = 'Jane')", 412 }, 413 { 414 `INSERT VERTEX x LABELS ( Person ) PROPERTIES ( x.name = 'John' ) 415 , EDGE e BETWEEN x AND y LABELS ( knows ) PROPERTIES ( e.since = DATE '2017-09-21' ) 416 FROM MATCH (y) 417 WHERE y.name = 'Jane'`, 418 true, 419 "INSERT VERTEX `x` LABELS (`Person`) PROPERTIES (`x`.`name` = 'John'),EDGE `e` BETWEEN `x` AND `y` LABELS (`knows`) PROPERTIES (`e`.`since` = DATE '2017-09-21') FROM MATCH (`y`) WHERE `y`.`name`='Jane'", 420 }, 421 { 422 `INSERT EDGE e BETWEEN x AND y 423 FROM MATCH (x) 424 , MATCH (y) -> (z) 425 WHERE id(x) = 1`, 426 true, 427 "INSERT EDGE `e` BETWEEN `x` AND `y` FROM MATCH (`x`),MATCH (`y`) -> (`z`) WHERE ID(`x`)=1", 428 }, 429 { 430 `UPDATE x SET ( x.age = 42 ) 431 FROM MATCH (x:Person) 432 WHERE x.name = 'John'`, 433 true, 434 "UPDATE `x` SET (`x`.`age` = 42) FROM MATCH (`x`:`Person`) WHERE `x`.`name`='John'", 435 }, 436 { 437 `UPDATE v SET ( v.carOwner = TRUE ) 438 , u SET ( u.weight = 3500 ) 439 , e SET ( e.since = DATE '2010-01-03' ) 440 FROM MATCH (v:Person) <-[e:belongs_to]- (u:Car) 441 WHERE v.name = 'John'`, 442 true, 443 "UPDATE `v` SET (`v`.`carOwner` = TRUE),`u` SET (`u`.`weight` = 3500),`e` SET (`e`.`since` = DATE '2010-01-03') FROM MATCH (`v`:`Person`) <-[`e`:`belongs_to`]- (`u`:`Car`) WHERE `v`.`name`='John'", 444 }, 445 { 446 `UPDATE x SET ( x.a = y.b, x.b = 12 ) FROM MATCH (x) -> (y)`, 447 true, 448 "UPDATE `x` SET (`x`.`a` = `y`.`b`, `x`.`b` = 12) FROM MATCH (`x`) -> (`y`)", 449 }, 450 { 451 `UPDATE x SET ( x.a = y.a ) FROM MATCH (x) -> (y)`, 452 true, 453 "UPDATE `x` SET (`x`.`a` = `y`.`a`) FROM MATCH (`x`) -> (`y`)", 454 }, 455 { 456 `UPDATE v SET ( v.a = 65 - v.age ) 457 FROM MATCH (v:Person) -> (u:Person) 458 WHERE v.name = 'John'`, 459 true, 460 "UPDATE `v` SET (`v`.`a` = 65-`v`.`age`) FROM MATCH (`v`:`Person`) -> (`u`:`Person`) WHERE `v`.`name`='John'", 461 }, 462 { 463 `UPDATE v SET ( v.a = 65 - u.age ) 464 FROM MATCH (v:Person) -> (u:Person) 465 WHERE v.name = 'John'`, 466 true, 467 "UPDATE `v` SET (`v`.`a` = 65-`u`.`age`) FROM MATCH (`v`:`Person`) -> (`u`:`Person`) WHERE `v`.`name`='John'", 468 }, 469 { 470 `DELETE e FROM MATCH () -[e]-> ()`, 471 true, 472 "DELETE `e` FROM MATCH () -[`e`]-> ()", 473 }, 474 { 475 `DELETE x, y FROM MATCH (x) -> (y)`, 476 true, 477 "DELETE `x`,`y` FROM MATCH (`x`) -> (`y`)", 478 }, 479 { 480 `DELETE x FROM MATCH (x) WHERE id(x) = 11`, 481 true, 482 "DELETE `x` FROM MATCH (`x`) WHERE ID(`x`)=11", 483 }, 484 { 485 `DELETE x FROM MATCH (x)`, 486 true, 487 "DELETE `x` FROM MATCH (`x`)", 488 }, 489 // { 490 // `INSERT EDGE e BETWEEN x AND y 491 //UPDATE y SET ( y.a = 12 ) 492 // FROM MATCH (x), MATCH (y) 493 // WHERE id(x) = 1 AND id(y) = 2 494 //`, 495 // true, 496 // "INSERT EDGE `e` BETWEEN `x` AND `y` UPDATE `y` SET (`y`.`a` = 12) FROM MATCH (`x`),MATCH (`y`) WHERE ID(`x`)=1 AND ID(`y`)=2", 497 // }, 498 } 499 RunTest(t, table) 500 } 501 502 func RunTest(t *testing.T, table []testCase) { 503 p := parser.New() 504 for _, tbl := range table { 505 _, _, err := p.Parse(tbl.src) 506 if !tbl.ok { 507 require.Errorf(t, err, "source %v", tbl.src) 508 continue 509 } 510 require.NoErrorf(t, err, "source %v", tbl.src) 511 // restore correctness test 512 if tbl.ok { 513 RunRestoreTest(t, tbl.src, tbl.restore) 514 } 515 } 516 } 517 518 func RunRestoreTest(t *testing.T, sourceSQLs, expectSQLs string) { 519 var sb strings.Builder 520 p := parser.New() 521 comment := fmt.Sprintf("source %v", sourceSQLs) 522 stmts, _, err := p.Parse(sourceSQLs) 523 require.NoErrorf(t, err, "source %v", sourceSQLs) 524 restoreSQLs := "" 525 for _, stmt := range stmts { 526 sb.Reset() 527 err = stmt.Restore(format.NewRestoreCtx(format.DefaultRestoreFlags, &sb)) 528 require.NoError(t, err, comment) 529 restoreSQL := sb.String() 530 comment = fmt.Sprintf("source %v; restore %v", sourceSQLs, restoreSQL) 531 restoreStmt, err := p.ParseOneStmt(restoreSQL) 532 require.NoError(t, err, comment) 533 _ = restoreStmt 534 // require.Equal(t, stmt, restoreStmt, comment) // TODO: compare stmt and restoreStmt 535 if restoreSQLs != "" { 536 restoreSQLs += "; " 537 } 538 restoreSQLs += restoreSQL 539 540 } 541 require.Equalf(t, expectSQLs, restoreSQLs, "restore %v; expect %v", restoreSQLs, expectSQLs) 542 }