Giter Site home page Giter Site logo

mysql_fdw's Introduction

MySQL Foreign Data Wrapper for PostgreSQL

This is a foreign data wrapper (FDW) to connect PostgreSQL to MySQL.

Please note that this version of mysql_fdw works with PostgreSQL and EDB Postgres Advanced Server 12, 13, 14, 15, 16, and 17.

Contents

  1. Features
  2. Supported platforms
  3. Installation
  4. Usage
  5. Functions
  6. Generated columns
  7. Examples
  8. Limitations
  9. Contributing
  10. Support
  11. Useful links
  12. License

Features

Common features & enhancements

The following enhancements are added to the latest version of mysql_fdw:

Write-able FDW

The previous version was only read-only, the latest version provides the write capability. The user can now issue an insert, update, and delete statements for the foreign tables using the mysql_fdw. It uses the PG type casting mechanism to provide opposite type casting between MySQL and PG data types.

Connection Pooling

The latest version comes with a connection pooler that utilises the same MySQL database connection for all the queries in the same session. The previous version would open a new MySQL database connection for every query. This is a performance enhancement.

Prepared Statement

(Refactoring for select queries to use prepared statement)

The select queries are now using prepared statements instead of simple query protocol.

Pushdowning

WHERE clause push-down

The latest version will push-down the foreign table where clause to the foreign server. The where condition on the foreign table will be executed on the foreign server hence there will be fewer rows to bring across to PostgreSQL. This is a performance feature.

Column push-down

The previous version was fetching all the columns from the target foreign table. The latest version does the column push-down and only brings back the columns that are part of the select target list. This is a performance feature.

JOIN push-down

mysql_fdw now also supports join push-down. The joins between two foreign tables from the same remote MySQL server are pushed to a remote server, instead of fetching all the rows for both the tables and performing a join locally, thereby enhancing the performance. Currently, joins involving only relational and arithmetic operators in join-clauses are pushed down to avoid any potential join failure. Also, only the INNER and LEFT/RIGHT OUTER joins are supported, and not the FULL OUTER, SEMI, and ANTI join. This is a performance feature.

AGGREGATE push-down

mysql_fdw now also supports aggregate push-down. Push aggregates to the remote MySQL server instead of fetching all of the rows and aggregating them locally. This gives a very good performance boost for the cases where aggregates can be pushed down. The push-down is currently limited to aggregate functions min, max, sum, avg, and count, to avoid pushing down the functions that are not present on the MySQL server. Also, aggregate filters and orders are not pushed down.

ORDER BY push-down

mysql_fdw now also supports order by push-down. If possible, push order by clause to the remote server so that we get the ordered result set from the foreign server itself. It might help us to have an efficient merge join. NULLs behavior is opposite on the MySQL server. Thus to get an equivalent result, we add the "expression IS NULL" clause at the beginning of each of the ORDER BY expressions.

LIMIT OFFSET push-down

mysql_fdw now also supports limit offset push-down. Wherever possible, perform LIMIT and OFFSET operations on the remote server. This reduces network traffic between local PostgreSQL and remote MySQL servers. ALL/NULL options are not supported on the MySQL server, and thus they are not pushed down. Also, OFFSET without LIMIT is not supported on the MySQL server hence queries having that construct are not pushed.

Supported platforms

mysql_fdw was developed on Linux, and should run on any reasonably POSIX-compliant system.

Please refer to mysql_fdw_documentation.

Installation

Prerequisites

To compile the MySQL foreign data wrapper, MySQL's C client library is needed. This library can be downloaded from the official MySQL website.

Source installation

  1. To build on POSIX-compliant systems you need to ensure the pg_config executable is in your path when you run make. This executable is typically in your PostgreSQL installation's bin directory. For example:

    $ export PATH=/usr/local/pgsql/bin/:$PATH
    
  2. The mysql_config must also be in the path, it resides in the MySQL bin directory.

    $ export PATH=/usr/local/mysql/bin/:$PATH
    
  3. Compile the code using make.

    $ make USE_PGXS=1
    
  4. Finally install the foreign data wrapper.

    $ make USE_PGXS=1 install
    
  5. Running regression test.

    $ make USE_PGXS=1 installcheck
    

    However, make sure to set the MYSQL_HOST, MYSQL_PORT, MYSQL_USER_NAME, and MYSQL_PWD environment variables correctly. The default settings can be found in the mysql_init.sh script.

If you run into any issues, please let us know.

Usage

CREATE SERVER options

mysql_fdw accepts the following options via the CREATE SERVER command:

  • host as string, optional, default 127.0.0.1

    Address or hostname of the MySQL server.

  • port as integer, optional, default 3306

    Port number of the MySQL server.

  • secure_auth as boolean, optional, default true

    Enable or disable secure authentication.

  • init_command as string, optional, no default

    SQL statement to execute when connecting to the MySQL server.

  • use_remote_estimate as boolean, optional, default false

    Controls whether mysql_fdw issues remote EXPLAIN commands to obtain cost estimates.

  • reconnect as boolean, optional, default false

    Enable or disable automatic reconnection to the MySQL server if the existing connection is found to have been lost.

  • sql_mode as string, optional, default ANSI_QUOTES

    Set MySQL sql_mode for established connection.

  • ssl_key as string, optional, no default

    The path name of the client private key file.

  • ssl_cert as string, optional, no default

    The path name of the client public key certificate file.

  • ssl_ca as string, optional, no default

    The path name of the Certificate Authority (CA) certificate file. This option, if used, must specify the same certificate used by the server.

  • ssl_capath as string, optional, no default

    The path name of the directory that contains trusted SSL CA certificate files.

  • ssl_cipher as string, optional, no default

    The list of permissible ciphers for SSL encryption.

  • fetch_size as integer, optional, default 100

    This option specifies the number of rows mysql_fdw should get in each fetch operation. It can be specified for a foreign table or a foreign server. The option specified on a table overrides an option specified for the server.

  • character_set as string, optional, default auto

    The character set to use for MySQL connection. Default is auto which means autodetect based on the operating system setting. Before the introduction of the character_set option, the character set was set similar to the PostgreSQL database encoding. To get this older behavior set the character_set to special value PGDatabaseEncoding.

  • mysql_default_file as string, optional, no default

    Set the MySQL default file path if connection details, such as username, password, etc., need to be picked from the default file.

  • truncatable as boolean, optional, default true

    This option controls whether mysql_fdw allows foreign tables to be truncated using the TRUNCATE command. It can be specified for a foreign table or a foreign server. A table-level option overrides a server-level option.

