openGauss-server/third_party/dependency/mysql_fdw/2-mysql_fdw-2.5.3_patch.patch

191 lines
8.6 KiB
Diff

diff --git expected/mysql_fdw.out expected/mysql_fdw.out
index 6048936..2d77913 100644
--- expected/mysql_fdw.out
+++ expected/mysql_fdw.out
@@ -10,6 +10,9 @@ CREATE FOREIGN TABLE department(department_id int, department_name text) SERVER
CREATE FOREIGN TABLE employee(emp_id int, emp_name text, emp_dept_id int) SERVER mysql_svr OPTIONS(dbname 'testdb', table_name 'employee');
CREATE FOREIGN TABLE empdata(emp_id int, emp_dat bytea) SERVER mysql_svr OPTIONS(dbname 'testdb', table_name 'empdata');
CREATE FOREIGN TABLE numbers(a int, b varchar(255)) SERVER mysql_svr OPTIONS (dbname 'testdb', table_name 'numbers');
+CREATE FOREIGN TABLE fdw126_ft1(stu_id int, stu_name varchar(255)) SERVER mysql_svr OPTIONS (dbname 'testdb1', table_name 'student');
+CREATE FOREIGN TABLE fdw126_ft2(stu_id int, stu_name varchar(255)) SERVER mysql_svr OPTIONS (table_name 'student');
+CREATE FOREIGN TABLE fdw126_ft3(a int, b varchar(255)) SERVER mysql_svr OPTIONS (dbname 'testdb1', table_name 'numbers');
SELECT * FROM department LIMIT 10;
department_id | department_name
---------------+-----------------
@@ -396,6 +399,46 @@ SELECT * FROM numbers ORDER BY 1 LIMIT 1;
1 | One
(1 row)
+-- FDW-126: Insert/update/delete statement failing in mysql_fdw by picking
+-- wrong database name.
+-- Verify the INSERT/UPDATE/DELETE operations on another foreign table which
+-- resides in the another database in MySQL. The previous commands performs
+-- the operation on foreign table created for tables in testdb MySQL database.
+-- Below operations will be performed for foreign table created for table in
+-- testdb1 MySQL database.
+INSERT INTO fdw126_ft1 VALUES(1, 'One');
+UPDATE fdw126_ft1 SET stu_name = 'one' WHERE stu_id = 1;
+DELETE FROM fdw126_ft1 WHERE stu_id = 1;
+-- Select on employee foreign table which is created for employee table from
+-- testdb MySQL database. This call is just to cross verify if everything is
+-- working correctly.
+SELECT * FROM employee ORDER BY 1 LIMIT 1;
+ emp_id | emp_name | emp_dept_id
+--------+----------+-------------
+ 1 | emp - 1 | 1
+(1 row)
+
+-- Insert into fdw126_ft2 table which does not have dbname specified while
+-- creating the foreign table, so it will consider the schema name of foreign
+-- table as database name and try to connect/lookup into that database. Will
+-- throw an error.
+INSERT INTO fdw126_ft2 VALUES(2, 'Two');
+ERROR: failed to execute the MySQL query:
+Unknown database 'public'
+-- Check with the same table name from different database. fdw126_ft3 is
+-- pointing to the testdb1.numbers and not testdb.numbers table.
+-- INSERT/UPDATE/DELETE should be failing. SELECT will return no rows.
+INSERT INTO fdw126_ft3 VALUES(1, 'One');
+ERROR: first column of remote table must be unique for INSERT/UPDATE/DELETE operation
+SELECT * FROM fdw126_ft3 ORDER BY 1 LIMIT 1;
+ a | b
+---+---
+(0 rows)
+
+UPDATE fdw126_ft3 SET b = 'one' WHERE a = 1;
+ERROR: first column of remote table must be unique for INSERT/UPDATE/DELETE operation
+DELETE FROM fdw126_ft3 WHERE a = 1;
+ERROR: first column of remote table must be unique for INSERT/UPDATE/DELETE operation
DELETE FROM employee;
DELETE FROM department;
DELETE FROM empdata;
@@ -406,6 +449,9 @@ DROP FOREIGN TABLE numbers;
DROP FOREIGN TABLE department;
DROP FOREIGN TABLE employee;
DROP FOREIGN TABLE empdata;
+DROP FOREIGN TABLE fdw126_ft1;
+DROP FOREIGN TABLE fdw126_ft2;
+DROP FOREIGN TABLE fdw126_ft3;
DROP USER MAPPING FOR postgres SERVER mysql_svr;
DROP SERVER mysql_svr;
DROP EXTENSION mysql_fdw CASCADE;
diff --git mysql_fdw.c mysql_fdw.c
index 2e520c2..eaba2e3 100644
--- mysql_fdw.c
+++ mysql_fdw.c
@@ -964,7 +964,12 @@ mysql_is_column_unique(Oid foreigntableid)
/* Build the query */
initStringInfo(&sql);
- appendStringInfo(&sql, "EXPLAIN %s", options->svr_table);
+ /*
+ * Construct the query by prefixing the database name so that it can lookup
+ * in correct database.
+ */
+ appendStringInfo(&sql, "EXPLAIN %s.%s", options->svr_database,
+ options->svr_table);
if (_mysql_query(conn, sql.data) != 0)
{
switch(_mysql_errno(conn))
diff --git mysql_init.sh mysql_init.sh
index a970f19..bea095d 100644
--- mysql_init.sh
+++ mysql_init.sh
@@ -4,4 +4,6 @@ mysql -h 127.0.0.1 -u foo -D testdb -e "CREATE TABLE department(department_id in
mysql -h 127.0.0.1 -u foo -D testdb -e "CREATE TABLE employee(emp_id int, emp_name text, emp_dept_id int, PRIMARY KEY (emp_id))"
mysql -h 127.0.0.1 -u foo -D testdb -e "CREATE TABLE empdata (emp_id int, emp_dat blob, PRIMARY KEY (emp_id))"
mysql -h 127.0.0.1 -u foo -D testdb -e "CREATE TABLE numbers (a int PRIMARY KEY, b varchar(255))"
-
+mysql -h 127.0.0.1 -u foo -D testdb -e "CREATE DATABASE testdb1"
+mysql -h 127.0.0.1 -u foo -D testdb1 -e "CREATE TABLE student (stu_id int PRIMARY KEY, stu_name text)"
+mysql -h 127.0.0.1 -u foo -D testdb1 -e "CREATE TABLE numbers (a int, b varchar(255))"
diff --git option.c option.c
index 880d984..574cb24 100644
--- option.c
+++ option.c
@@ -254,8 +254,19 @@ mysql_get_options(Oid foreignoid)
if (!opt->svr_port)
opt->svr_port = MYSQL_PORT;
- if (!opt->svr_table && f_table)
- opt->svr_table = get_rel_name(foreignoid);
+ /*
+ * When we don't have a table name or database name provided in the
+ * FOREIGN TABLE options, then use a foreign table name as the target table
+ * name and the namespace of the foreign table as a database name.
+ */
+ if (f_table)
+ {
+ if (!opt->svr_table)
+ opt->svr_table = get_rel_name(foreignoid);
+
+ if (!opt->svr_database)
+ opt->svr_database = get_namespace_name(get_rel_namespace(foreignoid));
+ }
return opt;
}
diff --git sql/mysql_fdw.sql sql/mysql_fdw.sql
index 4fd7ce3..b350c23 100644
--- sql/mysql_fdw.sql
+++ sql/mysql_fdw.sql
@@ -12,6 +12,9 @@ CREATE FOREIGN TABLE department(department_id int, department_name text) SERVER
CREATE FOREIGN TABLE employee(emp_id int, emp_name text, emp_dept_id int) SERVER mysql_svr OPTIONS(dbname 'testdb', table_name 'employee');
CREATE FOREIGN TABLE empdata(emp_id int, emp_dat bytea) SERVER mysql_svr OPTIONS(dbname 'testdb', table_name 'empdata');
CREATE FOREIGN TABLE numbers(a int, b varchar(255)) SERVER mysql_svr OPTIONS (dbname 'testdb', table_name 'numbers');
+CREATE FOREIGN TABLE fdw126_ft1(stu_id int, stu_name varchar(255)) SERVER mysql_svr OPTIONS (dbname 'testdb1', table_name 'student');
+CREATE FOREIGN TABLE fdw126_ft2(stu_id int, stu_name varchar(255)) SERVER mysql_svr OPTIONS (table_name 'student');
+CREATE FOREIGN TABLE fdw126_ft3(a int, b varchar(255)) SERVER mysql_svr OPTIONS (dbname 'testdb1', table_name 'numbers');
SELECT * FROM department LIMIT 10;
SELECT * FROM employee LIMIT 10;
@@ -110,6 +113,38 @@ SELECT * FROM numbers ORDER BY 1 LIMIT 1;
ALTER USER MAPPING FOR postgres SERVER mysql_svr OPTIONS(SET username :MYSQL_USER_NAME, SET password :MYSQL_PASS);
SELECT * FROM numbers ORDER BY 1 LIMIT 1;
+
+-- FDW-126: Insert/update/delete statement failing in mysql_fdw by picking
+-- wrong database name.
+
+-- Verify the INSERT/UPDATE/DELETE operations on another foreign table which
+-- resides in the another database in MySQL. The previous commands performs
+-- the operation on foreign table created for tables in testdb MySQL database.
+-- Below operations will be performed for foreign table created for table in
+-- testdb1 MySQL database.
+INSERT INTO fdw126_ft1 VALUES(1, 'One');
+UPDATE fdw126_ft1 SET stu_name = 'one' WHERE stu_id = 1;
+DELETE FROM fdw126_ft1 WHERE stu_id = 1;
+
+-- Select on employee foreign table which is created for employee table from
+-- testdb MySQL database. This call is just to cross verify if everything is
+-- working correctly.
+SELECT * FROM employee ORDER BY 1 LIMIT 1;
+
+-- Insert into fdw126_ft2 table which does not have dbname specified while
+-- creating the foreign table, so it will consider the schema name of foreign
+-- table as database name and try to connect/lookup into that database. Will
+-- throw an error.
+INSERT INTO fdw126_ft2 VALUES(2, 'Two');
+
+-- Check with the same table name from different database. fdw126_ft3 is
+-- pointing to the testdb1.numbers and not testdb.numbers table.
+-- INSERT/UPDATE/DELETE should be failing. SELECT will return no rows.
+INSERT INTO fdw126_ft3 VALUES(1, 'One');
+SELECT * FROM fdw126_ft3 ORDER BY 1 LIMIT 1;
+UPDATE fdw126_ft3 SET b = 'one' WHERE a = 1;
+DELETE FROM fdw126_ft3 WHERE a = 1;
+
DELETE FROM employee;
DELETE FROM department;
DELETE FROM empdata;
@@ -122,6 +157,9 @@ DROP FOREIGN TABLE numbers;
DROP FOREIGN TABLE department;
DROP FOREIGN TABLE employee;
DROP FOREIGN TABLE empdata;
+DROP FOREIGN TABLE fdw126_ft1;
+DROP FOREIGN TABLE fdw126_ft2;
+DROP FOREIGN TABLE fdw126_ft3;
DROP USER MAPPING FOR postgres SERVER mysql_svr;
DROP SERVER mysql_svr;
DROP EXTENSION mysql_fdw CASCADE;