Skip to content

Commit

Permalink
Fix issue where casting target list produces 'NULL'.
Browse files Browse the repository at this point in the history
To check which columns are needed to be output, we create a column
list from the target list.  However, we are only adding the plain
Var nodes appearing in the target list.  Thus, if a target list has
an explicit casting, then it won't appear as a plain Var node and
thus not added in the column list, resulting in returning NULL for
them.  Fix that by correctly pulling out the Vars from the expression
appearing in the target list by using pull_var_clause().  This enables
us to give a correct result even if we have expressions other than an
explicit cast like a function call or operators.

Reported on GitHub through issues #133 by Maksim Volkau (dadhi).

FDW-197, Vaibhav Dalvi, reviewed by Suraj Kharage
  • Loading branch information
jeevanchalke committed Oct 12, 2020
1 parent 3571072 commit de5db6e
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 1 deletion.
68 changes: 68 additions & 0 deletions expected/select.out
Original file line number Diff line number Diff line change
Expand Up @@ -1006,6 +1006,74 @@ SELECT c1, c8 FROM f_test_tbl1 ft1
200 | 30
(2 rows)

-- FDW-197: Casting target list should give correct result.
SELECT a::float FROM f_mongo_test ORDER BY a LIMIT 2;
a
---
0
1
(2 rows)

SELECT a, b::varchar FROM f_mongo_test ORDER BY a LIMIT 3;
a | b
---+-----------------------
0 | mongo_test collection
1 | One
2 | Two
(3 rows)

SELECT a::float, b::varchar FROM f_mongo_test ORDER BY a LIMIT 2;
a | b
---+-----------------------
0 | mongo_test collection
1 | One
(2 rows)

SELECT c1, c2::text FROM f_test_tbl1 ORDER BY c1 LIMIT 2;
c1 | c2
-----+------
100 | EMP1
200 | EMP2
(2 rows)

SELECT a, LENGTH(b) FROM f_mongo_test ORDER BY 1 LIMIT 2;
a | length
---+--------
0 | 21
1 | 3
(2 rows)

SELECT t1.c6::float, t1.c6::int, t1.c5::timestamptz, t1.c3::text, t2.c1::numeric, t2.c3
FROM f_test_tbl1 t1, f_test_tbl2 t2 WHERE t1.c8 = t2.c1
ORDER BY t2.c1, t1.c6 LIMIT 5;
c6 | c6 | c5 | c3 | c1 | c3
---------+------+------------------------+---------+----+----------
1300 | 1300 | 1982-01-23 00:00:00-08 | ADMIN | 10 | PUNE
2450.34 | 2450 | 1981-06-09 00:00:00-07 | MANAGER | 10 | PUNE
5000 | 5000 | 1981-11-17 00:00:00-08 | HEAD | 10 | PUNE
800.3 | 800 | 1980-12-17 00:00:00-08 | ADMIN | 20 | BANGLORE
1100 | 1100 | 1987-05-23 00:00:00-07 | ADMIN | 20 | BANGLORE
(5 rows)

SELECT SUM(a::float), SUM(a % 2), a % 2 AS "a % 2"FROM f_mongo_test
GROUP BY a % 2 ORDER BY 2;
sum | sum | a % 2
-----+-----+-------
30 | 0 | 0
25 | 5 | 1
(2 rows)

SELECT (c6::float + (c1 * length(c3::text))) AS "c1 + c6", c1, c6
FROM f_test_tbl1 ORDER BY c1 LIMIT 5;
c1 + c6 | c1 | c6
---------+-----+---------
1300.3 | 100 | 800.3
3200 | 200 | 1600
3650 | 300 | 1250
5775 | 400 | 2975
5250.23 | 500 | 1250.23
(5 rows)

-- Cleanup
DELETE FROM f_mongo_test WHERE a != 0;
DROP TABLE l_test_tbl1;
Expand Down
68 changes: 68 additions & 0 deletions expected/select_1.out
Original file line number Diff line number Diff line change
Expand Up @@ -970,6 +970,74 @@ SELECT c1, c8 FROM f_test_tbl1 ft1
200 | 30
(2 rows)

-- FDW-197: Casting target list should give correct result.
SELECT a::float FROM f_mongo_test ORDER BY a LIMIT 2;
a
---
0
1
(2 rows)

SELECT a, b::varchar FROM f_mongo_test ORDER BY a LIMIT 3;
a | b
---+-----------------------
0 | mongo_test collection
1 | One
2 | Two
(3 rows)

SELECT a::float, b::varchar FROM f_mongo_test ORDER BY a LIMIT 2;
a | b
---+-----------------------
0 | mongo_test collection
1 | One
(2 rows)