CREATE USER MAPPING options

mysql_fdw accepts the following options via the CREATE USER MAPPING command:

  • username as string, no default

    Username to use when connecting to MySQL.

  • password as string, no default

    Password to authenticate to the MySQL server with.

CREATE FOREIGN TABLE options

mysql_fdw accepts the following table-level options via the CREATE FOREIGN TABLE command.

  • dbname as string, mandatory

    Name of the MySQL database to query. This is a mandatory option.

  • table_name as string, optional, default name of foreign table

    Name of the MySQL table.

  • fetch_size as integer, optional

    Same as fetch_size parameter for foreign server.

  • max_blob_size as integer, optional

    Max blob size to read without truncation.

  • truncatable as boolean, optional, default true

    The same as foreign server option.

IMPORT FOREIGN SCHEMA options

mysql_fdw supports IMPORT FOREIGN SCHEMA and accepts the following custom options:

  • import_default as boolean, optional, default false

    This option controls whether column DEFAULT expressions are included in the definitions of foreign tables imported from a foreign server.

  • import_not_null as boolean, optional, default true

    This option controls whether column NOT NULL constraints are included in the definitions of foreign tables imported from a foreign server.

  • import_enum_as_text as boolean, optional, default false

    This option can be used to map MySQL ENUM type to TEXT type in the definitions of foreign tables, otherwise emit a warning for type to be created.

  • import_generated as boolean, optional, default true

    This option controls whether GENERATED column expressions are included in the definitions of foreign tables imported from a foreign server or not. The IMPORT will fail altogether if an imported generated expression uses a function or operator that does not exist on PostgreSQL.

TRUNCATE support

mysql_fdw implements the foreign data wrapper TRUNCATE API, available from PostgreSQL 14. MySQL does provide a TRUNCATE command, see https://dev.mysql.com/doc/refman/8.4/en/truncate-table.html.

Following restrictions apply:

  • TRUNCATE ... CASCADE is not supported
  • TRUNCATE ... RESTART IDENTITY is not supported and ignored
  • TRUNCATE ... CONTINUE IDENTITY is not supported and ignored
  • MySQL tables with foreign key references cannot be truncated

Functions

As well as the standard mysql_fdw_handler() and mysql_fdw_validator() functions, mysql_fdw provides the following user-callable utility functions:

  • mysql_fdw_version()

    Returns the version number as an integer.

  • mysql_fdw_display_pushdown_list()

    Displays the mysql_fdw_pushdown.config file contents.

Generated columns

Note that while mysql_fdw will insert or update the generated column value in MySQL, there is nothing to stop the value being modified within MySQL, and hence no guarantee that in subsequent SELECT operations the column will still contain the expected generated value. This limitation also applies to postgres_fdw.

For more details on generated columns see:

Examples

Install the extension:

Once for a database you need, as PostgreSQL superuser.

	-- load extension first time after install
	CREATE EXTENSION mysql_fdw;

Create a foreign server with appropriate configuration:

Once for a foreign datasource you need, as PostgreSQL superuser.

	-- create server object
	CREATE SERVER mysql_server
	FOREIGN DATA WRAPPER mysql_fdw
	OPTIONS (host '127.0.0.1', port '3306');

Grant usage on foreign server to normal user in PostgreSQL:

Once for a normal user (non-superuser) in PostgreSQL, as PostgreSQL superuser. It is a good idea to use a superuser only where really necessary, so let's allow a normal user to use the foreign server (this is not required for the example to work, but it's security recommendation).

	GRANT USAGE ON FOREIGN SERVER mysql_server TO pguser;

Where pguser is a sample user for works with foreign server (and foreign tables).

User mapping

Create an appropriate user mapping:

	-- create user mapping
	CREATE USER MAPPING FOR pguser
	SERVER mysql_server
	OPTIONS (username 'foo', password 'bar');

Where pguser is a sample user for works with foreign server (and foreign tables).

Create foreign table

All CREATE FOREIGN TABLE SQL commands can be executed as a normal PostgreSQL user if there were correct GRANT USAGE ON FOREIGN SERVER. No need PostgreSQL supersuer for security reasons but also works with PostgreSQL supersuer.

Please specify table_name option if MySQL table name is different from foreign table name.

	-- create foreign table
	CREATE FOREIGN TABLE warehouse (
	  warehouse_id int,
	  warehouse_name text,
	  warehouse_created timestamp
	)
	SERVER mysql_server
	OPTIONS (dbname 'db', table_name 'warehouse');

Some other operations with foreign table data

-- insert new rows in table
INSERT INTO warehouse values (1, 'UPS', current_date);
INSERT INTO warehouse values (2, 'TV', current_date);
INSERT INTO warehouse values (3, 'Table', current_date);

-- select from table
SELECT * FROM warehouse ORDER BY 1;

warehouse_id | warehouse_name | warehouse_created
-------------+----------------+-------------------
           1 | UPS            | 10-JUL-20 00:00:00
           2 | TV             | 10-JUL-20 00:00:00
           3 | Table          | 10-JUL-20 00:00:00

-- delete row from table
DELETE FROM warehouse where warehouse_id = 3;

-- update a row of table
UPDATE warehouse set warehouse_name = 'UPS_NEW' where warehouse_id = 1;

-- explain a table with verbose option
EXPLAIN VERBOSE SELECT warehouse_id, warehouse_name FROM warehouse WHERE warehouse_name LIKE 'TV' limit 1;

                                   QUERY PLAN
--------------------------------------------------------------------------------------------------------------------
Limit  (cost=10.00..11.00 rows=1 width=36)
	Output: warehouse_id, warehouse_name
	->  Foreign Scan on public.warehouse  (cost=10.00..1010.00 rows=1000 width=36)
		Output: warehouse_id, warehouse_name
		Local server startup cost: 10
		Remote query: SELECT `warehouse_id`, `warehouse_name` FROM `db`.`warehouse` WHERE ((`warehouse_name` LIKE BINARY 'TV'))

Import a MySQL database as schema to PostgreSQL:

	IMPORT FOREIGN SCHEMA someschema
	FROM SERVER mysql_server
	INTO public;

Limitations

Yet not described.

For more details, please refer to mysql_fdw documentation.

Contributing

If you experience any bug and have a fix for that, or have a new idea, create a ticket on github page. Before creating a pull request please read the contributing guidelines.

