diff --git a/expected/select.out b/expected/select.out index 9463d3f..16eb295 100644 --- a/expected/select.out +++ b/expected/select.out @@ -1419,6 +1419,20 @@ SELECT * FROM f_test_tbl1 WHERE c1::numeric = 12.2; Remote query: SELECT `c1`, `c2`, `c3`, `c4`, `c5`, `c6`, `c7`, `c8` FROM `mysql_fdw_regress`.`test_tbl1` WHERE ((`c1` = 12.2)) (3 rows) +-- FDW-408: Skip importing relations that have SET type because Postgres +-- doesn't have equivalent datatype which can be mapped to MySQL SET. +IMPORT FOREIGN SCHEMA mysql_fdw_regress LIMIT TO (test_set, mysql_test, test_tbl1) + FROM SERVER mysql_svr INTO public; +WARNING: skipping import for relation "test_set" +DETAIL: MySQL SET columns are not supported. +SELECT relname FROM pg_class + WHERE relname IN ('test_set', 'mysql_test', 'test_tbl1') AND relnamespace = 'public'::regnamespace; + relname +------------ + mysql_test + test_tbl1 +(2 rows) + -- Cleanup DROP TABLE l_test_tbl1; DROP TABLE l_test_tbl2; @@ -1440,6 +1454,8 @@ DROP FOREIGN TABLE f_test_tbl3; DROP FOREIGN TABLE test5; DROP FOREIGN TABLE test5_1; DROP FOREIGN TABLE test5_2; +DROP FOREIGN TABLE mysql_test; +DROP FOREIGN TABLE test_tbl1; DROP TYPE size_t; DROP TYPE enum_t1_size_t; DROP TYPE enum_t2_size_t; diff --git a/mysql_fdw.c b/mysql_fdw.c index faddbab..a90de78 100644 --- a/mysql_fdw.c +++ b/mysql_fdw.c @@ -2228,6 +2228,7 @@ mysqlImportForeignSchema(ImportForeignSchemaStmt *stmt, Oid serverOid) { char *tablename = row[0]; bool first_item = true; + bool has_set = false; resetStringInfo(&buf); appendStringInfo(&buf, "CREATE FOREIGN TABLE %s (\n", @@ -2242,8 +2243,12 @@ mysqlImportForeignSchema(ImportForeignSchemaStmt *stmt, Oid serverOid) char *attnotnull; char *attdefault; - /* If table has no columns, we'll see nulls here */ - if (row[1] == NULL) + /* + * If the table has no columns, we'll see nulls here. Also, if we + * have already discovered this table has a SET type column, we + * better skip the rest of the checking. + */ + if (row[1] == NULL || has_set) continue; attname = row[1]; @@ -2262,6 +2267,21 @@ mysqlImportForeignSchema(ImportForeignSchemaStmt *stmt, Oid serverOid) errhint("If you encounter an error, you may need to execute the following first:\nDO $$BEGIN IF NOT EXISTS (SELECT 1 FROM pg_catalog.pg_type WHERE typname = '%s') THEN CREATE TYPE %s AS %s; END IF; END$$;\n", typename, typename, typedfn))); + /* + * PostgreSQL does not have an equivalent data type to map with + * SET, so skip the table definitions for the ones having SET type + * column. + */ + if (strncmp(typedfn, "set", 3) == 0) + { + ereport(WARNING, + (errmsg("skipping import for relation \"%s\"", quote_identifier(tablename)), + errdetail("MySQL SET columns are not supported."))); + + has_set = true; + continue; + } + if (first_item) first_item = false; else @@ -2282,6 +2302,13 @@ mysqlImportForeignSchema(ImportForeignSchemaStmt *stmt, Oid serverOid) while ((row = mysql_fetch_row(res)) && (strcmp(row[0], tablename) == 0)); + /* + * As explained above, skip importing relations that have SET type + * column. + */ + if (has_set) + continue; + /* * Add server name and table-level options. We specify remote * database and table name as options (the latter to ensure that diff --git a/mysql_init.sh b/mysql_init.sh index 624e577..18e1472 100755 --- a/mysql_init.sh +++ b/mysql_init.sh @@ -36,6 +36,7 @@ mysql -h $MYSQL_HOST -u $MYSQL_USER_NAME -P $MYSQL_PORT -D mysql_fdw_regress -e mysql -h $MYSQL_HOST -u $MYSQL_USER_NAME -P $MYSQL_PORT -D mysql_fdw_regress -e "DROP TABLE IF EXISTS test3;" mysql -h $MYSQL_HOST -u $MYSQL_USER_NAME -P $MYSQL_PORT -D mysql_fdw_regress -e "DROP TABLE IF EXISTS test4;" mysql -h $MYSQL_HOST -u $MYSQL_USER_NAME -P $MYSQL_PORT -D mysql_fdw_regress -e "DROP TABLE IF EXISTS test5;" +mysql -h $MYSQL_HOST -u $MYSQL_USER_NAME -P $MYSQL_PORT -D mysql_fdw_regress -e "DROP TABLE IF EXISTS test_set;" mysql -h $MYSQL_HOST -u $MYSQL_USER_NAME -P $MYSQL_PORT -D mysql_fdw_regress -e "CREATE TABLE mysql_test(a int primary key, b int);" mysql -h $MYSQL_HOST -u $MYSQL_USER_NAME -P $MYSQL_PORT -D mysql_fdw_regress -e "INSERT INTO mysql_test(a,b) VALUES (1,1);" @@ -55,3 +56,4 @@ mysql -h $MYSQL_HOST -u $MYSQL_USER_NAME -P $MYSQL_PORT -D mysql_fdw_regress -e mysql -h $MYSQL_HOST -u $MYSQL_USER_NAME -P $MYSQL_PORT -D mysql_fdw_regress -e "CREATE TABLE test4 (c1 int PRIMARY KEY, c2 int, c3 varchar(255))" mysql -h $MYSQL_HOST -u $MYSQL_USER_NAME -P $MYSQL_PORT -D mysql_fdw_regress -e "CREATE TABLE test5 (c1 int primary key, c2 binary, c3 binary(3), c4 binary(1), c5 binary(10), c6 varbinary(3), c7 varbinary(1), c8 varbinary(10), c9 binary(0), c10 varbinary(0));" mysql -h $MYSQL_HOST -u $MYSQL_USER_NAME -P $MYSQL_PORT -D mysql_fdw_regress -e "INSERT INTO test5 VALUES (1, 'c', 'c3c', 't', 'c5c5c5', '04', '1', '01-10-2021', NULL, '');" +mysql -h $MYSQL_HOST -u $MYSQL_USER_NAME -P $MYSQL_PORT -D mysql_fdw_regress -e "CREATE TABLE test_set (c1 int primary key, c2 SET('a', 'b', 'c', 'd'), c3 int);" diff --git a/sql/select.sql b/sql/select.sql index e16fe68..4386ffe 100644 --- a/sql/select.sql +++ b/sql/select.sql @@ -420,6 +420,13 @@ SELECT * FROM f_test_tbl1 WHERE c1 = 12.2; EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM f_test_tbl1 WHERE c1::numeric = 12.2; +-- FDW-408: Skip importing relations that have SET type because Postgres +-- doesn't have equivalent datatype which can be mapped to MySQL SET. +IMPORT FOREIGN SCHEMA mysql_fdw_regress LIMIT TO (test_set, mysql_test, test_tbl1) + FROM SERVER mysql_svr INTO public; +SELECT relname FROM pg_class + WHERE relname IN ('test_set', 'mysql_test', 'test_tbl1') AND relnamespace = 'public'::regnamespace; + -- Cleanup DROP TABLE l_test_tbl1; DROP TABLE l_test_tbl2; @@ -441,6 +448,8 @@ DROP FOREIGN TABLE f_test_tbl3; DROP FOREIGN TABLE test5; DROP FOREIGN TABLE test5_1; DROP FOREIGN TABLE test5_2; +DROP FOREIGN TABLE mysql_test; +DROP FOREIGN TABLE test_tbl1; DROP TYPE size_t; DROP TYPE enum_t1_size_t; DROP TYPE enum_t2_size_t;