SELECT c1, c2::text FROM f_test_tbl1 ORDER BY c1 LIMIT 2;
c1 | c2
-----+------
100 | EMP1
200 | EMP2
(2 rows)

SELECT a, LENGTH(b) FROM f_mongo_test ORDER BY 1 LIMIT 2;
a | length
---+--------
0 | 21
1 | 3
(2 rows)

SELECT t1.c6::float, t1.c6::int, t1.c5::timestamptz, t1.c3::text, t2.c1::numeric, t2.c3
FROM f_test_tbl1 t1, f_test_tbl2 t2 WHERE t1.c8 = t2.c1
ORDER BY t2.c1, t1.c6 LIMIT 5;
c6 | c6 | c5 | c3 | c1 | c3
---------+------+------------------------+---------+----+----------
1300 | 1300 | 1982-01-23 00:00:00-08 | ADMIN | 10 | PUNE
2450.34 | 2450 | 1981-06-09 00:00:00-07 | MANAGER | 10 | PUNE
5000 | 5000 | 1981-11-17 00:00:00-08 | HEAD | 10 | PUNE
800.3 | 800 | 1980-12-17 00:00:00-08 | ADMIN | 20 | BANGLORE
1100 | 1100 | 1987-05-23 00:00:00-07 | ADMIN | 20 | BANGLORE
(5 rows)

SELECT SUM(a::float), SUM(a % 2), a % 2 AS "a % 2"FROM f_mongo_test
GROUP BY a % 2 ORDER BY 2;
sum | sum | a % 2
-----+-----+-------
30 | 0 | 0
25 | 5 | 1
(2 rows)

SELECT (c6::float + (c1 * length(c3::text))) AS "c1 + c6", c1, c6
FROM f_test_tbl1 ORDER BY c1 LIMIT 5;
c1 + c6 | c1 | c6
---------+-----+---------
1300.3 | 100 | 800.3
3200 | 200 | 1600
3650 | 300 | 1250
5775 | 400 | 2975
5250.23 | 500 | 1250.23
(5 rows)

-- Cleanup
DELETE FROM f_mongo_test WHERE a != 0;
DROP TABLE l_test_tbl1;
Expand Down
6 changes: 5 additions & 1 deletion mongo_query.c
Original file line number Diff line number Diff line change
Expand Up @@ -730,7 +730,11 @@ ColumnList(RelOptInfo *baserel)
ListCell *restrictInfoCell;

/* First add the columns used in joins and projections */
neededColumnList = list_copy(targetColumnList);
neededColumnList = pull_var_clause((Node *)targetColumnList,
#if PG_VERSION_NUM < 90600
PVC_RECURSE_AGGREGATES,
#endif
PVC_RECURSE_PLACEHOLDERS);

/* Then walk over all restriction clauses, and pull up any used columns */
foreach(restrictInfoCell, restrictInfoList)
Expand Down
14 changes: 14 additions & 0 deletions sql/select.sql
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,20 @@ SELECT c1, c8 FROM f_test_tbl1 ft1
WHERE ft1.c8 = (SELECT c1 FROM f_test_tbl2 ft2 WHERE ft1.c8 = ft2.c1)
ORDER BY c1 LIMIT 2;

-- FDW-197: Casting target list should give correct result.
SELECT a::float FROM f_mongo_test ORDER BY a LIMIT 2;
SELECT a, b::varchar FROM f_mongo_test ORDER BY a LIMIT 3;
SELECT a::float, b::varchar FROM f_mongo_test ORDER BY a LIMIT 2;
SELECT c1, c2::text FROM f_test_tbl1 ORDER BY c1 LIMIT 2;
SELECT a, LENGTH(b) FROM f_mongo_test ORDER BY 1 LIMIT 2;
SELECT t1.c6::float, t1.c6::int, t1.c5::timestamptz, t1.c3::text, t2.c1::numeric, t2.c3
FROM f_test_tbl1 t1, f_test_tbl2 t2 WHERE t1.c8 = t2.c1
ORDER BY t2.c1, t1.c6 LIMIT 5;
SELECT SUM(a::float), SUM(a % 2), a % 2 AS "a % 2"FROM f_mongo_test
GROUP BY a % 2 ORDER BY 2;
SELECT (c6::float + (c1 * length(c3::text))) AS "c1 + c6", c1, c6
FROM f_test_tbl1 ORDER BY c1 LIMIT 5;

-- Cleanup
DELETE FROM f_mongo_test WHERE a != 0;
DROP TABLE l_test_tbl1;
Expand Down

0 comments on commit de5db6e

Please sign in to comment.