Support

This project will be modified to maintain compatibility with new PostgreSQL and EDB Postgres Advanced Server releases.

If you require commercial support, please contact the EnterpriseDB sales team, or check whether your existing PostgreSQL support provider can also support mysql_fdw.

Useful links

Source code

Reference FDW implementation, postgres_fdw

General FDW Documentation

Other FDWs

License

Copyright (c) 2011-2024, EnterpriseDB Corporation.

Permission to use, copy, modify, and distribute this software and its documentation for any purpose, without fee, and without a written agreement is hereby granted, provided that the above copyright notice and this paragraph and the following two paragraphs appear in all copies.

See the LICENSE file for full details.

mysql_fdw's People

Contributors

amutu avatar atkinschang avatar blazek avatar davidboone avatar davidfetter avatar df7cb avatar dpage avatar fclairamb avatar gabbasb avatar glynastill avatar ibrarahmad avatar ibrarahmed1974 avatar infosec812 avatar jeevanchalke avatar jeevanladhe avatar jjthiessen avatar mithuncy avatar nikicat avatar nyov avatar sahapasci avatar sir-galahad avatar snaga avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mysql_fdw's Issues

Timeout or limit on the amount of results

Hi guys,

I'm using this FDW to migrate a large mysql database. I started by the smaller table that contains around 6 million rows. After the foreign table is created if I issue a count(*) on that table I consistently get 1537820 rows instead of 5919560 reported by mysql using the same query. I had a look at the source code to see if the wrapper limits the time a query takes to execute or if there is a limit of rows returned by the wrapper with no success.

Any ideas on how to fix this issue?

P.S.: Using postgres 9.3.5 with latest mysql_fdw and mysql 5.6.13. Both servers running Ubuntu 12.04.4 LTS

dlopen(libmysqlclient.dylib, 1): image not found

Mac OS-X 10.9.5: I followed instructions
All went well.

I tried:
CREATE EXTENSION mysql_fdw;

I Got:
ERROR: failed to load the mysql query:
dlopen(libmysqlclient.dylib, 1): image not found
HINT: export LD_LIBRARY_PATH to locate the library

********** Error **********

ERROR: failed to load the mysql query:
dlopen(libmysqlclient.dylib, 1): image not found
SQL state: HV00L
Hint: export LD_LIBRARY_PATH to locate the library

IMPORT FOREIGN SCHEMA

...is not yet implemented.

This would be super handy now, even though it's a 9.5 feature.

"bit" column type

I'm using mysql_fdw for migrating from an existing mysql database that uses bit(1) columns. When performing a select on the foreign table (where a column value is b'1'), I'm presented with an error message ' "" is not a valid binary digit '. When the same column contains b'0', everything appears to work as expected.

Sending additional connection parameters

G'day,

this might be the wrong location, but we have used the mysql fdw to help migrate off a number of old (but production) mysql servers... so thank you.

Our problem is now an upgrade of a 'very' legacy system. The only way we can connect is by setting secure-auth to 'disabled', i.e. by including the --skip-secure-auth flag.

Is it possible to somehow include that in the options for the connection? Or do I need to learn C?

cheers

Ben

Dropped Connection

I am getting the following error:

# explain select id from fdw_mysql_table limit 10;
ERROR:  failed to execute the MySQL query: 
MySQL server has gone away

Until I restart my postgres session I cannot preform any more queries.

fdw not supported Chinese

query the foreign table contains Chinese content, shows '????'

mysql 5.0.77 utf8
postgresql 9.1 utf8

Not all backends support EXPLAIN

Hello.

I tried to use this one to talk to sphinxsearch. This is full-text indexing service that has mysql protocol support for querying/updating realtime indices. But alas it doesn't support EXPLAIN at all.

Is there any possibility to ditch using EXPLAIN for specified server or somehow preset EXPLAIN results as all sphinx indices are actually have the same structure (first field indexed, second is a mapping and can be queried fast too).

Dumping Large Table

I am trying to create a materialized view of a fdw table that has 22,596,915 rows using the following commands:

CREATE FOREIGN TABLE fdw_mysql_table (
    id                   INTEGER      ,
    ...
) SERVER fdw_mysql_server OPTIONS (dbname 'db', table_name 'table');

CREATE MATERIALIZED VIEW mview_fdw_mysql_table AS
    SELECT * FROM fdw_mysql_table;
SELECT 159822
Time: 1185316.779 ms

When I try to run the query again I get the following error:

ERROR:  failed to execute the MySQL query: 
MySQL server has gone away

Is there something special that needs to be done when dumping a large table?

Problems compiling and installing in windows 7

I have 2 issues trying to use mysql_fdw in 64bit windows 7. Compile will fail if RTLD_LAZY and RTLD_DEEPBIND in the function mysql_load_library() in mysql_fdw.c are not explicitly initialized. It will compile if they are initialized. However, installing the extension using:

CREATE EXTENSION mysql_fdw;

will crash the server. The server log reports:

2015-02-27 10:15:10 CST LOG: server process (PID 1216) was terminated by exception 0xC0000005

2015-02-27 10:15:10 CST DETAIL: Failed process was running: CREATE EXTENSION mysql_fdw;

2015-02-27 10:15:10 CST HINT: See C include file "ntstatus.h" for a description of the hexadecimal value.

I am compiling against postgresql version 9.4.1 and mysql 5.6.23.0 using microsoft visual studio express 2013. I am trying to install into the official 9.4.1 64bit windows release. I am compiling as 64bit. Are there any dependencies that mysql_fdw requires? It could be possible that my build environment is deficient..

Error on ILike

hi, i tried to run a query with a ilike but it seems to fail

select * from remote_mysql_table where name ilike '%hello%'

i got

ERROR:  failed to prepare the MySQL query: 
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '~~* '%hello%'))' at line 1
********** Error **********

ERROR: failed to prepare the MySQL query: 
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '~~* '%hello%'))' at line 1
State SQL :HV00L

pg "auto-cast" in stored functions causes mysql syntax error

CREATE FOREIGN TABLE foreign_users(
     id bigint,
     username varchar(255)
)
SERVER f_mysql OPTIONS (dbname 'db', table_name 'users');

Query ОК

SELECT U.id FROM foreign_users AS U WHERE U.username = 'test';
  id   
-------
 33088
(1 row)

Call function Error

create or replace function get_user(_username varchar) returns bigint as $$
        SELECT 
            U.id
        FROM foreign_users AS U
        WHERE U.username = _username;
