You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@age.apache.org by de...@apache.org on 2022/02/03 22:40:48 UTC
[incubator-age] branch master updated: bug-fix: chained union logic
This is an automated email from the ASF dual-hosted git repository.
dehowef pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-age.git
The following commit(s) were added to refs/heads/master by this push:
new ed283c0 bug-fix: chained union logic
ed283c0 is described below
commit ed283c06b44b990957e3fa21e719eb9dc93e45f3
Author: Dehowe Feng <de...@gmail.com>
AuthorDate: Wed Feb 2 16:42:39 2022 -0800
bug-fix: chained union logic
fixed bug with chained unions that failed to remove duplicate values
the bug appeared when mixing agtypes and chaining multiple unions
---
regress/expected/cypher_union.out | 24 ++++++++++++++++++++----
regress/sql/cypher_union.sql | 10 +++++++++-
src/backend/parser/cypher_clause.c | 13 ++++++++++---
3 files changed, 39 insertions(+), 8 deletions(-)
diff --git a/regress/expected/cypher_union.out b/regress/expected/cypher_union.out
index 1999721..1931564 100644
--- a/regress/expected/cypher_union.out
+++ b/regress/expected/cypher_union.out
@@ -46,15 +46,15 @@ SELECT * FROM cypher('cypher_union', $$ MATCH (n) RETURN n UNION ALL MATCH (n) R
SELECT * FROM cypher('cypher_union', $$ MATCH (n) RETURN n UNION RETURN 1 $$) as (a agtype);
a
----------------------------------------------------------------
- 1
{"id": 281474976710657, "label": "", "properties": {}}::vertex
+ 1
(2 rows)
SELECT * FROM cypher('cypher_union', $$ MATCH (n) RETURN n UNION RETURN NULL $$) as (a agtype);
a
----------------------------------------------------------------
-
{"id": 281474976710657, "label": "", "properties": {}}::vertex
+
(2 rows)
SELECT * FROM cypher('cypher_union', $$ RETURN [1,2,3] UNION RETURN 1 $$) as (a agtype);
@@ -137,10 +137,26 @@ SELECT * FROM cypher('cypher_union', $$MATCH (n) RETURN n UNION MATCH (n) return
(1 row)
/* scoping */
-SELECT * FROM cypher('cypher_union', $$MATCH (n) RETURN n UNION ALL MATCH (m) RETURN n$$) AS (result agtype);
+SELECT * FROM cypher('cypher_union', $$MATCH (n) RETURN n UNION ALL MATCH (m) RETURN n$$) AS (result agtype);
ERROR: could not find rte for n
-LINE 2: ... $$MATCH (n) RETURN n UNION ALL MATCH (m) RETURN n$$) AS (r...
+LINE 2: ..., $$MATCH (n) RETURN n UNION ALL MATCH (m) RETURN n$$) AS (r...
^
+/*
+ *UNION and UNION ALL, type casting
+ */
+SELECT * FROM cypher('cypher_union', $$ RETURN 1.0::int UNION return 1::float UNION ALL RETURN 2.0::float $$) AS (result agtype);
+ result
+--------
+ 1
+ 2.0
+(2 rows)
+
+SELECT * FROM cypher('cypher_union', $$ RETURN 1.0::float UNION return 1::int UNION RETURN 1::float $$) AS (result agtype);
+ result
+--------
+ 1.0
+(1 row)
+
SELECT drop_graph('cypher_union', true);
NOTICE: drop cascades to 2 other objects
DETAIL: drop cascades to table cypher_union._ag_label_vertex
diff --git a/regress/sql/cypher_union.sql b/regress/sql/cypher_union.sql
index 4f6ec85..3338ebb 100644
--- a/regress/sql/cypher_union.sql
+++ b/regress/sql/cypher_union.sql
@@ -65,6 +65,14 @@ SELECT * FROM cypher('cypher_union', $$MATCH (n) RETURN n UNION ALL MATCH (n) re
SELECT * FROM cypher('cypher_union', $$MATCH (n) RETURN n UNION MATCH (n) return n UNION ALL MATCH(n) RETURN n$$) AS (result agtype);
/* scoping */
-SELECT * FROM cypher('cypher_union', $$MATCH (n) RETURN n UNION ALL MATCH (m) RETURN n$$) AS (result agtype);
+SELECT * FROM cypher('cypher_union', $$MATCH (n) RETURN n UNION ALL MATCH (m) RETURN n$$) AS (result agtype);
+
+/*
+ *UNION and UNION ALL, type casting
+ */
+SELECT * FROM cypher('cypher_union', $$ RETURN 1.0::int UNION return 1::float UNION ALL RETURN 2.0::float $$) AS (result agtype);
+
+SELECT * FROM cypher('cypher_union', $$ RETURN 1.0::float UNION return 1::int UNION RETURN 1::float $$) AS (result agtype);
+
SELECT drop_graph('cypher_union', true);
diff --git a/src/backend/parser/cypher_clause.c b/src/backend/parser/cypher_clause.c
index c540237..151da2d 100644
--- a/src/backend/parser/cypher_clause.c
+++ b/src/backend/parser/cypher_clause.c
@@ -921,17 +921,24 @@ transform_cypher_union_tree(cypher_parsestate *cpstate, cypher_clause *clause,
SortGroupClause *grpcl = makeNode(SortGroupClause);
Oid sortop;
Oid eqop;
- bool hashable;
+ bool hashable = false;
ParseCallbackState pcbstate;
setup_parser_errposition_callback(&pcbstate, pstate,
bestlocation);
- /* determine the eqop and optional sortop */
+ /*
+ * determine the eqop and optional sortop
+ *
+ * NOTE: for UNION, we set hashable to false and pass a NULL to
+ * isHashable in get_sort_group_operators to prevent a logic error
+ * where UNION fails to exclude duplicate results.
+ *
+ */
get_sort_group_operators(rescoltype,
false, true, false,
&sortop, &eqop, NULL,
- &hashable);
+ NULL);
cancel_parser_errposition_callback(&pcbstate);