1\set MYSQL_HOST			`echo \'"$MYSQL_HOST"\'`
2\set MYSQL_PORT			`echo \'"$MYSQL_PORT"\'`
3\set MYSQL_USER_NAME	`echo \'"$MYSQL_USER_NAME"\'`
4\set MYSQL_PASS			`echo \'"$MYSQL_PWD"\'`
5
6-- Before running this file User must create database mysql_fdw_regress on
7-- MySQL with all permission for MYSQL_USER_NAME user with MYSQL_PWD password
8-- and ran mysql_init.sh file to create tables.
9
10\c contrib_regression
11CREATE EXTENSION IF NOT EXISTS mysql_fdw;
12CREATE SERVER mysql_svr FOREIGN DATA WRAPPER mysql_fdw
13  OPTIONS (host :MYSQL_HOST, port :MYSQL_PORT);
14CREATE USER MAPPING FOR PUBLIC SERVER mysql_svr
15  OPTIONS (username :MYSQL_USER_NAME, password :MYSQL_PASS);
16
17-- Check version
18SELECT mysql_fdw_version();
19
20-- Create foreign tables
21CREATE FOREIGN TABLE f_mysql_test(a int, b int)
22  SERVER mysql_svr OPTIONS (dbname 'mysql_fdw_regress', table_name 'mysql_test');
23CREATE FOREIGN TABLE f_numbers(a int, b varchar(255))
24  SERVER mysql_svr OPTIONS (dbname 'mysql_fdw_regress', table_name 'numbers');
25CREATE FOREIGN TABLE f_test_tbl1 (c1 INTEGER, c2 VARCHAR(10), c3 CHAR(9),c4 BIGINT, c5 pg_catalog.Date, c6 DECIMAL, c7 INTEGER, c8 SMALLINT)
26  SERVER mysql_svr OPTIONS (dbname 'mysql_fdw_regress', table_name 'test_tbl1');
27CREATE FOREIGN TABLE f_test_tbl2 (c1 INTEGER, c2 VARCHAR(14), c3 VARCHAR(13))
28  SERVER mysql_svr OPTIONS (dbname 'mysql_fdw_regress', table_name 'test_tbl2');
29CREATE TYPE size_t AS enum('small','medium','large');
30CREATE FOREIGN TABLE f_enum_t1(id int, size size_t)
31  SERVER mysql_svr OPTIONS (dbname 'mysql_fdw_regress', table_name 'enum_t1');
32
33-- Insert data in MySQL db using foreign tables
34INSERT INTO f_test_tbl1 VALUES (100, 'EMP1', 'ADMIN', 1300, '1980-12-17', 800.23, NULL, 20);
35INSERT INTO f_test_tbl1 VALUES (200, 'EMP2', 'SALESMAN', 600, '1981-02-20', 1600.00, 300, 30);
36INSERT INTO f_test_tbl1 VALUES (300, 'EMP3', 'SALESMAN', 600, '1981-02-22', 1250, 500, 30);
37INSERT INTO f_test_tbl1 VALUES (400, 'EMP4', 'MANAGER', 900, '1981-04-02', 2975.12, NULL, 20);
38INSERT INTO f_test_tbl1 VALUES (500, 'EMP5', 'SALESMAN', 600, '1981-09-28', 1250, 1400, 30);
39INSERT INTO f_test_tbl1 VALUES (600, 'EMP6', 'MANAGER', 900, '1981-05-01', 2850, NULL, 30);
40INSERT INTO f_test_tbl1 VALUES (700, 'EMP7', 'MANAGER', 900, '1981-06-09', 2450.45, NULL, 10);
41INSERT INTO f_test_tbl1 VALUES (800, 'EMP8', 'FINANCE', 400, '1987-04-19', 3000, NULL, 20);
42INSERT INTO f_test_tbl1 VALUES (900, 'EMP9', 'HEAD', NULL, '1981-11-17', 5000, NULL, 10);
43INSERT INTO f_test_tbl1 VALUES (1000, 'EMP10', 'SALESMAN', 600, '1980-09-08', 1500, 0, 30);
44INSERT INTO f_test_tbl1 VALUES (1100, 'EMP11', 'ADMIN', 800, '1987-05-23', 1100, NULL, 20);
45INSERT INTO f_test_tbl1 VALUES (1200, 'EMP12', 'ADMIN', 600, '1981-12-03', 950, NULL, 30);
46INSERT INTO f_test_tbl1 VALUES (1300, 'EMP13', 'FINANCE', 400, '1981-12-03', 3000, NULL, 20);
47INSERT INTO f_test_tbl1 VALUES (1400, 'EMP14', 'ADMIN', 700, '1982-01-23', 1300, NULL, 10);
48INSERT INTO f_test_tbl2 VALUES(10, 'DEVELOPMENT', 'PUNE');
49INSERT INTO f_test_tbl2 VALUES(20, 'ADMINISTRATION', 'BANGLORE');
50INSERT INTO f_test_tbl2 VALUES(30, 'SALES', 'MUMBAI');
51INSERT INTO f_test_tbl2 VALUES(40, 'HR', 'NAGPUR');
52
53SET datestyle TO ISO;
54
55-- Retrieve Data from Foreign Table using SELECT Statement.
56SELECT c1, c2, c3, c4, c5, c6, c7, c8 FROM f_test_tbl1
57  ORDER BY c1 DESC, c8;
58SELECT DISTINCT c8 FROM f_test_tbl1 ORDER BY 1;
59SELECT c2 AS "Employee Name" FROM f_test_tbl1 ORDER BY 1;
60SELECT c8, c6, c7 FROM f_test_tbl1 ORDER BY 1, 2, 3;
61SELECT c1, c2, c3, c4, c5, c6, c7, c8 FROM f_test_tbl1
62  WHERE c1 = 100 ORDER BY 1;
63SELECT c1, c2, c3, c4, c5, c6, c7, c8 FROM f_test_tbl1
64  WHERE c1 = 100 OR c1 = 700 ORDER BY 1;
65SELECT * FROM f_test_tbl1 WHERE c3 like 'SALESMAN' ORDER BY 1;
66SELECT * FROM f_test_tbl1 WHERE c1 IN (100, 700) ORDER BY 1;
67SELECT * FROM f_test_tbl1 WHERE c1 NOT IN (100, 700) ORDER BY 1 LIMIT 5;
68SELECT * FROM f_test_tbl1 WHERE c8 BETWEEN 10 AND 20 ORDER BY 1;
69SELECT * FROM f_test_tbl1 ORDER BY 1 OFFSET 5;
70
71-- Retrieve Data from Foreign Table using Group By Clause.
72SELECT c8 "Department", COUNT(c1) "Total Employees" FROM f_test_tbl1
73  GROUP BY c8 ORDER BY c8;
74SELECT c8, SUM(c6) FROM f_test_tbl1
75  GROUP BY c8 HAVING c8 IN (10, 30) ORDER BY c8;
76SELECT c8, SUM(c6) FROM f_test_tbl1
77  GROUP BY c8 HAVING SUM(c6) > 9400 ORDER BY c8;
78
79-- Row Level Functions
80SELECT UPPER(c2), LOWER(c2) FROM f_test_tbl2 ORDER BY 1, 2;
81
82-- Retrieve Data from Foreign Table using Sub Queries.
83SELECT * FROM f_test_tbl1
84  WHERE c8 <> ALL (SELECT c1 FROM f_test_tbl2 WHERE c1 IN (10, 30, 40))
85  ORDER BY c1;
86SELECT c1, c2, c3 FROM f_test_tbl2
87  WHERE EXISTS (SELECT 1 FROM f_test_tbl1 WHERE f_test_tbl2.c1 = f_test_tbl1.c8)
88  ORDER BY 1, 2;
89SELECT c1, c2, c3, c4, c5, c6, c7, c8 FROM f_test_tbl1
90  WHERE c8 NOT IN (SELECT c1 FROM f_test_tbl2) ORDER BY c1;
91
92-- Retrieve Data from Foreign Table using UNION Operator.
93SELECT c1, c2 FROM f_test_tbl2 UNION
94SELECT c1, c2 FROM f_test_tbl1 ORDER BY c1;
95
96SELECT c2 FROM f_test_tbl2  UNION ALL
97SELECT c2 FROM f_test_tbl1 ORDER BY c2;
98
99-- Retrieve Data from Foreign Table using INTERSECT Operator.
100SELECT c2 FROM f_test_tbl1 WHERE c1 >= 800 INTERSECT
101SELECT c2 FROM f_test_tbl1 WHERE c1 >= 400 ORDER BY c2;
102
103SELECT c2 FROM f_test_tbl1 WHERE c1 >= 800 INTERSECT ALL
104SELECT c2 FROM f_test_tbl1 WHERE c1 >= 400 ORDER BY c2;
105
106-- Retrieve Data from Foreign Table using EXCEPT.
107SELECT c2 FROM f_test_tbl1 EXCEPT
108SELECT c2 FROM f_test_tbl1 WHERE c1 > 900 ORDER BY c2;
109
110SELECT c2 FROM f_test_tbl1 EXCEPT ALL
111SELECT c2 FROM f_test_tbl1 WHERE c1 > 900 ORDER BY c2;
112
113-- Retrieve Data from Foreign Table using CTE (With Clause).
114WITH
115  with_qry AS (SELECT c1, c2, c3 FROM f_test_tbl2)
116SELECT e.c2, e.c6, w.c1, w.c2 FROM f_test_tbl1 e, with_qry w
117  WHERE e.c8 = w.c1 ORDER BY e.c8, e.c2;
118
119WITH
120  test_tbl2_costs AS (SELECT d.c2, SUM(c6) test_tbl2_total FROM f_test_tbl1 e, f_test_tbl2 d
121    WHERE e.c8 = d.c1 GROUP BY 1),
122  avg_cost AS (SELECT SUM(test_tbl2_total)/COUNT(*) avg FROM test_tbl2_costs)
123SELECT * FROM test_tbl2_costs
124  WHERE test_tbl2_total > (SELECT avg FROM avg_cost) ORDER BY c2;
125
126-- Retrieve Data from Foreign Table using Window Clause.
127SELECT c8, c1, c6, AVG(c6) OVER (PARTITION BY c8) FROM f_test_tbl1
128  ORDER BY c8, c1;
129SELECT c8, c1, c6, COUNT(c6) OVER (PARTITION BY c8) FROM f_test_tbl1
130  WHERE c8 IN (10, 30, 40, 50, 60, 70) ORDER BY c8, c1;
131SELECT c8, c1, c6, SUM(c6) OVER (PARTITION BY c8) FROM f_test_tbl1
132  ORDER BY c8, c1;
133
134-- Views
135CREATE VIEW smpl_vw AS
136  SELECT c1, c2, c3, c4, c5, c6, c7, c8 FROM f_test_tbl1
137    ORDER BY c1;
138SELECT * FROM smpl_vw ORDER BY 1;
139
140CREATE VIEW comp_vw (s1, s2, s3, s6, s7, s8, d2) AS
141  SELECT s.c1, s.c2, s.c3, s.c6, s.c7, s.c8, d.c2
142    FROM f_test_tbl2 d, f_test_tbl1 s WHERE d.c1 = s.c8 AND d.c1 = 10
143    ORDER BY s.c1;
144SELECT * FROM comp_vw ORDER BY 1;
145
146CREATE TEMPORARY VIEW ttest_tbl1_vw AS
147  SELECT c1, c2, c3 FROM f_test_tbl2;
148SELECT * FROM ttest_tbl1_vw ORDER BY 1, 2;
149
150CREATE VIEW mul_tbl_view AS
151  SELECT d.c1 dc1, d.c2 dc2, e.c1 ec1, e.c2 ec2, e.c6 ec6
152    FROM f_test_tbl2 d INNER JOIN f_test_tbl1 e ON d.c1 = e.c8 ORDER BY d.c1;
153SELECT * FROM mul_tbl_view ORDER BY 1, 2,3;
154
155-- Insert Some records in numbers table.
156INSERT INTO f_numbers VALUES (1, 'One');
157INSERT INTO f_numbers VALUES (2, 'Two');
158INSERT INTO f_numbers VALUES (3, 'Three');
159INSERT INTO f_numbers VALUES (4, 'Four');
160INSERT INTO f_numbers VALUES (5, 'Five');
161INSERT INTO f_numbers VALUES (6, 'Six');
162INSERT INTO f_numbers VALUES (7, 'Seven');
163INSERT INTO f_numbers VALUES (8, 'Eight');
164INSERT INTO f_numbers VALUES (9, 'Nine');
165
166-- Retrieve Data From foreign tables in functions.
167CREATE OR REPLACE FUNCTION test_param_where() RETURNS void AS $$
168DECLARE
169  n varchar;
170BEGIN
171  FOR x IN 1..9 LOOP
172    SELECT b INTO n FROM f_numbers WHERE a = x;
173    RAISE NOTICE 'Found number %', n;
174  END LOOP;
175  return;
176END
177$$ LANGUAGE plpgsql;
178
179SELECT test_param_where();
180
181CREATE OR REPLACE FUNCTION test_param_where2(int, text) RETURNS integer AS '
182  SELECT a FROM f_numbers WHERE a = $1 AND b = $2;
183' LANGUAGE sql;
184
185SELECT test_param_where2(1, 'One');
186
187-- Foreign-Foreign table joins
188
189-- CROSS JOIN.
190SELECT f_test_tbl2.c2, f_test_tbl1.c2 FROM f_test_tbl2 CROSS JOIN f_test_tbl1 ORDER BY 1, 2;
191-- INNER JOIN.
192SELECT d.c1, d.c2, e.c1, e.c2, e.c6, e.c8
193  FROM f_test_tbl2 d, f_test_tbl1 e WHERE d.c1 = e.c8 ORDER BY 1, 3;
194SELECT d.c1, d.c2, e.c1, e.c2, e.c6, e.c8
195  FROM f_test_tbl2 d INNER JOIN f_test_tbl1 e ON d.c1 = e.c8 ORDER BY 1, 3;
196-- OUTER JOINS.
197SELECT d.c1, d.c2, e.c1, e.c2, e.c6, e.c8
198  FROM f_test_tbl2 d LEFT OUTER JOIN f_test_tbl1 e ON d.c1 = e.c8 ORDER BY 1, 3;
199SELECT d.c1, d.c2, e.c1, e.c2, e.c6, e.c8
200  FROM f_test_tbl2 d RIGHT OUTER JOIN f_test_tbl1 e ON d.c1 = e.c8 ORDER BY 1, 3;
201SELECT d.c1, d.c2, e.c1, e.c2, e.c6, e.c8
202  FROM f_test_tbl2 d FULL OUTER JOIN f_test_tbl1 e ON d.c1 = e.c8 ORDER BY 1, 3;
203
204-- Local-Foreign table joins.
205CREATE TABLE l_test_tbl1 AS
206  SELECT c1, c2, c3, c4, c5, c6, c7, c8 FROM f_test_tbl1;
207CREATE TABLE l_test_tbl2 AS
208  SELECT c1, c2, c3 FROM f_test_tbl2;
209
210-- CROSS JOIN.
211SELECT f_test_tbl2.c2, l_test_tbl1.c2 FROM f_test_tbl2 CROSS JOIN l_test_tbl1 ORDER BY 1, 2;
212-- INNER JOIN.
213SELECT d.c1, d.c2, e.c1, e.c2, e.c6, e.c8
214  FROM l_test_tbl2 d, f_test_tbl1 e WHERE d.c1 = e.c8 ORDER BY 1, 3;
215SELECT d.c1, d.c2, e.c1, e.c2, e.c6, e.c8
216  FROM f_test_tbl2 d INNER JOIN l_test_tbl1 e ON d.c1 = e.c8 ORDER BY 1, 3;
217-- OUTER JOINS.
218SELECT d.c1, d.c2, e.c1, e.c2, e.c6, e.c8
219  FROM f_test_tbl2 d LEFT OUTER JOIN l_test_tbl1 e ON d.c1 = e.c8 ORDER BY 1, 3;
220SELECT d.c1, d.c2, e.c1, e.c2, e.c6, e.c8
221  FROM f_test_tbl2 d RIGHT OUTER JOIN l_test_tbl1 e ON d.c1 = e.c8 ORDER BY 1, 3;
222SELECT d.c1, d.c2, e.c1, e.c2, e.c6, e.c8
223  FROM f_test_tbl2 d FULL OUTER JOIN l_test_tbl1 e ON d.c1 = e.c8 ORDER BY 1, 3;
224
225-- FDW-206: LEFT JOIN LATERAL case should not crash
226EXPLAIN (VERBOSE, COSTS OFF)
227SELECT * FROM f_mysql_test t1 LEFT JOIN LATERAL (
228  SELECT t2.a, t1.a AS t1_a FROM f_mysql_test t2) t3 ON t1.a = t3.a ORDER BY 1;
229SELECT * FROM f_mysql_test t1 LEFT JOIN LATERAL (
230  SELECT t2.a, t1.a AS t1_a FROM f_mysql_test t2) t3 ON t1.a = t3.a ORDER BY 1;
231SELECT t1.c1, t3.c1, t3.t1_c8 FROM f_test_tbl1 t1 INNER JOIN LATERAL (
232  SELECT t2.c1, t1.c8 AS t1_c8 FROM f_test_tbl2 t2) t3 ON t3.c1 = t3.t1_c8
233  ORDER BY 1, 2, 3;
234SELECT t1.c1, t3.c1, t3.t1_c8 FROM l_test_tbl1 t1 LEFT JOIN LATERAL (
235  SELECT t2.c1, t1.c8 AS t1_c8 FROM f_test_tbl2 t2) t3 ON t3.c1 = t3.t1_c8
236  ORDER BY 1, 2, 3;
237SELECT *, (SELECT r FROM (SELECT c1 AS c1) x, LATERAL (SELECT c1 AS r) y)
238  FROM f_test_tbl1 ORDER BY 1, 2, 3;
239-- LATERAL JOIN with RIGHT should throw error
240SELECT t1.c1, t3.c1, t3.t1_c8 FROM f_test_tbl1 t1 RIGHT JOIN LATERAL (
241  SELECT t2.c1, t1.c8 AS t1_c8 FROM f_test_tbl2 t2) t3 ON t3.c1 = t3.t1_c8
242  ORDER BY 1, 2, 3;
243
244-- FDW-207: NATURAL JOIN should give correct output
245SELECT t1.c1, t2.c1, t3.c1
246  FROM f_test_tbl1 t1 NATURAL JOIN f_test_tbl1 t2 NATURAL JOIN f_test_tbl1 t3
247  ORDER BY 1, 2, 3;
248
249-- FDW-208: IS NULL and LIKE should give the correct output with
250-- use_remote_estimate set to true.
251INSERT INTO f_test_tbl2 VALUES (50, 'TEMP1', NULL);
252INSERT INTO f_test_tbl2 VALUES (60, 'TEMP2', NULL);
253ALTER SERVER mysql_svr OPTIONS (use_remote_estimate 'true');
254SELECT t1.c1, t2.c1
255  FROM f_test_tbl2 t1 INNER JOIN f_test_tbl2 t2 ON t1.c1 = t2.c1
256  WHERE t1.c3 IS NULL ORDER BY 1, 2;
257SELECT t1.c1, t2.c1
258  FROM f_test_tbl2 t1 INNER JOIN f_test_tbl2 t2 ON t1.c1 = t2.c1 AND t1.c2 LIKE 'TEMP%'
259  ORDER BY 1, 2;
260DELETE FROM f_test_tbl2 WHERE c1 IN (50, 60);
261ALTER SERVER mysql_svr OPTIONS (SET use_remote_estimate 'false');
262
263-- FDW-169: Insert/Update/Delete on enum column.
264INSERT INTO f_enum_t1
265  VALUES (1, 'small'), (2, 'medium'), (3, 'medium'), (4, 'small');
266SELECT * FROM f_enum_t1 WHERE id = 4;
267UPDATE f_enum_t1 SET size = 'large' WHERE id = 4;
268SELECT * FROM f_enum_t1 WHERE id = 4;
269DELETE FROM f_enum_t1 WHERE size = 'large';
270SELECT * FROM f_enum_t1 WHERE id = 4;
271
272-- Negative scenarios for ENUM handling.
273-- Test that if we insert the ENUM value which is not present on MySQL side,
274-- but present on Postgres side.
275DROP FOREIGN TABLE f_enum_t1;
276DROP TYPE size_t;
277-- Create the type with extra enum values.
278CREATE TYPE size_t AS enum('small', 'medium', 'large', 'largest', '');
279CREATE FOREIGN TABLE f_enum_t1(id int, size size_t)
280  SERVER mysql_svr OPTIONS (dbname 'mysql_fdw_regress', table_name 'enum_t1');
281
282-- If we insert the enum value which is not present on MySQL side then it
283-- inserts empty string in ANSI_QUOTES sql_mode, so verify that.
284INSERT INTO f_enum_t1 VALUES (4, 'largest');
285SELECT * from f_enum_t1;
286DELETE FROM f_enum_t1 WHERE size = '';
287
288-- Postgres should throw an error as the value which we are inserting for enum
289-- column is not present in enum on Postgres side, no matter whether it is
290-- present on MySQL side or not. PG's sanity check itself throws an error.
291INSERT INTO f_enum_t1 VALUES (4, 'big');
292
293-- FDW-155: Enum data type can be handled correctly in select statements on
294-- foreign table.
295SELECT * FROM f_enum_t1 WHERE size = 'medium' ORDER BY id;
296
297-- Remote aggregate in combination with a local Param (for the output
298-- of an initplan)
299EXPLAIN (VERBOSE, COSTS OFF)
300SELECT EXISTS(SELECT 1 FROM pg_enum), sum(id) from f_enum_t1;
301SELECT EXISTS(SELECT 1 FROM pg_enum), sum(id) from f_enum_t1;
302
303-- Check with the IMPORT FOREIGN SCHEMA command.  Also, check ENUM types with
304-- the IMPORT FOREIGN SCHEMA command. If the enum name is the same for multiple
305-- tables, then it should handle correctly by prefixing the table name.
306CREATE TYPE enum_t1_size_t AS enum('small', 'medium', 'large');
307CREATE TYPE enum_t2_size_t AS enum('S', 'M', 'L');
308IMPORT FOREIGN SCHEMA mysql_fdw_regress LIMIT TO (enum_t1, enum_t2)
309  FROM SERVER mysql_svr INTO public;
310SELECT attrelid::regclass, atttypid::regtype FROM pg_attribute
311  WHERE (attrelid = 'enum_t1'::regclass OR attrelid = 'enum_t2'::regclass) AND
312    attnum > 1 ORDER BY 1;
313SELECT * FROM enum_t1 ORDER BY id;
314SELECT * FROM enum_t2 ORDER BY id;
315DROP FOREIGN TABLE enum_t1;
316DROP FOREIGN TABLE enum_t2;
317
318-- FDW-248: IMPORT FOREIGN SCHEMA command should work correctly if called
319-- multiple times. Earlier we wrongly used PG_TRY/CATCH block to get the server
320-- options without clearing the error state and that exceeded
321-- ERRORDATA_STACK_SIZE hard coded to 5.
322DO
323$DO$
324DECLARE
325  i int;
326BEGIN
327  FOR i IN 1..5
328  LOOP
329    IMPORT FOREIGN SCHEMA mysql_fdw_regress LIMIT TO (mysql_test)
330    FROM SERVER mysql_svr INTO public;
331
332    DROP FOREIGN TABLE mysql_test;
333  END LOOP;
334END;
335$DO$;
336
337-- Parameterized queries should work correctly.
338EXPLAIN (VERBOSE, COSTS OFF)
339SELECT c1, c2 FROM f_test_tbl1
340  WHERE c8 = (SELECT c1 FROM f_test_tbl2 WHERE c1 = (SELECT 20))
341  ORDER BY c1;
342SELECT c1, c2 FROM f_test_tbl1
343  WHERE c8 = (SELECT c1 FROM f_test_tbl2 WHERE c1 = (SELECT 20))
344  ORDER BY c1;
345
346SELECT * FROM f_test_tbl1
347  WHERE c8 NOT IN (SELECT c1 FROM f_test_tbl2 WHERE c1 = (SELECT 20))
348  ORDER BY c1;
349
350-- Check parameterized queries with text/varchar column, should not crash.
351CREATE FOREIGN TABLE f_test_tbl3 (c1 INTEGER, c2 text, c3 text)
352  SERVER mysql_svr OPTIONS (dbname 'mysql_fdw_regress', table_name 'test_tbl2');
353CREATE TABLE local_t1 (c1 INTEGER, c2 text);
354INSERT INTO local_t1 VALUES (1, 'SALES');
355
356SELECT c1, c2 FROM f_test_tbl3 WHERE c3 = (SELECT 'PUNE'::text) ORDER BY c1;
357SELECT c1, c2 FROM f_test_tbl2 WHERE c3 = (SELECT 'PUNE'::varchar) ORDER BY c1;
358
359SELECT * FROM local_t1 lt1 WHERE lt1.c1 =
360  (SELECT count(*) FROM f_test_tbl3 ft1 WHERE ft1.c2 = lt1.c2) ORDER BY lt1.c1;
361
362EXPLAIN (VERBOSE, COSTS OFF)
363SELECT c1, c2 FROM f_test_tbl1 WHERE c8 = (
364  SELECT c1 FROM f_test_tbl2 WHERE c1 = (
365    SELECT min(c1) + 1 FROM f_test_tbl2)) ORDER BY c1;
366SELECT c1, c2 FROM f_test_tbl1 WHERE c8 = (
367  SELECT c1 FROM f_test_tbl2 WHERE c1 = (
368    SELECT min(c1) + 1 FROM f_test_tbl2)) ORDER BY c1;
369
370SELECT * FROM f_test_tbl1 WHERE c1 = (SELECT 500) AND c2 = (
371  SELECT max(c2) FROM f_test_tbl1 WHERE c4 = (SELECT 600))
372  ORDER BY 1, 2;
373SELECT t1.c1, (SELECT c2 FROM f_test_tbl1 WHERE c1 =(SELECT 500))
374  FROM f_test_tbl2 t1, (
375    SELECT c1, c2 FROM f_test_tbl2 WHERE c1 > ANY (SELECT 20)) t2
376  ORDER BY 1, 2;
377
378-- FDW-255: Should throw an error when we select system attribute.
379SELECT xmin FROM f_test_tbl1;
380SELECT ctid, xmax, tableoid FROM f_test_tbl1;
381SELECT xmax, c1 FROM f_test_tbl1;
382SELECT count(tableoid) FROM f_test_tbl1;
383
384-- Cleanup
385DROP TABLE l_test_tbl1;
386DROP TABLE l_test_tbl2;
387DROP TABLE local_t1;
388DROP VIEW smpl_vw;
389DROP VIEW comp_vw;
390DROP VIEW ttest_tbl1_vw;
391DROP VIEW mul_tbl_view;
392DELETE FROM f_test_tbl1;
393DELETE FROM f_test_tbl2;
394DELETE FROM f_numbers;
395DELETE FROM f_enum_t1;
396DROP FOREIGN TABLE f_test_tbl1;
397DROP FOREIGN TABLE f_test_tbl2;
398DROP FOREIGN TABLE f_numbers;
399DROP FOREIGN TABLE f_mysql_test;
400DROP FOREIGN TABLE f_enum_t1;
401DROP FOREIGN TABLE f_test_tbl3;
402DROP TYPE size_t;
403DROP TYPE enum_t1_size_t;
404DROP TYPE enum_t2_size_t;
405DROP FUNCTION test_param_where();
406DROP FUNCTION test_param_where2(int, text);
407DROP USER MAPPING FOR public SERVER mysql_svr;
408DROP SERVER mysql_svr;
409DROP EXTENSION mysql_fdw;
410