$$ language sql;

select * from  get_user('test');

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '::character varying))' at line 1

Connection Pooling

I created two different servers to the same mysql database:

CREATE SERVER fdw_mysql_read FOREIGN DATA WRAPPER mysql_fdw OPTIONS (
    host 'XXX.XXX.XXX.XXX', port '3306'
);
CREATE SERVER fdw_mysql_write FOREIGN DATA WRAPPER mysql_fdw OPTIONS (
    host 'XXX.XXX.XXX.XXX', port '3306'
);

I then created two different user mappings, one for each server:

CREATE USER MAPPING FOR postgres SERVER fdw_mysql_read OPTIONS (username 'read'  , password 'XXX');
CREATE USER MAPPING FOR postgres SERVER fdw_mysql_write OPTIONS (username 'write'  , password 'XXX');

The write user has all access on the write table and the read user only has select on the read table.
I then made two different tables one using the fdw_mysql_read server and one using the fdw_mysql_write:

CREATE FOREIGN TABLE fdw_mysql_read_table (
    id   INTEGER,
    name VARCHAR(32)
) SERVER fdw_mysql_read OPTIONS (dbname 'db', table_name 'table_read');
CREATE FOREIGN TABLE fdw_mysql_write_table (
    id   INTEGER,
    name VARCHAR(32)
) SERVER fdw_mysql_write OPTIONS (dbname 'db', table_name 'table_write');

Once I run a query all subsequent queries are sent over using the permissions from the mapping of based on that first query. I don't think it is respecting the mapping for server the table references. It might be an issue with the connection pooling.

Relative date comparisons

Thanks for all the hard work! I'm trying to execute queries with where clauses using relative timestamps. However, it looks like because the mysql and postgres time subtraction approaches are different, this isn't working: I'm receiving errors like ERROR: failed to prepare the MySQL query: FUNCTION mysql_fdw.now does not exist..

Although the where clauses are pushed down to Mysql, using mysql-only functions appears does not appear to work either: ERROR: function date_sub(timestamp with time zone, interval) does not exist.

For example, in mysql a relevant query would be:

CREATE TABLE `foos` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `created_at` datetime NOT NULL,
  PRIMARY KEY (`id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

SELECT count(*)
FROM foos
WHERE created_at > date_sub(NOW(), INTERVAL '30' DAY);

On the postgres side, the query in straight postgres syntax would be:

SELECT count(*)
FROM foreign_mysql.foos
WHERE created_at > now() - interval '30' DAY;

I've taken a look at #42, but it seems like this might be a separate issue.

cc @supershabam

DML

Hi,
Great FDW. Would you like to INSERT, UPDATE or DELETE. It is possible?

fails to compile on DragonFlyBSD 4.2.3

gmake USE_PGXS=1
cc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -pipe -O2 -fno-strict-aliasing -fPIC -DPIC -I/usr/local/include/mysql -D _MYSQL_LIBNAME="libmysqlclient.so" -I. -I./ -I/usr/local/include/postgresql/server -I/usr/local/include/postgresql/internal -I/usr/local/include -I/usr/local/include/libxml2 -I/usr/include -I/usr/local/include -I/usr/local/include -c -o connection.o connection.c
cc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -pipe -O2 -fno-strict-aliasing -fPIC -DPIC -I/usr/local/include/mysql -D _MYSQL_LIBNAME="libmysqlclient.so" -I. -I./ -I/usr/local/include/postgresql/server -I/usr/local/include/postgresql/internal -I/usr/local/include -I/usr/local/include/libxml2 -I/usr/include -I/usr/local/include -I/usr/local/include -c -o option.o option.c
cc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -pipe -O2 -fno-strict-aliasing -fPIC -DPIC -I/usr/local/include/mysql -D _MYSQL_LIBNAME="libmysqlclient.so" -I. -I./ -I/usr/local/include/postgresql/server -I/usr/local/include/postgresql/internal -I/usr/local/include -I/usr/local/include/libxml2 -I/usr/include -I/usr/local/include -I/usr/local/include -c -o deparse.o deparse.c
cc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -pipe -O2 -fno-strict-aliasing -fPIC -DPIC -I/usr/local/include/mysql -D _MYSQL_LIBNAME="libmysqlclient.so" -I. -I./ -I/usr/local/include/postgresql/server -I/usr/local/include/postgresql/internal -I/usr/local/include -I/usr/local/include/libxml2 -I/usr/include -I/usr/local/include -I/usr/local/include -c -o mysql_query.o mysql_query.c
cc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -pipe -O2 -fno-strict-aliasing -fPIC -DPIC -I/usr/local/include/mysql -D _MYSQL_LIBNAME="libmysqlclient.so" -I. -I./ -I/usr/local/include/postgresql/server -I/usr/local/include/postgresql/internal -I/usr/local/include -I/usr/local/include/libxml2 -I/usr/include -I/usr/local/include -I/usr/local/include -c -o mysql_fdw.o mysql_fdw.c
mysql_fdw.c: In function 'mysql_load_library':
mysql_fdw.c:176:56: error: 'RTLD_DEEPBIND' undeclared (first use in this function)
mysql_dll_handle = dlopen(_MYSQL_LIBNAME, RTLD_LAZY | RTLD_DEEPBIND);
^
mysql_fdw.c:176:56: note: each undeclared identifier is reported only once for each function it appears in
: recipe for target 'mysql_fdw.o' failed
gmake: *** [mysql_fdw.o] Error 1

uname -a
DragonFly vola 4.2-RELEASE DragonFly v4.2.3.2.g6ca39-RELEASE #3: Mon Jul 20 22:51:17 CEST 2015 [email protected]:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64

query with a function doesn't work

I have this query:
SELECT * FROM some_foreign_table WHERE date(datetime_column)='2013-08-30';
and after sent I get this error:
ERROR: failed to prepare the MySQL query: FUNCTION db.date does not exist

Subquery returns NULL instead of values

Having the following schema in MySQL: http://sqlfiddle.com/#!2/b0902/2
I do the following in PostgreSQL 9.3.2 with mysql_fdw (commit df035c0):

byzon=# CREATE FOREIGN TABLE foo (id int) SERVER mysql_orion1984 OPTIONS (table 'mercatos.foo');
CREATE FOREIGN TABLE
byzon=# CREATE FOREIGN TABLE bar (id int, v text) SERVER mysql_orion1984 OPTIONS (table 'mercatos.bar');
CREATE FOREIGN TABLE
byzon=# SELECT foo.id, (SELECT bar.v FROM bar WHERE bar.id = foo.id) AS v FROM foo;
 id | v
----+----
  1 | t1
  2 |
  3 |
(3 rows)

byzon=#

(The plan of the last SELECT is: http://explain.depesz.com/s/b4o).

Expected result:

 id | v
----+----
  1 | t1
  2 | t2
  3 | t3

Workaround is to copy the tables to PostgreSQL:

byzon=# CREATE TABLE foo_ AS SELECT * FROM foo;
SELECT 3
byzon=# CREATE TABLE bar_ AS SELECT * FROM bar;
SELECT 3
byzon=# SELECT foo_.id, (SELECT bar_.v FROM bar_ WHERE bar_.id = foo_.id) AS v FROM foo_;
 id | v
----+----
  1 | t1
  2 | t2
  3 | t3
(3 rows)

avoid confusion with dpage mysql_fdw

When you grab mysql_fdw from pgxn you get an old version from dpage.
the version reported by pg is 1.0 ... same as the version here...

it might be a good idea to upgrade version or change name or smth to be able to distinguish them ...
and to update pgxn.org with the related info to avoid any confusion

Thanks

DELETE causes "server closed the connection unexpectedly" Error

I set up a simple FOREIGN table to mysql (v 5.1.71) using both today's master and the REL_2_0_1 versions and whenever I issue a DELETE FROM I always get this error:

`
postgres=# delete from tester where dir='ABC';

server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
The connection to the server was lost. Attempting reset: Failed.
!>
`

I'm a PG noob so I don't really know where to start troubleshooting but if I reconnect I see that the delete actually completed (the row is gone). I'm guessing I must be doing something really stupid as the build and install of the fdw was super easy/pain free. I created the foreign table and all of the dependencies following the example in the README.

Any ideas on where I can start to figure out what's going on? FWIW I don't see any error in the mysql log.

Thanks,

JPS

IN clause does not work

Trying to execute a simple query that contains an IN clause.

SELECT * FROM mysql_driver WHERE id IN (1,2,3)

This is the error I'm receiving:

ERROR: failed to execute the MySQL query:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''{1,2,3}')))' at line 1

If I retrieve the ids with a subquery, it works.

SELECT * FROM mysql_driver WHERE id IN (SELECT id FROM mysql_driver WHERE id < 4)

Cannot create foreign table based on a view

ERROR:  failed to execute the MySQL query: 
EXPLAIN/SHOW can not be issued; lacking privileges for underlying table

There are no underlying permissions issues, I can select from the view using the normal mysql client.

Long field names not working?

My FDW table schema is:

CREATE FOREIGN TABLE liquorstore_backendipaddress (
    id bigint NOT NULL,
    backend_network_id bigint,
    backend_virtual_interface_id bigint,
    address character varying(15) NOT NULL,
    is_gateway boolean NOT NULL,
    is_reserved boolean NOT NULL
)
SERVER edison
OPTIONS (
    dbname 'edison',
    table_name 'liquorstore_backendvirtualinterface'
);

But when I run the following query:

SELECT
    *
FROM liquorstore_backendipaddress

I get an error:

ccedison=# SELECT * FROM liquorstore_backendipaddress;
ERROR:  failed to prepare the MySQL query:
Unknown column 'backend_network_id' in 'field list'

I still cannot figure out what the problem might be so any help would be GREATLY appreciated.

It appears that all of my other FDW mappings are working correctly, so I suspect that this may be due to the long field names.

Provide a Debian package

It would be helpful to provide a Debian package instead compiling it e.g. on server.
I have implemented it in [https://github.com/jankorichter/mysql_fdw/commit/342d49aab2cc3bd90e9cdbf512c3372132a8045d]

Type conversion for MySQL BLOB and LONGBLOB types?

I am trying to use the mysql_fdw with several MySQL tables that contain BLOB and LONGBLOB fields. I mapped these fields to BYTEA and TEXT fields in the corresponding Postgres foreign table. Queries against the corresponding FTs run to completion, but it looks like each of the BYTEA and TEXT fields is getting truncated after the first three bytes.

Does the mysql_fdw currently support BLOB and LONGBLOB fields, and if so, what is the correct way of accessing these fields through the corresponding foreign table?

Segmentation Fault

Hi -- Huge fan of this library. This may be a user error issue as I'm a little out of my element here.

I'm working on a quixotic addition to this lib that creates a function which automatically loads some basic schema info from the mysql. I setup a foreign server and credentials ok, and add a normal table which I can select against ok. Next...

create foreign table mysql_columns (table_name text, column_name text) server mysql_svr options (table 'information_schema.columns');

Then when I execute a select against mysql_columns a segfault occurs.

Here is the backtrace from gdb:

(gdb) backtrace
#0  0x00007fd7cb1567ab in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#1  0x00007fd7c4fffe83 in atof (__nptr=<optimized out>)
    at /usr/include/stdlib.h:281
#2  mysqlPlanForeignScan (foreigntableid=<optimized out>, 
    root=<optimized out>, baserel=0x7fd7ce3b17d8) at mysql_fdw.c:466
#3  0x00007fd7cd304f7a in create_foreignscan_path ()
#4  0x00007fd7cd2dae07 in ?? ()
#5  0x00007fd7cd2db215 in make_one_rel ()
#6  0x00007fd7cd2f1633 in query_planner ()
#7  0x00007fd7cd2f2f31 in ?? ()
#8  0x00007fd7cd2f4b41 in subquery_planner ()
#9  0x00007fd7cd2f4e07 in standard_planner ()
#10 0x00007fd7cd355a70 in pg_plan_query ()
#11 0x00007fd7cd355b74 in pg_plan_queries ()
#12 0x00007fd7cd35658e in PostgresMain ()
#13 0x00007fd7cd318791 in ?? ()
#14 0x00007fd7cd3194d1 in PostmasterMain ()
#15 0x00007fd7cd16cdb9 in main ()

I'm continuing to investigate but am a bit of a novice in such matters. Thanks!

update: A one line hack to get this working is on my fork but I'm reluctant to suggest its an actual fix since I don't understand the problem fully.

Datetime value of 0000-00-00 00:00:00 causes errors

I have mysql_fdw pointed at a Wordpress database and I get this:

=> select * from wp_posts ;
ERROR:  date/time field value out of range: "0000-00-00 00:00:00"

Not sure what the best way to handle this is, since in MySQL's mind this is a non-null DATETIME but there's no way to translate it to to a valid non-null Postgres TIMESTAMP...

Insert Of Date Is Off By 1 Day

When I do an insert via fdw table with a date field it seems that the date inserted is off by 1.

pg_db=# INSERT INTO fdw_table (id, created_on) VALUES (1, '2014/01/01');
pg_db=# SELECT FROM fdw_table WHERE id = 1;
 id | created_on 
----+------------
  1 | 2013-12-31

Strings longer than 128 in text columns cause failure.

I added a number of comments in #20 that I thought were related to table size but I actually think the problem is something else.

Mysql Table (Percona 5.5.29)

mysql> describe products;
+------------------------+---------------+------+-----+---------------------+-----------------------------+
| Field                  | Type          | Null | Key | Default             | Extra                       |
+------------------------+---------------+------+-----+---------------------+-----------------------------+
| id                     | int(11)       | NO   | PRI | NULL                | auto_increment              |
| account_id             | int(11)       | NO   | MUL | 0                   |                             |
| name                   | varchar(100)  | NO   |     |                     |                             |
| position               | int(11)       | NO   |     | 0                   |                             |
| default_price          | decimal(10,2) | NO   |     | 0.00                |                             |
| on_sale                | tinyint(1)    | NO   |     | 0                   |                             |
| description            | text          | YES  |     | NULL                |                             |
| views                  | int(11)       | NO   |     | 0                   |                             |
| permalink              | varchar(100)  | NO   | MUL |                     |                             |
| updated_at             | timestamp     | NO   |     | CURRENT_TIMESTAMP   | on update CURRENT_TIMESTAMP |
| created_at             | timestamp     | NO   |     | 0000-00-00 00:00:00 |                             |
| primary_image_id       | int(11)       | YES  | MUL | NULL                |                             |
| status                 | varchar(255)  | YES  | MUL | NULL                |                             |
| disabled_at            | datetime      | YES  |     | NULL                |                             |
| queued_for_destruction | tinyint(1)    | NO   |     | 0                   |                             |
+------------------------+---------------+------+-----+---------------------+-----------------------------+

The Foreign Table Schema (postgresql 9.4rc1 with mysql_fdw at 0869eeb):

directory=# \d products;
           Foreign table "public.products"
   Column    |          Type          | Modifiers | FDW Options 
-------------+------------------------+-----------+-------------
 id          | integer                |           | 
 account_id  | integer                |           | 
 name        | character varying      |           | 
 description | character text |           | 

When there is a select and the description is longer than 128 characters, it stops returning rows.

So for example if there were products 1, 2, 3, 4 that had description length of 90, 90, and 130, 90 respectively

  • select * from products returns 2 rows
  • select * from products where id=3 returns 0 rows
  • select id from products returns all 4 rows.

If I update the foreign table and make the description 128 chars or less, then everything behaves as expected. I tried ensuring collation and encodings were compatible, fail. Made sure there were no crazy bytes, fail. Looked through the code for anything that might explain it but C isn't my forte. Hopefully this is enough to send somebody on the right track to fixing a bug.

Error building the EnterpriseDB mysql_fdw on OSX

From: [email protected]

I'm running 10.9.5 of OSX.

I got the MySQL and PostgreSQL dependencies installed (I think).

Checked out the git repo for mysql_fdw from git://github.com/EnterpriseDB/mysql_fdw

USE_PGXS=1 make

and got the error:

mysql_fdw.c
mysql_fdw.c:153:56: error: use of undeclared identifier 'RTLD_DEEPBIND'
mysql_dll_handle = dlopen(_MYSQL_LIBNAME, RTLD_LAZY | RTLD_DEEPBIND);

Is RTLD_DEEPBIND supported on OSX?

Did I do something wrong getting the dependencies together?

Repeating options parsing.

In mysql_fdw.c within mysqlGetForeignRelSize function you have two identical consecutive calls:

/* Fetch the options */
options = mysql_get_options(foreigntableid);

/* Fetch options */
options = mysql_get_options(foreigntableid);

This are 655 - 659 lines.

please adjust version numbers

Hi, to my understanding, the version numbers in various files need to be adjusted to 2.0.1 (aka the current release). Otherwise, postgres lists it as version 1.0, yet the release name is 2.0.1.

Make Error

Hi There,

I'm getting a problem running the make USE_PGSX=1 command to compile the source:

❯ make USE_PGXS=1                                                                                                                                                                   ⏎
gcc -mmacosx-version-min=10.7 -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv  -I/usr/local/mysql/include -I. -I. -I/Applications/Postgres93.app/Contents/MacOS/include/postgresql/server -I/Applications/Postgres93.app/Contents/MacOS/include/postgresql/internal -I/Applications/Postgres93.app/Contents/MacOS/include/libxml2  -I/Applications/Postgres93.app/Contents/MacOS/include  -c -o connection.o connection.c
gcc -mmacosx-version-min=10.7 -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv  -I/usr/local/mysql/include -I. -I. -I/Applications/Postgres93.app/Contents/MacOS/include/postgresql/server -I/Applications/Postgres93.app/Contents/MacOS/include/postgresql/internal -I/Applications/Postgres93.app/Contents/MacOS/include/libxml2  -I/Applications/Postgres93.app/Contents/MacOS/include  -c -o option.o option.c
gcc -mmacosx-version-min=10.7 -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv  -I/usr/local/mysql/include -I. -I. -I/Applications/Postgres93.app/Contents/MacOS/include/postgresql/server -I/Applications/Postgres93.app/Contents/MacOS/include/postgresql/internal -I/Applications/Postgres93.app/Contents/MacOS/include/libxml2  -I/Applications/Postgres93.app/Contents/MacOS/include  -c -o deparse.o deparse.c
deparse.c:963:11: error: use of undeclared identifier 'OIDARRAYOID'
                                        case OIDARRAYOID:
                                             ^
1 error generated.
make: *** [deparse.o] Error 1

If it's of any interest, this is with LLVM 6.0:

❯ gcc -v
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 6.0 (clang-600.0.54) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin14.0.0
Thread model: posix

WHERE clause isn't pushed after multiple SELECTs from a function/do

When a SELECT is executed multiple times inside a function or DO-block, mysql_fdw stops to push the WHERE clause down to mysql after 5 executions.

A very simple and crude example of this behavior:

DO $$
DECLARE
    startid BIGINT;
    endid BIGINT;
BEGIN
    startid := 0;

    LOOP
        startid := startid + 1000;
        endid := startid + 1000;

        RAISE NOTICE 'copying data from id % to id %', startid, endid;

        PERFORM id
        FROM remotetable
        WHERE id BETWEEN startid AND endid;

        PERFORM pg_sleep(0.5);
    END LOOP;
END $$;
NOTICE:  copying data from id 1000 to id 2000
NOTICE:  copying data from id 2000 to id 3000
NOTICE:  copying data from id 3000 to id 4000
NOTICE:  copying data from id 4000 to id 5000
NOTICE:  copying data from id 5000 to id 6000
NOTICE:  copying data from id 6000 to id 7000

Now mysql_fdw justs sits there and collects all rows from mysql (several million in my case). Postgresql is unresponsive and the connection has to be killed in MySQL.

I am using postgresql 9.4.4, mysql 5.6.25 and mysql_fdw 97006df.

Note that #44 also stopped working after 5 executions and also affects the usage inside functions.

Column/table names need to be quoted in the query being sent to MySQL

I have a few MySQL tables that use reserved words for their column names. When I run a query against the foreign tables, I get the standard syntax error message from MySQL:

ERROR:  failed to execute the MySQL query:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'key, value, is_active FROM my_schema.my_table' at line 1

In this particular instance, key is a reserved word and requires quoting with either backticks or double quotes in order to run without error.

query option missing

I have a number of foreign tables defined with the query option, which seems to be no longer supported. Is this coming back or has it been removed intentionally or is it a bug?

Module does not compile against PostgreSQL git master

The following diff fixes the issue. Apparently, the header refactoring wasn't entirely free of side effects.

diff --git a/mysql_fdw.c b/mysql_fdw.c
index d5720f3..beb467e 100644
--- a/mysql_fdw.c
+++ b/mysql_fdw.c
@@ -44,6 +44,7 @@
#include "storage/fd.h"
#include "utils/array.h"
#include "utils/builtins.h"
+#include "utils/rel.h"

PG_MODULE_MAGIC;

Issue with installation

Hi,
I have trouble installing the FDW for MySQL.
My installation steps were as below:

  1. Installed MySQL C Connector
    2)Executed
    export PATH=/Library/PostgreSQL/9.4/bin/:$PATH
    export PATH=/usr/local/mysql/bin/:$PATH
    3)make USE_PGXS=1N

This is the error I get when I run make.

/Library/PostgreSQL/9.4/include/postgresql/server/c.h:81:10: fatal error:
'stdio.h' file not found

I uninstalled and installed many times but I am stuck at this point.

I know its not a problem related to FDW but my development environment.
However if you can point out what is it that I am not doing correctly then it would help me. I use a Mac.

Thanks!

Where condition not pushed ?

Hi,
i tried to fetch records from a remote mysql_fdw table, but it seems to be reaaaaaly slow....it might be because no idx/PK is used (if i understand correctly)
here is what i did on my pg 9.3 on debian

here is what i did :

CREATE FOREIGN TABLE remote_page (
  id bigint NOT NULL,
  name text DEFAULT NULL,
  username text DEFAULT NULL,
  url text,
  picture_url text,
  category_id int DEFAULT NULL,
  is_used boolean DEFAULT NULL,
  status int DEFAULT NULL,
  created_time timestamp NULL DEFAULT NULL,
  updated_time timestamp NULL DEFAULT NULL
)
SERVER mysql_server OPTIONS (database 'fdw_db', table 'page');

expalin analyze select * from remote_page where id=12;

"Limit (cost=25.00..135.00 rows=110 width=199) (actual time=1977.399..2021.399 rows=1 loops=1)"
" -> Foreign Scan on remote_page (cost=25.00..7777.00 rows=7752 width=199) (actual time=1977.397..2021.390 rows=1 loops=1)"
" Filter: (id = 12::bigint)"
" Rows Removed by Filter: 7797"
" Remote server startup cost: 25"
" MySQL query: SELECT * FROM page"
"Total runtime: 2225.734 ms"

is there something i can do to speed uo the thing? or is it the "normal" performance ?

The default functionality in create table is not working

CREATE TABLE content_html (id int(11) default 10, id_box_elements int(11), id_router int(11), PRIMARY KEY (id), UNIQUE KEY id_box_elements (id_box_elements,id_router));

This insert from PPAS foreign table should succeed...it works when issues directly in mysql.

edb=# insert into content_html (id_box_elements,id_router) values (20,30);
2015-03-05 23:07:27 PKT LOG: statement: insert into content_html (id_box_elements,id_router) values (20,30);
2015-03-05 23:07:27 PKT ERROR: failed to execute the MySQL query:
Column 'id' cannot be null
2015-03-05 23:07:27 PKT STATEMENT: insert into content_html (id_box_elements,id_router) values (20,30);
ERROR: failed to execute the MySQL query:
Column 'id' cannot be null

Problem with 9.2 PG FDW Api

Hi Dave,

i got a error if i try to compile the mysql_fdw on pg 9.2:

gcc -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Wformat-security -Werror=format-security -fPIC -DLINUX_OOM_ADJ=0 -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -g -fpic -I/usr/include/mysql -I. -I. -I/usr/include/postgresql/9.2/server -I/usr/include/postgresql/internal -D_FORTIFY_SOURCE=2 -D_GNU_SOURCE -I/usr/include/libxml2 -I/usr/include/tcl8.5 -c -o mysql_fdw.o mysql_fdw.c
mysql_fdw.c:103:1: error: unknown type name 'FdwPlan'
mysql_fdw.c: In function 'mysql_fdw_handler':
mysql_fdw.c:125:12: error: 'FdwRoutine' has no member named 'PlanForeignScan'
mysql_fdw.c: At top level:
mysql_fdw.c:359:1: error: unknown type name 'FdwPlan'
mysql_fdw.c: In function 'mysqlPlanForeignScan':
mysql_fdw.c:362:2: error: unknown type name 'FdwPlan'
mysql_fdw.c:380:12: error: 'FdwPlan' undeclared (first use in this function)
mysql_fdw.c:380:12: note: each undeclared identifier is reported only once for each function it appears in
mysql_fdw.c:380:12: error: expected expression before ')' token
mysql_fdw.c:384:10: error: request for member 'startup_cost' in something not a structure or union
mysql_fdw.c:386:10: error: request for member 'startup_cost' in something not a structure or union
mysql_fdw.c:449:9: error: request for member 'total_cost' in something not a structure or union
mysql_fdw.c:449:38: error: request for member 'startup_cost' in something not a structure or union
mysql_fdw.c:450:9: error: request for member 'fdw_private' in something not a structure or union
make: *** [mysql_fdw.o] Error 1

I create a fork to implemented the new api: https://github.com/albertlast/mysql_fdw/
the code is not realy clean but it work

Strange Query Plan

It seems to generate a strange plan when trying to do a count.

db=# explain select count(*) from fdw_mysql_table;
                                           QUERY PLAN                                           
------------------------------------------------------------------------------------------------
 Aggregate  (cost=20806728.04..20806728.05 rows=1 width=0)
   ->  Foreign Scan on fdw_mysql_table  (cost=25.00..20754841.00 rows=20754816 width=0)
         Remote server startup cost: 25
         Remote query: SELECT NULL FROM db.table
(4 rows)
db=# explain select count(id) from fdw_mysql_table;
                                           QUERY PLAN                                           
------------------------------------------------------------------------------------------------
 Aggregate  (cost=20806729.04..20806729.05 rows=1 width=4)
   ->  Foreign Scan on fdw_mysql_table  (cost=25.00..20754842.00 rows=20754817 width=4)
         Remote server startup cost: 25
         Remote query: SELECT id FROM db.table
(4 rows)

Wrong UPDATE if values in the first column are not unique (data corrupted)

PostgreSQL 9.3, MySQL 5.5, mysql_fdw ddd5344

MySQL:

CREATE TABLE foo (
  a int,
  b int,
  c varchar(3)
);
INSERT INTO foo VALUES ( 1, 1, 'aaa');
INSERT INTO foo VALUES ( 1, 2, 'bbb');

PostgreSQL:

CREATE FOREIGN TABLE foo ( a int, b int, c varchar(44) ) 
  SERVER mysql_server OPTIONS (dbname 'test', table_name 'foo');
UPDATE foo set c = 'zzz' WHERE b = 2;
SELECT * FROM foo;
 a | b |  c  
---+---+-----
 1 | 1 | zzz
 1 | 2 | zzz

I.e. all rows were updated (very dangerous IMO). Works OK if values in 'a' (the first column) are unique or if the first column is not included in the foreign table.

BTW, probably not related directly to this issue, but there are also some strange skips over the first column here
https://github.com/EnterpriseDB/mysql_fdw/blob/e03bc73/mysql_fdw.c#L943
https://github.com/EnterpriseDB/mysql_fdw/blob/e03bc73/mysql_fdw.c#L1244

Postgres-9.4 mysql_fdw write issues to MariaDB-5.5

Hi all,

I chanced upon this great extension and it is excellent for reading mysql and mariadb database.

However, there seems to be an issue with the mysql database write functions, even though the current master branch (d9836a3) says it has included write capability.

SELECT statements are fine.

INSERT statement has weird behaviour:

  • the autoincrement id gets updated, while all other columns becomes '0' or 0
    Example test schema data is below.

DELETE statement returns error from postgres:

ERROR:  cache lookup failed for type 0
********** Error **********
ERROR: cache lookup failed for type 0
SQL state: XX000

My system is running ubuntu 14.04 and the db servers are as below.

  • postgresql-9.4/trusty-pgdg,now 9.4.4-1.pgdg14.04+1 amd64
  • 5.5.44-MariaDB-1ubuntu0.14.04.1 (Ubuntu)

Connection to foreign mysql server is root with superuser privileges so there should not be privilege issues and user mapping issues.

I'm not too sure how to debug this for the fdw writing to MariaDB database. (Encoding? Server Version?)

Any direction or help is much appreciated.

-- MariaDB database
CREATE DATABASE `test` /*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci */

-- MariaDB table
CREATE TABLE `test_table` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `col1` varchar(45) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'test',
  `bool` tinyint(1) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

-- postgres db
CREATE DATABASE testdb
WITH OWNER = postgres
ENCODING = 'UTF8'
TABLESPACE = pg_default
LC_COLLATE = 'en_US.UTF-8'
LC_CTYPE = 'en_US.UTF-8'
CONNECTION LIMIT = -1;

-- postgres foreign table
CREATE FOREIGN TABLE remote_mysql_test.test_table
(
    id integer NOT NULL,
    col1 character varying(45),
    bool boolean
)
SERVER mysqlserver
OPTIONS (dbname 'test', table_name 'test_table');
ALTER FOREIGN TABLE remote_mysql_test.test_table
OWNER TO postgres;

query one of mysql fdw table,the where condition is using json

  1. the table pro_json is contain two columns just like that
    id int,instance text
    1, '{"userid":"10001","version":"1.2"}
    2, '{"userid":"10002","version":"1.3"}
  2. PostgreSQL
    1. CREATE FOREIGN TABLE fdw_project_json(
      id int,
      instance json)
      SERVER mysql_server
      OPTIONS (dbname 'osns', table_name 'pro_json');
    2. PostgreSQL's sql running as follows:
      select id,instance::json->>'version' as version from fdw_project_json where (instance::json->>'version')::text = '1.2'
      it's cannot running... how can I query the json using where condition. thanks!

NOT IN with Sub-select is not working

NOT IN with Sub-select is not working.

postgres=# SELECT * FROM department d, employee e WHERE d.department_id NOT IN (SELECT department_id FROM department) LIMIT 10;
ERROR: unsupported expression type for deparse: 317
STATEMENT: SELECT * FROM department d, employee e WHERE d.department_id NOT IN (SELECT department_id FROM department) LIMIT 10;
ERROR: unsupported expression type for deparse: 317

Can't map tables with uppercase letters in the name

I'm trying to build a mapping to a MySQL database that uses uppercases in the tables names. This is resulting problematic because the fdw applies Postgres quoting rules which fail on MySQL (unless a certain session parameter is set and all the other unreliability MySQL kindly offers). The offender is the line:

appendStringInfo(buf, "%s.%s", quote_identifier(nspname), quote_identifier(relname));

in deparse.c.

Querying a table called schema.Table result in generating:

EXPLAIN SELECT idattendance, description FROM schema."Table"

which is a MySQL error, unless SET SQL_MODE=ANSI_QUOTES is not set in the session.

I think the quote_identifier() calls should be dropped. Alternatively consider setting ANSI_QUOTES in the session.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.