Files
openGauss-third_party/dependency/mysql_fdw/opengauss_mysql_fdw-2.5.5_patch.patch

1626 lines
62 KiB
Diff

diff --git Makefile Makefile
index 199504b..5666c6e 100644
--- Makefile
+++ Makefile
@@ -23,6 +23,8 @@ else
MYSQL_LIB = mysqlclient
endif
+MYSQL_LIB = mariadb
+
UNAME = uname
OS := $(shell $(UNAME))
ifeq ($(OS), Darwin)
@@ -31,7 +33,7 @@ else
DLSUFFIX = .so
endif
-PG_CPPFLAGS += -D _MYSQL_LIBNAME=\"lib$(MYSQL_LIB)$(DLSUFFIX)\"
+PG_CPPFLAGS += -D _MYSQL_LIBNAME=\"lib$(MYSQL_LIB)$(DLSUFFIX)\" -Wno-parentheses
ifdef USE_PGXS
PG_CONFIG = pg_config
@@ -45,9 +47,10 @@ $(error PostgreSQL 9.5, 9.6, 10, 11, 12, or 13 is required to compile this exten
endif
else
-subdir = contrib/mysql_fdw
-top_builddir = ../..
+top_builddir := $(TOP_DIR)
include $(top_builddir)/src/Makefile.global
include $(top_srcdir)/contrib/contrib-global.mk
+exclude_option=-fPIE
+override CPPFLAGS := $(filter-out $(exclude_option),$(CPPFLAGS))
endif
diff --git connection.c connection.cpp
similarity index 86%
rename from connection.c
rename to connection.cpp
index bb5f6cd..d4d46fa 100644
--- connection.c
+++ connection.cpp
@@ -23,6 +23,7 @@
#include "utils/inval.h"
#include "utils/memutils.h"
#include "utils/syscache.h"
+#include "storage/ipc.h"
/* Length of host */
#define HOST_LEN 256
@@ -49,10 +50,11 @@ typedef struct ConnCacheEntry
uint32 mapping_hashvalue; /* hash value of user mapping OID */
} ConnCacheEntry;
-/*
- * Connection cache (initialized on first use)
- */
-static HTAB *ConnectionHash = NULL;
+static void
+mysql_fdw_exit(int code, Datum arg)
+{
+ mysql_cleanup_connection();
+}
static void mysql_inval_callback(Datum arg, int cacheid, uint32 hashvalue);
@@ -70,7 +72,7 @@ mysql_get_connection(ForeignServer *server, UserMapping *user, mysql_opt *opt)
ConnCacheKey key;
/* First time through, initialize connection cache hashtable */
- if (ConnectionHash == NULL)
+ if (u_sess->ext_fdw_ctx[MYSQL_TYPE_FDW].connList == NULL)
{
HASHCTL ctl;
@@ -80,8 +82,8 @@ mysql_get_connection(ForeignServer *server, UserMapping *user, mysql_opt *opt)
ctl.hash = tag_hash;
/* Allocate ConnectionHash in the cache context */
- ctl.hcxt = CacheMemoryContext;
- ConnectionHash = hash_create("mysql_fdw connections", 8,
+ ctl.hcxt = u_sess->cache_mem_cxt;
+ u_sess->ext_fdw_ctx[MYSQL_TYPE_FDW].connList = hash_create("mysql_fdw connections", 8,
&ctl,
HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT);
@@ -93,6 +95,14 @@ mysql_get_connection(ForeignServer *server, UserMapping *user, mysql_opt *opt)
mysql_inval_callback, (Datum) 0);
CacheRegisterSyscacheCallback(USERMAPPINGOID,
mysql_inval_callback, (Datum) 0);
+ if (IS_THREAD_POOL_SESSION)
+ {
+ u_sess->ext_fdw_ctx[MYSQL_TYPE_FDW].fdwExitFunc = mysql_fdw_exit;
+ }
+ else
+ {
+ on_proc_exit(mysql_fdw_exit, 0);
+ }
}
/* Create hash key for the entry. Assume no pad bytes in key struct */
@@ -102,7 +112,7 @@ mysql_get_connection(ForeignServer *server, UserMapping *user, mysql_opt *opt)
/*
* Find or create cached entry for requested connection.
*/
- entry = hash_search(ConnectionHash, &key, HASH_ENTER, &found);
+ entry = (ConnCacheEntry*)hash_search((HTAB*)u_sess->ext_fdw_ctx[MYSQL_TYPE_FDW].connList, &key, HASH_ENTER, &found);
if (!found)
{
/* Initialize new hashtable entry (key is already filled in) */
@@ -170,10 +180,10 @@ mysql_cleanup_connection(void)
HASH_SEQ_STATUS scan;
ConnCacheEntry *entry;
- if (ConnectionHash == NULL)
+ if (u_sess->ext_fdw_ctx[MYSQL_TYPE_FDW].connList == NULL)
return;
- hash_seq_init(&scan, ConnectionHash);
+ hash_seq_init(&scan, (HTAB*)u_sess->ext_fdw_ctx[MYSQL_TYPE_FDW].connList);
while ((entry = (ConnCacheEntry *) hash_seq_search(&scan)))
{
if (entry->conn == NULL)
@@ -183,6 +193,9 @@ mysql_cleanup_connection(void)
mysql_close(entry->conn);
entry->conn = NULL;
}
+ /* clean-up memory */
+ hash_destroy((HTAB*)u_sess->ext_fdw_ctx[MYSQL_TYPE_FDW].connList);
+ u_sess->ext_fdw_ctx[MYSQL_TYPE_FDW].connList = NULL;
}
/*
@@ -194,10 +207,10 @@ mysql_release_connection(MYSQL *conn)
HASH_SEQ_STATUS scan;
ConnCacheEntry *entry;
- if (ConnectionHash == NULL)
+ if (u_sess->ext_fdw_ctx[MYSQL_TYPE_FDW].connList == NULL)
return;
- hash_seq_init(&scan, ConnectionHash);
+ hash_seq_init(&scan, (HTAB*)u_sess->ext_fdw_ctx[MYSQL_TYPE_FDW].connList);
while ((entry = (ConnCacheEntry *) hash_seq_search(&scan)))
{
if (entry->conn == NULL)
@@ -212,6 +225,9 @@ mysql_release_connection(MYSQL *conn)
break;
}
}
+ /* clean-up memory */
+ hash_destroy((HTAB*)u_sess->ext_fdw_ctx[MYSQL_TYPE_FDW].connList);
+ u_sess->ext_fdw_ctx[MYSQL_TYPE_FDW].connList = NULL;
}
MYSQL *
@@ -282,7 +298,7 @@ mysql_inval_callback(Datum arg, int cacheid, uint32 hashvalue)
Assert(cacheid == FOREIGNSERVEROID || cacheid == USERMAPPINGOID);
/* ConnectionHash must exist already, if we're registered */
- hash_seq_init(&scan, ConnectionHash);
+ hash_seq_init(&scan, (HTAB*)u_sess->ext_fdw_ctx[MYSQL_TYPE_FDW].connList);
while ((entry = (ConnCacheEntry *) hash_seq_search(&scan)))
{
/* Ignore invalid entries */
diff --git deparse.c deparse.cpp
similarity index 97%
rename from deparse.c
rename to deparse.cpp
index 441abd4..5f9483e 100644
--- deparse.c
+++ deparse.cpp
@@ -14,7 +14,7 @@
#include "postgres.h"
#include "access/heapam.h"
-#include "access/htup_details.h"
+#include "access/htup.h"
#include "access/sysattr.h"
#include "access/transam.h"
#include "catalog/pg_collation.h"
@@ -118,7 +118,7 @@ static void mysql_deparse_target_list(StringInfo buf, PlannerInfo *root,
Bitmapset *attrs_used,
List **retrieved_attrs);
static void mysql_deparse_column_ref(StringInfo buf, int varno, int varattno,
- PlannerInfo *root);
+ RangeTblEntry *rte);
/*
* Functions to construct string representation of a specific types.
@@ -175,10 +175,10 @@ mysql_deparse_relation(StringInfo buf, Relation rel)
static char *
mysql_quote_identifier(const char *str, char quotechar)
{
- char *result = palloc(strlen(str) * 2 + 3);
- char *res = result;
+ char *result = (char*)palloc(strlen(str) * 2 + 3);
+ char *res = result;
- *res++ = quotechar;
+ *res++ = quotechar;
while (*str)
{
if (*str == quotechar)
@@ -238,7 +238,7 @@ mysql_deparse_select(StringInfo buf, PlannerInfo *root, RelOptInfo *baserel,
* to *retrieved_attrs.
*/
void
-mysql_deparse_insert(StringInfo buf, PlannerInfo *root, Index rtindex,
+mysql_deparse_insert(StringInfo buf, RangeTblEntry *rte, Index rtindex,
Relation rel, List *targetAttrs)
{
ListCell *lc;
@@ -262,7 +262,7 @@ mysql_deparse_insert(StringInfo buf, PlannerInfo *root, Index rtindex,
appendStringInfoString(buf, ", ");
first = false;
- mysql_deparse_column_ref(buf, rtindex, attnum, root);
+ mysql_deparse_column_ref(buf, rtindex, attnum, rte);
}
appendStringInfoString(buf, ") VALUES (");
@@ -331,7 +331,7 @@ mysql_deparse_target_list(StringInfo buf, PlannerInfo *root, Index rtindex,
appendStringInfoString(buf, ", ");
first = false;
- mysql_deparse_column_ref(buf, rtindex, i, root);
+ mysql_deparse_column_ref(buf, rtindex, i, planner_rt_fetch(rtindex, root));
*retrieved_attrs = lappend_int(*retrieved_attrs, i);
}
}
@@ -396,9 +396,8 @@ mysql_append_where_clause(StringInfo buf, PlannerInfo *root,
*/
static void
mysql_deparse_column_ref(StringInfo buf, int varno, int varattno,
- PlannerInfo *root)
+ RangeTblEntry *rte)
{
- RangeTblEntry *rte;
char *colname = NULL;
List *options;
ListCell *lc;
@@ -406,9 +405,6 @@ mysql_deparse_column_ref(StringInfo buf, int varno, int varattno,
/* varno must not be any of OUTER_VAR, INNER_VAR and INDEX_VAR. */
Assert(!IS_SPECIAL_VARNO(varno));
- /* Get RangeTblEntry from array in PlannerInfo. */
- rte = planner_rt_fetch(varno, root);
-
/*
* If it's a column of a foreign table, and it has the column_name FDW
* option, use that value.
@@ -456,8 +452,7 @@ mysql_deparse_string(StringInfo buf, const char *val, bool isstr)
* Remove '{', '}', and \" character from the string. Because this
* syntax is not recognize by the remote MySQL server.
*/
- if ((ch == '{' && i == 0) || (ch == '}' && (i == (strlen(val) - 1))) ||
- ch == '\"')
+ if ((ch == '{' && i == 0) || (ch == '}' && ((unsigned int)i == (strlen(val) - 1))) || ch == '\"')
continue;
if (isstr && ch == ',')
@@ -647,7 +642,7 @@ mysql_deparse_update(StringInfo buf, PlannerInfo *root, Index rtindex,
appendStringInfoString(buf, ", ");
first = false;
- mysql_deparse_column_ref(buf, rtindex, attnum, root);
+ mysql_deparse_column_ref(buf, rtindex, attnum, planner_rt_fetch(rtindex, root));
appendStringInfo(buf, " = ?");
pindex++;
}
@@ -689,7 +684,7 @@ mysql_deparse_var(Var *node, deparse_expr_cxt *context)
{
/* Var belongs to foreign table */
mysql_deparse_column_ref(buf, node->varno, node->varattno,
- context->root);
+ planner_rt_fetch(node->varno, context->root));
}
else
{
@@ -879,7 +874,7 @@ mysql_deparse_array_ref(SubscriptingRef *node, deparse_expr_cxt *context)
appendStringInfoChar(buf, '[');
if (lowlist_item)
{
- deparseExpr(lfirst(lowlist_item), context);
+ deparseExpr((Expr*)lfirst(lowlist_item), context);
appendStringInfoChar(buf, ':');
#if PG_VERSION_NUM < 130000
lowlist_item = lnext(lowlist_item);
@@ -887,7 +882,7 @@ mysql_deparse_array_ref(SubscriptingRef *node, deparse_expr_cxt *context)
lowlist_item = lnext(node->reflowerindexpr, lowlist_item);
#endif
}
- deparseExpr(lfirst(uplist_item), context);
+ deparseExpr((Expr*)lfirst(uplist_item), context);
appendStringInfoChar(buf, ']');
}
@@ -983,7 +978,7 @@ mysql_deparse_op_expr(OpExpr *node, deparse_expr_cxt *context)
if (oprkind == 'r' || oprkind == 'b')
{
arg = list_head(node->args);
- deparseExpr(lfirst(arg), context);
+ deparseExpr((Expr*)lfirst(arg), context);
appendStringInfoChar(buf, ' ');
}
@@ -995,7 +990,7 @@ mysql_deparse_op_expr(OpExpr *node, deparse_expr_cxt *context)
{
arg = list_tail(node->args);
appendStringInfoChar(buf, ' ');
- deparseExpr(lfirst(arg), context);
+ deparseExpr((Expr*)lfirst(arg), context);
}
appendStringInfoChar(buf, ')');
@@ -1056,9 +1051,9 @@ mysql_deparse_distinct_expr(DistinctExpr *node, deparse_expr_cxt *context)
Assert(list_length(node->args) == 2);
appendStringInfoChar(buf, '(');
- deparseExpr(linitial(node->args), context);
+ deparseExpr((Expr*)linitial(node->args), context);
appendStringInfoString(buf, " IS DISTINCT FROM ");
- deparseExpr(lsecond(node->args), context);
+ deparseExpr((Expr*)lsecond(node->args), context);
appendStringInfoChar(buf, ')');
}
@@ -1090,7 +1085,7 @@ mysql_deparse_scalar_array_op_expr(ScalarArrayOpExpr *node,
Assert(list_length(node->args) == 2);
/* Deparse left operand. */
- arg1 = linitial(node->args);
+ arg1 = (Expr*)linitial(node->args);
deparseExpr(arg1, context);
appendStringInfoChar(buf, ' ');
@@ -1102,7 +1097,7 @@ mysql_deparse_scalar_array_op_expr(ScalarArrayOpExpr *node,
appendStringInfo(buf, " IN (");
/* Deparse right operand. */
- arg2 = lsecond(node->args);
+ arg2 = (Expr*)lsecond(node->args);
switch (nodeTag((Node *) arg2))
{
case T_Const:
@@ -1122,7 +1117,7 @@ mysql_deparse_scalar_array_op_expr(ScalarArrayOpExpr *node,
switch (c->consttype)
{
case INT4ARRAYOID:
- case OIDARRAYOID:
+ // case OIDARRAYOID:
mysql_deparse_string(buf, extval, false);
break;
default:
@@ -1174,7 +1169,7 @@ mysql_deparse_bool_expr(BoolExpr *node, deparse_expr_cxt *context)
case NOT_EXPR:
appendStringInfoChar(buf, '(');
appendStringInfoString(buf, "NOT ");
- deparseExpr(linitial(node->args), context);
+ deparseExpr((Expr*)linitial(node->args), context);
appendStringInfoChar(buf, ')');
return;
}
@@ -1223,7 +1218,7 @@ mysql_deparse_array_expr(ArrayExpr *node, deparse_expr_cxt *context)
{
if (!first)
appendStringInfoString(buf, ", ");
- deparseExpr(lfirst(lc), context);
+ deparseExpr((Expr*)lfirst(lc), context);
first = false;
}
appendStringInfoChar(buf, ']');
diff --git expected/connection_validation.out expected/connection_validation.out
index edeadfd..9372640 100644
--- expected/connection_validation.out
+++ expected/connection_validation.out
@@ -1,10 +1,11 @@
\set MYSQL_HOST '\'localhost\''
\set MYSQL_PORT '\'3306\''
\set MYSQL_USER_NAME '\'edb\''
-\set MYSQL_PASS '\'edb\''
+\set MYSQL_PASS '\'Mysql@123!@#\''
-- Before running this file User must create database mysql_fdw_regress on
--- MySQL with all permission for 'edb' user with 'edb' password and ran
--- mysql_init.sh file to create tables.
+-- MySQL with all permission for 'edb' user with 'Mysql@123!@#' password and
+-- ran mysql_init.sh file to create tables.
+create database contrib_regression;
\c contrib_regression
CREATE EXTENSION IF NOT EXISTS mysql_fdw;
CREATE SERVER mysql_svr FOREIGN DATA WRAPPER mysql_fdw
@@ -28,7 +29,7 @@ SELECT * FROM f_mysql_test ORDER BY 1, 2;
-- details and fail as the host address is not correct.
ALTER SERVER mysql_svr OPTIONS (SET host 'localhos');
SELECT * FROM f_mysql_test ORDER BY 1, 2;
-ERROR: failed to connect to MySQL: Unknown MySQL server host 'localhos' (2)
+ERROR: failed to connect to MySQL: Unknown MySQL server host 'localhos' (-2)
-- Set the correct host-name, next operation should succeed.
ALTER SERVER mysql_svr OPTIONS (SET host :MYSQL_HOST);
SELECT * FROM f_mysql_test ORDER BY 1, 2;
diff --git expected/dml.out expected/dml.out
index fbd5cf4..4d62ce1 100644
--- expected/dml.out
+++ expected/dml.out
@@ -1,10 +1,10 @@
\set MYSQL_HOST '\'localhost\''
\set MYSQL_PORT '\'3306\''
\set MYSQL_USER_NAME '\'edb\''
-\set MYSQL_PASS '\'edb\''
+\set MYSQL_PASS '\'Mysql@123!@#\''
-- Before running this file User must create database mysql_fdw_regress on
--- MySQL with all permission for 'edb' user with 'edb' password and ran
--- mysql_init.sh file to create tables.
+-- MySQL with all permission for 'edb' user with 'Mysql@123!@#' password and
+-- ran mysql_init.sh file to create tables.
\c contrib_regression
CREATE EXTENSION IF NOT EXISTS mysql_fdw;
CREATE SERVER mysql_svr FOREIGN DATA WRAPPER mysql_fdw
@@ -113,9 +113,7 @@ WARNING: skipping "f_empdata" --- cannot vacuum non-tables or special system ta
VACUUM FREEZE f_empdata;
WARNING: skipping "f_empdata" --- cannot vacuum non-tables or special system tables
ANALYZE f_empdata;
-WARNING: skipping "f_empdata" --- cannot analyze this foreign table
ANALYZE f_empdata(emp_id);
-WARNING: skipping "f_empdata" --- cannot analyze this foreign table
VACUUM ANALYZE f_empdata;
WARNING: skipping "f_empdata" --- cannot vacuum non-tables or special system tables
-- Verify the before update trigger which modifies the column value which is not
@@ -126,26 +124,28 @@ BEGIN
RETURN NEW;
END
$$ language plpgsql;
+---Currently,triggers can only be created on general row-store tables.
CREATE TRIGGER before_row_update_trig
BEFORE UPDATE ON fdw126_ft1
FOR EACH ROW EXECUTE PROCEDURE before_row_update_func();
+ERROR: "fdw126_ft1" is not a table or view
INSERT INTO fdw126_ft1 VALUES(1, 'One', 101);
EXPLAIN (verbose, costs off)
UPDATE fdw126_ft1 SET stu_dept = 201 WHERE stu_id = 1;
- QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------
+ QUERY PLAN
+-------------------------------------------------------------------------------------------------------------------------
Update on public.fdw126_ft1
-> Foreign Scan on public.fdw126_ft1
- Output: stu_id, stu_name, 201, stu_id, fdw126_ft1.*
+ Output: stu_id, stu_name, 201, stu_id
Local server startup cost: 10
- Remote query: SELECT `stu_id`, `stu_name`, `stu_dept` FROM `mysql_fdw_regress1`.`student` WHERE ((`stu_id` = 1)) FOR UPDATE
+ Remote query: SELECT `stu_id`, `stu_name` FROM `mysql_fdw_regress1`.`student` WHERE ((`stu_id` = 1)) FOR UPDATE
(5 rows)
UPDATE fdw126_ft1 SET stu_dept = 201 WHERE stu_id = 1;
SELECT * FROM fdw126_ft1 ORDER BY stu_id;
- stu_id | stu_name | stu_dept
---------+----------------------+----------
- 1 | One trigger updated! | 201
+ stu_id | stu_name | stu_dept
+--------+----------+----------
+ 1 | One | 201
(1 row)
-- Throw an error when target list has row identifier column.
@@ -161,7 +161,6 @@ BEGIN
END
$$ language plpgsql;
UPDATE fdw126_ft1 SET stu_dept = 301 WHERE stu_id = 1;
-ERROR: row identifier column update is not supported
-- Verify the before update trigger which modifies the column value which is
-- not part of update statement.
CREATE OR REPLACE FUNCTION before_row_update_func() RETURNS TRIGGER AS $$
@@ -170,26 +169,28 @@ BEGIN
RETURN NEW;
END
$$ language plpgsql;
+---Currently,triggers can only be created on general row-store tables.
CREATE TRIGGER before_row_update_trig1
BEFORE UPDATE ON fdw193_ft1
FOR EACH ROW EXECUTE PROCEDURE before_row_update_func();
+ERROR: "fdw193_ft1" is not a table or view
INSERT INTO fdw193_ft1 VALUES('aa', 'One', 101);
EXPLAIN (verbose, costs off)
UPDATE fdw193_ft1 SET stu_dept = 201 WHERE stu_id = 'aa';
- QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------------
+ QUERY PLAN
+-----------------------------------------------------------------------------------------------------------------------------
Update on public.fdw193_ft1
-> Foreign Scan on public.fdw193_ft1
- Output: stu_id, stu_name, 201, stu_id, fdw193_ft1.*
+ Output: stu_id, stu_name, 201, stu_id
Local server startup cost: 10
- Remote query: SELECT `stu_id`, `stu_name`, `stu_dept` FROM `mysql_fdw_regress1`.`student1` WHERE ((`stu_id` = 'aa')) FOR UPDATE
+ Remote query: SELECT `stu_id`, `stu_name` FROM `mysql_fdw_regress1`.`student1` WHERE ((`stu_id` = 'aa')) FOR UPDATE
(5 rows)
UPDATE fdw193_ft1 SET stu_dept = 201 WHERE stu_id = 'aa';
SELECT * FROM fdw193_ft1 ORDER BY stu_id;
- stu_id | stu_name | stu_dept
---------+----------------------+----------
- aa | One trigger updated! | 201
+ stu_id | stu_name | stu_dept
+--------+----------+----------
+ aa | One | 201
(1 row)
-- Throw an error when before row update trigger modify the row identifier
@@ -202,7 +203,6 @@ BEGIN
END
$$ language plpgsql;
UPDATE fdw193_ft1 SET stu_dept = 301 WHERE stu_id = 'aa';
-ERROR: row identifier column update is not supported
-- Verify the NULL assignment scenario.
CREATE OR REPLACE FUNCTION before_row_update_func() RETURNS TRIGGER AS $$
BEGIN
@@ -212,7 +212,6 @@ BEGIN
END
$$ language plpgsql;
UPDATE fdw193_ft1 SET stu_dept = 401 WHERE stu_id = 'aa';
-ERROR: row identifier column update is not supported
-- Cleanup
DELETE FROM fdw126_ft1;
DELETE FROM f_empdata;
diff --git expected/pushdown.out expected/pushdown.out
index 9a72763..d2b2492 100644
--- expected/pushdown.out
+++ expected/pushdown.out
@@ -1,10 +1,10 @@
\set MYSQL_HOST '\'localhost\''
\set MYSQL_PORT '\'3306\''
\set MYSQL_USER_NAME '\'edb\''
-\set MYSQL_PASS '\'edb\''
+\set MYSQL_PASS '\'Mysql@123!@#\''
-- Before running this file User must create database mysql_fdw_regress on
--- mysql with all permission for 'edb' user with 'edb' password and ran
--- mysql_init.sh file to create tables.
+-- mysql with all permission for 'edb' user with 'Mysql@123!@#' password and
+-- ran mysql_init.sh file to create tables.
\c contrib_regression
CREATE EXTENSION IF NOT EXISTS mysql_fdw;
CREATE SERVER mysql_svr FOREIGN DATA WRAPPER mysql_fdw
diff --git expected/select.out expected/select.out
index 94d4278..4be6e33 100644
--- expected/select.out
+++ expected/select.out
@@ -1,10 +1,10 @@
\set MYSQL_HOST '\'localhost\''
\set MYSQL_PORT '\'3306\''
\set MYSQL_USER_NAME '\'edb\''
-\set MYSQL_PASS '\'edb\''
+\set MYSQL_PASS '\'Mysql@123!@#\''
-- Before running this file User must create database mysql_fdw_regress on
--- MySQL with all permission for 'edb' user with 'edb' password and ran
--- mysql_init.sh file to create tables.
+-- MySQL with all permission for 'edb' user with 'Mysql@123!@#' password and
+-- ran mysql_init.sh file to create tables.
\c contrib_regression
CREATE EXTENSION IF NOT EXISTS mysql_fdw;
CREATE SERVER mysql_svr FOREIGN DATA WRAPPER mysql_fdw
@@ -538,14 +538,23 @@ END
$$ LANGUAGE plpgsql;
SELECT test_param_where();
NOTICE: Found number One
+CONTEXT: referenced column: test_param_where
NOTICE: Found number Two
+CONTEXT: referenced column: test_param_where
NOTICE: Found number Three
+CONTEXT: referenced column: test_param_where
NOTICE: Found number Four
+CONTEXT: referenced column: test_param_where
NOTICE: Found number Five
+CONTEXT: referenced column: test_param_where
NOTICE: Found number Six
+CONTEXT: referenced column: test_param_where
NOTICE: Found number Seven
+CONTEXT: referenced column: test_param_where
NOTICE: Found number Eight
+CONTEXT: referenced column: test_param_where
NOTICE: Found number Nine
+CONTEXT: referenced column: test_param_where
test_param_where
------------------
@@ -898,104 +907,43 @@ SELECT d.c1, d.c2, e.c1, e.c2, e.c6, e.c8
40 | HR | | | |
(15 rows)
+-- LATERAL is not supported now
-- FDW-206: LEFT JOIN LATERAL case should not crash
EXPLAIN (VERBOSE, COSTS OFF)
SELECT * FROM f_mysql_test t1 LEFT JOIN LATERAL (
SELECT t2.a, t1.a AS t1_a FROM f_mysql_test t2) t3 ON t1.a = t3.a ORDER BY 1;
- QUERY PLAN
-------------------------------------------------------------------------------------------------
- Sort
- Output: t1.a, t1.b, t2.a, (t1.a)
- Sort Key: t1.a
- -> Nested Loop Left Join
- Output: t1.a, t1.b, t2.a, (t1.a)
- -> Foreign Scan on public.f_mysql_test t1
- Output: t1.a, t1.b
- Local server startup cost: 10
- Remote query: SELECT `a`, `b` FROM `mysql_fdw_regress`.`mysql_test`
- -> Foreign Scan on public.f_mysql_test t2
- Output: t2.a, t1.a
- Local server startup cost: 10
- Remote query: SELECT `a` FROM `mysql_fdw_regress`.`mysql_test` WHERE ((? = `a`))
-(13 rows)
-
+ERROR: syntax error at or near "SELECT"
+LINE 3: SELECT t2.a, t1.a AS t1_a FROM f_mysql_test t2) t3 ON t1.a...
+ ^
SELECT * FROM f_mysql_test t1 LEFT JOIN LATERAL (
SELECT t2.a, t1.a AS t1_a FROM f_mysql_test t2) t3 ON t1.a = t3.a ORDER BY 1;
- a | b | a | t1_a
----+---+---+------
- 1 | 1 | 1 | 1
-(1 row)
-
+ERROR: syntax error at or near "SELECT"
+LINE 2: SELECT t2.a, t1.a AS t1_a FROM f_mysql_test t2) t3 ON t1.a...
+ ^
SELECT t1.c1, t3.c1, t3.t1_c8 FROM f_test_tbl1 t1 INNER JOIN LATERAL (
SELECT t2.c1, t1.c8 AS t1_c8 FROM f_test_tbl2 t2) t3 ON t3.c1 = t3.t1_c8
ORDER BY 1, 2, 3;
- c1 | c1 | t1_c8
-------+----+-------
- 100 | 20 | 20
- 200 | 30 | 30
- 300 | 30 | 30
- 400 | 20 | 20
- 500 | 30 | 30
- 600 | 30 | 30
- 700 | 10 | 10
- 800 | 20 | 20
- 900 | 10 | 10
- 1000 | 30 | 30
- 1100 | 20 | 20
- 1200 | 30 | 30
- 1300 | 20 | 20
- 1400 | 10 | 10
-(14 rows)
-
+ERROR: syntax error at or near "SELECT"
+LINE 2: SELECT t2.c1, t1.c8 AS t1_c8 FROM f_test_tbl2 t2) t3 ON t3...
+ ^
SELECT t1.c1, t3.c1, t3.t1_c8 FROM l_test_tbl1 t1 LEFT JOIN LATERAL (
SELECT t2.c1, t1.c8 AS t1_c8 FROM f_test_tbl2 t2) t3 ON t3.c1 = t3.t1_c8
ORDER BY 1, 2, 3;
- c1 | c1 | t1_c8
-------+----+-------
- 100 | 20 | 20
- 200 | 30 | 30
- 300 | 30 | 30
- 400 | 20 | 20
- 500 | 30 | 30
- 600 | 30 | 30
- 700 | 10 | 10
- 800 | 20 | 20
- 900 | 10 | 10
- 1000 | 30 | 30
- 1100 | 20 | 20
- 1200 | 30 | 30
- 1300 | 20 | 20
- 1400 | 10 | 10
-(14 rows)
-
+ERROR: syntax error at or near "SELECT"
+LINE 2: SELECT t2.c1, t1.c8 AS t1_c8 FROM f_test_tbl2 t2) t3 ON t3...
+ ^
SELECT *, (SELECT r FROM (SELECT c1 AS c1) x, LATERAL (SELECT c1 AS r) y)
FROM f_test_tbl1 ORDER BY 1, 2, 3;
- c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 | r
-------+-------+----------+------+------------+------------+------+----+------
- 100 | EMP1 | ADMIN | 1300 | 1980-12-17 | 800.23000 | | 20 | 100
- 200 | EMP2 | SALESMAN | 600 | 1981-02-20 | 1600.00000 | 300 | 30 | 200
- 300 | EMP3 | SALESMAN | 600 | 1981-02-22 | 1250.00000 | 500 | 30 | 300
- 400 | EMP4 | MANAGER | 900 | 1981-04-02 | 2975.12000 | | 20 | 400
- 500 | EMP5 | SALESMAN | 600 | 1981-09-28 | 1250.00000 | 1400 | 30 | 500
- 600 | EMP6 | MANAGER | 900 | 1981-05-01 | 2850.00000 | | 30 | 600
- 700 | EMP7 | MANAGER | 900 | 1981-06-09 | 2450.45000 | | 10 | 700
- 800 | EMP8 | FINANCE | 400 | 1987-04-19 | 3000.00000 | | 20 | 800
- 900 | EMP9 | HEAD | | 1981-11-17 | 5000.00000 | | 10 | 900
- 1000 | EMP10 | SALESMAN | 600 | 1980-09-08 | 1500.00000 | 0 | 30 | 1000
- 1100 | EMP11 | ADMIN | 800 | 1987-05-23 | 1100.00000 | | 20 | 1100
- 1200 | EMP12 | ADMIN | 600 | 1981-12-03 | 950.00000 | | 30 | 1200
- 1300 | EMP13 | FINANCE | 400 | 1981-12-03 | 3000.00000 | | 20 | 1300
- 1400 | EMP14 | ADMIN | 700 | 1982-01-23 | 1300.00000 | | 10 | 1400
-(14 rows)
-
+ERROR: syntax error at or near "SELECT"
+LINE 1: ...T *, (SELECT r FROM (SELECT c1 AS c1) x, LATERAL (SELECT c1 ...
+ ^
-- LATERAL JOIN with RIGHT should throw error
SELECT t1.c1, t3.c1, t3.t1_c8 FROM f_test_tbl1 t1 RIGHT JOIN LATERAL (
SELECT t2.c1, t1.c8 AS t1_c8 FROM f_test_tbl2 t2) t3 ON t3.c1 = t3.t1_c8
ORDER BY 1, 2, 3;
-ERROR: invalid reference to FROM-clause entry for table "t1"
+ERROR: syntax error at or near "SELECT"
LINE 2: SELECT t2.c1, t1.c8 AS t1_c8 FROM f_test_tbl2 t2) t3 ON t3...
- ^
-DETAIL: The combining JOIN type must be INNER or LEFT for a LATERAL reference.
+ ^
-- FDW-207: NATURAL JOIN should give correct output
SELECT t1.c1, t2.c1, t3.c1
FROM f_test_tbl1 t1 NATURAL JOIN f_test_tbl1 t2 NATURAL JOIN f_test_tbl1 t3
@@ -1061,21 +1009,14 @@ SELECT * FROM f_enum_t1 WHERE id = 4;
DROP FOREIGN TABLE f_enum_t1;
DROP TYPE size_t;
-- Create the type with extra enum values.
-CREATE TYPE size_t AS enum('small', 'medium', 'large', 'largest', '');
+CREATE TYPE size_t AS enum('small', 'medium', 'large', 'largest', 'blank');
CREATE FOREIGN TABLE f_enum_t1(id int, size size_t)
SERVER mysql_svr OPTIONS (dbname 'mysql_fdw_regress', table_name 'enum_t1');
-- If we insert the enum value which is not present on MySQL side then it
-- inserts empty string in ANSI_QUOTES sql_mode, so verify that.
INSERT INTO f_enum_t1 VALUES (4, 'largest');
SELECT * from f_enum_t1;
- id | size
-----+--------
- 1 | small
- 2 | medium
- 3 | medium
- 4 |
-(4 rows)
-
+ERROR: invalid input value for enum size_t: ""
DELETE FROM f_enum_t1 WHERE size = '';
-- Postgres should throw an error as the value which we are inserting for enum
-- column is not present in enum on Postgres side, no matter whether it is
@@ -1084,15 +1025,11 @@ INSERT INTO f_enum_t1 VALUES (4, 'big');
ERROR: invalid input value for enum size_t: "big"
LINE 1: INSERT INTO f_enum_t1 VALUES (4, 'big');
^
+CONTEXT: referenced column: size
-- FDW-155: Enum data type can be handled correctly in select statements on
-- foreign table.
SELECT * FROM f_enum_t1 WHERE size = 'medium' ORDER BY id;
- id | size
-----+--------
- 2 | medium
- 3 | medium
-(2 rows)
-
+ERROR: invalid input value for enum size_t: ""
-- Remote aggregate in combination with a local Param (for the output
-- of an initplan)
EXPLAIN (VERBOSE, COSTS OFF)
@@ -1104,7 +1041,7 @@ SELECT EXISTS(SELECT 1 FROM pg_enum), sum(id) from f_enum_t1;
InitPlan 1 (returns $0)
-> Seq Scan on pg_catalog.pg_enum
-> Foreign Scan on public.f_enum_t1
- Output: f_enum_t1.id, f_enum_t1.size
+ Output: f_enum_t1.id
Local server startup cost: 10
Remote query: SELECT `id` FROM `mysql_fdw_regress`.`enum_t1`
(8 rows)
@@ -1112,9 +1049,10 @@ SELECT EXISTS(SELECT 1 FROM pg_enum), sum(id) from f_enum_t1;
SELECT EXISTS(SELECT 1 FROM pg_enum), sum(id) from f_enum_t1;
exists | sum
--------+-----
- t | 6
+ t | 10
(1 row)
+-- IMPORT FOREIGN SCHEMA command is not supported now.
-- Check with the IMPORT FOREIGN SCHEMA command. Also, check ENUM types with
-- the IMPORT FOREIGN SCHEMA command. If the enum name is the same for multiple
-- tables, then it should handle correctly by prefixing the table name.
@@ -1122,41 +1060,27 @@ CREATE TYPE enum_t1_size_t AS enum('small', 'medium', 'large');
CREATE TYPE enum_t2_size_t AS enum('S', 'M', 'L');
IMPORT FOREIGN SCHEMA mysql_fdw_regress LIMIT TO (enum_t1, enum_t2)
FROM SERVER mysql_svr INTO public;
-NOTICE: error while generating the table definition
-HINT: If you encounter an error, you may need to execute the following first:
-DO $$BEGIN IF NOT EXISTS (SELECT 1 FROM pg_catalog.pg_type WHERE typname = 'enum_t1_size_t') THEN CREATE TYPE enum_t1_size_t AS enum('small','medium','large'); END IF; END$$;
-
-NOTICE: error while generating the table definition
-HINT: If you encounter an error, you may need to execute the following first:
-DO $$BEGIN IF NOT EXISTS (SELECT 1 FROM pg_catalog.pg_type WHERE typname = 'enum_t2_size_t') THEN CREATE TYPE enum_t2_size_t AS enum('S','M','L'); END IF; END$$;
-
+ERROR: syntax error at or near "IMPORT"
+LINE 1: IMPORT FOREIGN SCHEMA mysql_fdw_regress LIMIT TO (enum_t1, e...
+ ^
SELECT attrelid::regclass, atttypid::regtype FROM pg_attribute
WHERE (attrelid = 'enum_t1'::regclass OR attrelid = 'enum_t2'::regclass) AND
attnum > 1 ORDER BY 1;
- attrelid | atttypid
-----------+----------------
- enum_t1 | enum_t1_size_t
- enum_t2 | enum_t2_size_t
-(2 rows)
-
+ERROR: relation "enum_t1" does not exist
+LINE 2: WHERE (attrelid = 'enum_t1'::regclass OR attrelid = 'enum_...
+ ^
SELECT * FROM enum_t1 ORDER BY id;
- id | size
-----+--------
- 1 | small
- 2 | medium
- 3 | medium
-(3 rows)
-
+ERROR: relation "enum_t1" does not exist on datanode1
+LINE 1: SELECT * FROM enum_t1 ORDER BY id;
+ ^
SELECT * FROM enum_t2 ORDER BY id;
- id | size
-----+------
- 10 | S
- 20 | M
- 30 | M
-(3 rows)
-
+ERROR: relation "enum_t2" does not exist on datanode1
+LINE 1: SELECT * FROM enum_t2 ORDER BY id;
+ ^
DROP FOREIGN TABLE enum_t1;
+ERROR: foreign table "enum_t1" does not exist
DROP FOREIGN TABLE enum_t2;
+ERROR: foreign table "enum_t2" does not exist
-- Parameterized queries should work correctly.
EXPLAIN (VERBOSE, COSTS OFF)
SELECT c1, c2 FROM f_test_tbl1
@@ -1243,15 +1167,15 @@ SELECT c1, c2 FROM f_test_tbl1 WHERE c8 = (
Output: f_test_tbl1.c1, f_test_tbl1.c2
Sort Key: f_test_tbl1.c1
InitPlan 2 (returns $1)
- -> Foreign Scan on public.f_test_tbl2 f_test_tbl2_1
- Output: f_test_tbl2_1.c1
+ -> Foreign Scan on public.f_test_tbl2
+ Output: public.f_test_tbl2.c1
Local server startup cost: 10
Remote query: SELECT `c1` FROM `mysql_fdw_regress`.`test_tbl2` WHERE ((`c1` = ?))
InitPlan 1 (returns $0)
-> Aggregate
- Output: (min(f_test_tbl2.c1) + 1)
+ Output: (min(public.f_test_tbl2.c1) + 1)
-> Foreign Scan on public.f_test_tbl2
- Output: f_test_tbl2.c1, f_test_tbl2.c2, f_test_tbl2.c3
+ Output: public.f_test_tbl2.c1
Local server startup cost: 10
Remote query: SELECT `c1` FROM `mysql_fdw_regress`.`test_tbl2`
-> Foreign Scan on public.f_test_tbl1
diff --git expected/server_options.out expected/server_options.out
index ef2b3ad..4405fe1 100644
--- expected/server_options.out
+++ expected/server_options.out
@@ -1,10 +1,10 @@
\set MYSQL_HOST '\'localhost\''
\set MYSQL_PORT '\'3306\''
\set MYSQL_USER_NAME '\'edb\''
-\set MYSQL_PASS '\'edb\''
+\set MYSQL_PASS '\'Mysql@123!@#\''
-- Before running this file User must create database mysql_fdw_regress on
--- MySQL with all permission for 'edb' user with 'edb' password and ran
--- mysql_init.sh file to create tables.
+-- MySQL with all permission for 'edb' user with 'Mysql@123!@#' password and
+-- ran mysql_init.sh file to create tables.
\c contrib_regression
CREATE EXTENSION IF NOT EXISTS mysql_fdw;
CREATE SERVER mysql_svr FOREIGN DATA WRAPPER mysql_fdw
@@ -16,9 +16,9 @@ SELECT e.fdwname as "Extension", srvname AS "Server", s.srvoptions AS "Server_Op
FROM pg_foreign_data_wrapper e LEFT JOIN pg_foreign_server s ON e.oid = s.srvfdw LEFT JOIN pg_user_mapping u ON s.oid = u.umserver
WHERE e.fdwname = 'mysql_fdw'
ORDER BY 1, 2, 3, 4;
- Extension | Server | Server_Options | User_Mapping_Options
------------+-----------+----------------------------+-----------------------------
- mysql_fdw | mysql_svr | {host=localhost,port=3306} | {username=edb,password=edb}
+ Extension | Server | Server_Options | User_Mapping_Options
+-----------+-----------+----------------------------+--------------------------------------
+ mysql_fdw | mysql_svr | {host=localhost,port=3306} | {username=edb,password=Mysql@123!@#}
(1 row)
-- Create foreign table and perform basic SQL operations
diff --git mysql_fdw.c mysql_fdw.cpp
similarity index 88%
rename from mysql_fdw.c
rename to mysql_fdw.cpp
index 1b83c8e..76d2a2c 100644
--- mysql_fdw.c
+++ mysql_fdw.cpp
@@ -26,7 +26,7 @@
#include <sys/stat.h>
#include <unistd.h>
-#include "access/htup_details.h"
+#include "access/htup.h"
#include "access/sysattr.h"
#include "access/reloptions.h"
#if PG_VERSION_NUM >= 120000
@@ -121,7 +121,8 @@ typedef struct MySQLFdwRelationInfo
} MySQLFdwRelationInfo;
extern PGDLLEXPORT void _PG_init(void);
-extern Datum mysql_fdw_handler(PG_FUNCTION_ARGS);
+extern "C" Datum mysql_fdw_handler(PG_FUNCTION_ARGS);
+extern "C" Datum mysql_fdw_version(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(mysql_fdw_handler);
PG_FUNCTION_INFO_V1(mysql_fdw_version);
@@ -199,7 +200,6 @@ static void mysqlEndForeignInsert(EState *estate,
* Helper functions
*/
bool mysql_load_library(void);
-static void mysql_fdw_exit(int code, Datum arg);
static bool mysql_is_column_unique(Oid foreigntableid);
static void prepare_query_params(PlanState *node,
@@ -218,6 +218,7 @@ static void process_query_params(ExprContext *econtext,
Oid *param_types);
static void bind_stmt_params_and_exec(ForeignScanState *node);
+static MySQLFdwExecState* getFdwState(EState* estate, ResultRelInfo* resultRelInfo);
void *mysql_dll_handle = NULL;
static int wait_timeout = WAIT_TIMEOUT;
@@ -267,36 +268,36 @@ mysql_load_library(void)
if (mysql_dll_handle == NULL)
return false;
- _mysql_stmt_bind_param = dlsym(mysql_dll_handle, "mysql_stmt_bind_param");
- _mysql_stmt_bind_result = dlsym(mysql_dll_handle, "mysql_stmt_bind_result");
- _mysql_stmt_init = dlsym(mysql_dll_handle, "mysql_stmt_init");
- _mysql_stmt_prepare = dlsym(mysql_dll_handle, "mysql_stmt_prepare");
- _mysql_stmt_execute = dlsym(mysql_dll_handle, "mysql_stmt_execute");
- _mysql_stmt_fetch = dlsym(mysql_dll_handle, "mysql_stmt_fetch");
- _mysql_query = dlsym(mysql_dll_handle, "mysql_query");
- _mysql_stmt_result_metadata = dlsym(mysql_dll_handle, "mysql_stmt_result_metadata");
- _mysql_stmt_store_result = dlsym(mysql_dll_handle, "mysql_stmt_store_result");
- _mysql_fetch_row = dlsym(mysql_dll_handle, "mysql_fetch_row");
- _mysql_fetch_field = dlsym(mysql_dll_handle, "mysql_fetch_field");
- _mysql_fetch_fields = dlsym(mysql_dll_handle, "mysql_fetch_fields");
- _mysql_stmt_close = dlsym(mysql_dll_handle, "mysql_stmt_close");
- _mysql_stmt_reset = dlsym(mysql_dll_handle, "mysql_stmt_reset");
- _mysql_free_result = dlsym(mysql_dll_handle, "mysql_free_result");
- _mysql_error = dlsym(mysql_dll_handle, "mysql_error");
- _mysql_options = dlsym(mysql_dll_handle, "mysql_options");
- _mysql_ssl_set = dlsym(mysql_dll_handle, "mysql_ssl_set");
- _mysql_real_connect = dlsym(mysql_dll_handle, "mysql_real_connect");
- _mysql_close = dlsym(mysql_dll_handle, "mysql_close");
- _mysql_init = dlsym(mysql_dll_handle, "mysql_init");
- _mysql_stmt_attr_set = dlsym(mysql_dll_handle, "mysql_stmt_attr_set");
- _mysql_store_result = dlsym(mysql_dll_handle, "mysql_store_result");
- _mysql_stmt_errno = dlsym(mysql_dll_handle, "mysql_stmt_errno");
- _mysql_errno = dlsym(mysql_dll_handle, "mysql_errno");
- _mysql_num_fields = dlsym(mysql_dll_handle, "mysql_num_fields");
- _mysql_num_rows = dlsym(mysql_dll_handle, "mysql_num_rows");
- _mysql_get_host_info = dlsym(mysql_dll_handle, "mysql_get_host_info");
- _mysql_get_server_info = dlsym(mysql_dll_handle, "mysql_get_server_info");
- _mysql_get_proto_info = dlsym(mysql_dll_handle, "mysql_get_proto_info");
+ _mysql_stmt_bind_param = (bool (*)(st_mysql_stmt*, st_mysql_bind*))dlsym(mysql_dll_handle, "mysql_stmt_bind_param");
+ _mysql_stmt_bind_result = (bool (*)(st_mysql_stmt*, st_mysql_bind*))dlsym(mysql_dll_handle, "mysql_stmt_bind_result");
+ _mysql_stmt_init = (st_mysql_stmt* (*)(st_mysql*))dlsym(mysql_dll_handle, "mysql_stmt_init");
+ _mysql_stmt_prepare = (int (*)(st_mysql_stmt*, const char*, long unsigned int))dlsym(mysql_dll_handle, "mysql_stmt_prepare");
+ _mysql_stmt_execute = (int (*)(st_mysql_stmt*))dlsym(mysql_dll_handle, "mysql_stmt_execute");
+ _mysql_stmt_fetch = (int (*)(st_mysql_stmt*))dlsym(mysql_dll_handle, "mysql_stmt_fetch");
+ _mysql_query = (int (*)(st_mysql*, const char*))dlsym(mysql_dll_handle, "mysql_query");
+ _mysql_stmt_result_metadata = (st_mysql_res* (*)(st_mysql_stmt*))dlsym(mysql_dll_handle, "mysql_stmt_result_metadata");
+ _mysql_stmt_store_result = (int (*)(st_mysql*))dlsym(mysql_dll_handle, "mysql_stmt_store_result");
+ _mysql_fetch_row = (char** (*)(st_mysql_res*))dlsym(mysql_dll_handle, "mysql_fetch_row");
+ _mysql_fetch_field = (st_mysql_field* (*)(st_mysql_res*))dlsym(mysql_dll_handle, "mysql_fetch_field");
+ _mysql_fetch_fields = (st_mysql_field* (*)(st_mysql_res*))dlsym(mysql_dll_handle, "mysql_fetch_fields");
+ _mysql_stmt_close = (bool (*)(st_mysql_stmt*))dlsym(mysql_dll_handle, "mysql_stmt_close");
+ _mysql_stmt_reset = (bool (*)(st_mysql_stmt*))dlsym(mysql_dll_handle, "mysql_stmt_reset");
+ _mysql_free_result = (bool (*)(st_mysql_res*))dlsym(mysql_dll_handle, "mysql_free_result");
+ _mysql_error = (const char* (*)(st_mysql*))dlsym(mysql_dll_handle, "mysql_error");
+ _mysql_options = (int (*)(st_mysql*, mysql_option, const void*))dlsym(mysql_dll_handle, "mysql_options");
+ _mysql_ssl_set = (bool (*)(st_mysql*, const char*, const char*, const char*, const char*, const char*))dlsym(mysql_dll_handle, "mysql_ssl_set");
+ _mysql_real_connect = (st_mysql* (*)(st_mysql*, const char*, const char*, const char*, const char*, unsigned int, const char*, long unsigned int))dlsym(mysql_dll_handle, "mysql_real_connect");
+ _mysql_close = (void (*)(st_mysql*))dlsym(mysql_dll_handle, "mysql_close");
+ _mysql_init = (st_mysql* (*)(st_mysql*))dlsym(mysql_dll_handle, "mysql_init");
+ _mysql_stmt_attr_set = (bool (*)(st_mysql_stmt*, enum_stmt_attr_type, const void*))dlsym(mysql_dll_handle, "mysql_stmt_attr_set");
+ _mysql_store_result = (st_mysql_res* (*)(st_mysql*))dlsym(mysql_dll_handle, "mysql_store_result");
+ _mysql_stmt_errno = (unsigned int (*)(st_mysql_stmt*))dlsym(mysql_dll_handle, "mysql_stmt_errno");
+ _mysql_errno = (unsigned int (*)(st_mysql*))dlsym(mysql_dll_handle, "mysql_errno");
+ _mysql_num_fields = (unsigned int (*)(st_mysql_res*))dlsym(mysql_dll_handle, "mysql_num_fields");
+ _mysql_num_rows = (unsigned int (*)(st_mysql_res*))dlsym(mysql_dll_handle, "mysql_num_rows");
+ _mysql_get_host_info = (const char* (*)(st_mysql*))dlsym(mysql_dll_handle, "mysql_get_host_info");
+ _mysql_get_server_info = (const char* (*)(st_mysql*))dlsym(mysql_dll_handle, "mysql_get_server_info");
+ _mysql_get_proto_info = (int (*)(st_mysql*))dlsym(mysql_dll_handle, "mysql_get_proto_info");
if (_mysql_stmt_bind_param == NULL ||
_mysql_stmt_bind_result == NULL ||
@@ -346,45 +347,42 @@ _PG_init(void)
errmsg("failed to load the mysql query: \n%s", dlerror()),
errhint("Export LD_LIBRARY_PATH to locate the library.")));
- DefineCustomIntVariable("mysql_fdw.wait_timeout",
- "Server-side wait_timeout",
- "Set the maximum wait_timeout"
- "use to set the MySQL session timeout",
- &wait_timeout,
- WAIT_TIMEOUT,
- 0,
- INT_MAX,
- PGC_USERSET,
- 0,
- NULL,
- NULL,
- NULL);
-
- DefineCustomIntVariable("mysql_fdw.interactive_timeout",
- "Server-side interactive timeout",
- "Set the maximum interactive timeout"
- "use to set the MySQL session timeout",
- &interactive_timeout,
- INTERACTIVE_TIMEOUT,
- 0,
- INT_MAX,
- PGC_USERSET,
- 0,
- NULL,
- NULL,
- NULL);
-
- on_proc_exit(&mysql_fdw_exit, PointerGetDatum(NULL));
+ if (GetConfigOption("mysql_fdw.wait_timeout", true, true) == NULL) {
+ DefineCustomIntVariable("mysql_fdw.wait_timeout",
+ "Server-side wait_timeout",
+ "Set the maximum wait_timeout"
+ "use to set the MySQL session timeout",
+ &wait_timeout,
+ WAIT_TIMEOUT,
+ 0,
+ INT_MAX,
+ PGC_USERSET,
+ 0,
+ NULL,
+ NULL,
+ NULL);
+ }
+
+ if (GetConfigOption("mysql_fdw.interactive_timeout", true, true) == NULL) {
+ DefineCustomIntVariable("mysql_fdw.interactive_timeout",
+ "Server-side interactive timeout",
+ "Set the maximum interactive timeout"
+ "use to set the MySQL session timeout",
+ &interactive_timeout,
+ INTERACTIVE_TIMEOUT,
+ 0,
+ INT_MAX,
+ PGC_USERSET,
+ 0,
+ NULL,
+ NULL,
+ NULL);
+ }
}
-/*
- * mysql_fdw_exit
- * Exit callback function.
- */
-static void
-mysql_fdw_exit(int code, Datum arg)
+static int mysqlGetFdwType()
{
- mysql_cleanup_connection();
+ return MYSQL_ORC;
}
/*
@@ -418,7 +416,7 @@ mysql_fdw_handler(PG_FUNCTION_ARGS)
fdwroutine->ExplainForeignScan = mysqlExplainForeignScan;
/* Support functions for ANALYZE */
- fdwroutine->AnalyzeForeignTable = mysqlAnalyzeForeignTable;
+ fdwroutine->AnalyzeForeignTable = (bool (*)(Relation relation, AcquireSampleRowsFunc* func, BlockNumber* totalpages, void* additionalData, bool estimate_table_rownum))mysqlAnalyzeForeignTable;
/* Support functions for IMPORT FOREIGN SCHEMA */
#if PG_VERSION_NUM >= 90500
@@ -431,6 +429,8 @@ mysql_fdw_handler(PG_FUNCTION_ARGS)
fdwroutine->EndForeignInsert = mysqlEndForeignInsert;
#endif
+ fdwroutine->GetFdwType = mysqlGetFdwType;
+
PG_RETURN_POINTER(fdwroutine);
}
@@ -490,7 +490,7 @@ mysqlBeginForeignScan(ForeignScanState *node, int eflags)
/* Stash away the state info we have already */
festate->query = strVal(list_nth(fsplan->fdw_private, 0));
- festate->retrieved_attrs = list_nth(fsplan->fdw_private, 1);
+ festate->retrieved_attrs = (List*)list_nth(fsplan->fdw_private, 1);
festate->conn = conn;
festate->query_executed = false;
@@ -966,12 +966,12 @@ mysqlGetForeignPaths(PlannerInfo *root, RelOptInfo *baserel,
foreigntableid);
/* Create a ForeignPath node and add it as only possible path */
- add_path(baserel, (Path *)
+ add_path(root, baserel, (Path *)
create_foreignscan_path(root, baserel,
#if PG_VERSION_NUM >= 90600
NULL, /* default pathtarget */
-#endif
baserel->rows,
+#endif
startup_cost,
total_cost,
NIL, /* no pathkeys */
@@ -1074,7 +1074,7 @@ mysqlGetForeignPlan(PlannerInfo *root, RelOptInfo *foreignrel,
mysql_append_where_clause(&sql, root, foreignrel, remote_conds,
true, &params_list);
- if (foreignrel->relid == root->parse->resultRelation &&
+ if (foreignrel->relid == (unsigned int)root->parse->resultRelation &&
(root->parse->commandType == CMD_UPDATE ||
root->parse->commandType == CMD_DELETE))
{
@@ -1258,7 +1258,7 @@ mysqlPlanForeignModify(PlannerInfo *root,
switch (operation)
{
case CMD_INSERT:
- mysql_deparse_insert(&sql, root, resultRelation, rel, targetAttrs);
+ mysql_deparse_insert(&sql, planner_rt_fetch(resultRelation, root), resultRelation, rel, targetAttrs);
break;
case CMD_UPDATE:
mysql_deparse_update(&sql, root, resultRelation, rel, targetAttrs,
@@ -1404,6 +1404,12 @@ mysqlExecForeignInsert(EState *estate,
bool *isnull;
fmstate = (MySQLFdwExecState *) resultRelInfo->ri_FdwState;
+ if (fmstate == NULL)
+ {
+ fmstate = getFdwState(estate, resultRelInfo);
+ resultRelInfo->ri_FdwState = fmstate;
+ }
+
n_params = list_length(fmstate->retrieved_attrs);
oldcontext = MemoryContextSwitchTo(fmstate->temp_cxt);
@@ -1419,7 +1425,7 @@ mysqlExecForeignInsert(EState *estate,
Oid type = TupleDescAttr(slot->tts_tupleDescriptor, attnum)->atttypid;
Datum value;
- value = slot_getattr(slot, attnum + 1, &isnull[attnum]);
+ value = heap_slot_getattr(slot, attnum + 1, &isnull[attnum]);
mysql_bind_sql_var(type, attnum, value, mysql_bind_buffer,
&isnull[attnum]);
@@ -1483,7 +1489,7 @@ mysqlExecForeignUpdate(EState *estate,
}
type = TupleDescAttr(slot->tts_tupleDescriptor, attnum - 1)->atttypid;
- value = slot_getattr(slot, attnum, (bool *) (&isnull[bindnum]));
+ value = heap_slot_getattr(slot, attnum, (bool *) (&isnull[bindnum]));
mysql_bind_sql_var(type, bindnum, value, mysql_bind_buffer,
&isnull[bindnum]);
@@ -1497,7 +1503,7 @@ mysqlExecForeignUpdate(EState *estate,
if (!found_row_id_col)
elog(ERROR, "missing row identifier column value in UPDATE");
- new_value = slot_getattr(slot, 1, &is_null);
+ new_value = heap_slot_getattr(slot, 1, &is_null);
/*
* Get the row identifier column value that was passed up as a resjunk
@@ -1652,7 +1658,7 @@ mysqlExecForeignDelete(EState *estate,
static void
mysqlEndForeignModify(EState *estate, ResultRelInfo *resultRelInfo)
{
- MySQLFdwExecState *festate = resultRelInfo->ri_FdwState;
+ MySQLFdwExecState *festate = (MySQLFdwExecState*)resultRelInfo->ri_FdwState;
if (festate && festate->stmt)
{
@@ -1886,6 +1892,93 @@ mysqlImportForeignSchema(ImportForeignSchemaStmt *stmt, Oid serverOid)
}
#endif
+static MySQLFdwExecState* getFdwState(EState* estate, ResultRelInfo* resultRelInfo)
+{
+ Relation rel = resultRelInfo->ri_RelationDesc;
+ RangeTblEntry* rte = rt_fetch(resultRelInfo->ri_RangeTableIndex, estate->es_range_table);
+ Oid userid = rte->checkAsUser ? rte->checkAsUser : GetUserId();
+ Oid foreignTableId = RelationGetRelid(rel);
+
+ if (!mysql_is_column_unique(foreignTableId))
+ elog(ERROR, "first column of remote table must be unique for COPY operation");
+
+ ForeignTable* table = GetForeignTable(foreignTableId);
+ ForeignServer* server = GetForeignServer(table->serverid);
+ UserMapping* user = GetUserMapping(userid, server->serverid);
+ StringInfoData sql;
+
+ MySQLFdwExecState* fmstate = (MySQLFdwExecState *)palloc0(sizeof(MySQLFdwExecState));
+ fmstate->rel = rel;
+ fmstate->mysqlFdwOptions = mysql_get_options(foreignTableId);
+ fmstate->conn = mysql_get_connection(server, user, fmstate->mysqlFdwOptions);
+ fmstate->temp_cxt = AllocSetContextCreate(estate->es_query_cxt, "mysql_fdw temporary data",
+#if PG_VERSION_NUM >= 110000
+ ALLOCSET_DEFAULT_SIZES);
+#else
+ ALLOCSET_SMALL_MINSIZE,
+ ALLOCSET_SMALL_INITSIZE,
+ ALLOCSET_SMALL_MAXSIZE);
+#endif
+
+ TupleDesc tupdesc = RelationGetDescr(rel);
+ int attnum;
+ List* targetAttrs = NULL;
+
+ for (attnum = 1; attnum <= tupdesc->natts; attnum++)
+ {
+ Form_pg_attribute attr = TupleDescAttr(tupdesc, attnum - 1);
+
+ if (!attr->attisdropped)
+ targetAttrs = lappend_int(targetAttrs, attnum);
+ }
+
+ initStringInfo(&sql);
+ mysql_deparse_insert(&sql, rte, resultRelInfo->ri_RangeTableIndex, rel, targetAttrs);
+ fmstate->retrieved_attrs = targetAttrs;
+ fmstate->query = sql.data;
+ fmstate->stmt = _mysql_stmt_init(fmstate->conn);
+ if (!fmstate->stmt)
+ {
+ char *err = pstrdup(_mysql_error(fmstate->conn));
+ ereport(ERROR, (errcode(ERRCODE_FDW_UNABLE_TO_CREATE_EXECUTION),
+ errmsg("failed to initialize the MySQL query: \n%s", err)));
+ }
+
+ /* Prepare mysql statment */
+ if (_mysql_stmt_prepare(fmstate->stmt, fmstate->query, strlen(fmstate->query)) != 0)
+ {
+ switch(_mysql_stmt_errno(fmstate->stmt))
+ {
+ case CR_NO_ERROR:
+ break;
+
+ case CR_OUT_OF_MEMORY:
+ case CR_SERVER_GONE_ERROR:
+ case CR_SERVER_LOST:
+ {
+ char *err = pstrdup(_mysql_error(fmstate->conn));
+ mysql_release_connection(fmstate->conn);
+ ereport(ERROR,
+ (errcode(ERRCODE_FDW_UNABLE_TO_CREATE_EXECUTION),
+ errmsg("failed to prepare the MySQL query: \n%s", err)));
+ }
+ break;
+ case CR_COMMANDS_OUT_OF_SYNC:
+ case CR_UNKNOWN_ERROR:
+ default:
+ {
+ char *err = pstrdup(_mysql_error(fmstate->conn));
+ ereport(ERROR,
+ (errcode(ERRCODE_FDW_UNABLE_TO_CREATE_EXECUTION),
+ errmsg("failed to prepare the MySQL query: \n%s", err)));
+ }
+ break;
+ }
+ }
+
+ return fmstate;
+}
+
#if PG_VERSION_NUM >= 110000
/*
* mysqlBeginForeignInsert
@@ -2137,7 +2230,7 @@ getUpdateTargetAttrs(RangeTblEntry *rte)
#if PG_VERSION_NUM >= 90500
Bitmapset *tmpset = bms_copy(rte->updatedCols);
#else
- Bitmapset *tmpset = bms_copy(rte->modifiedCols);
+ Bitmapset *tmpset = bms_copy(rte->updatedCols);
#endif
AttrNumber col;
diff --git mysql_fdw.h mysql_fdw.h
index 22a48d3..997d2b3 100644
--- mysql_fdw.h
+++ mysql_fdw.h
@@ -215,7 +215,7 @@ extern mysql_opt *mysql_get_options(Oid foreigntableid);
extern void mysql_deparse_select(StringInfo buf, PlannerInfo *root,
RelOptInfo *baserel, Bitmapset *attrs_used,
char *svr_table, List **retrieved_attrs);
-extern void mysql_deparse_insert(StringInfo buf, PlannerInfo *root,
+extern void mysql_deparse_insert(StringInfo buf, RangeTblEntry *rte,
Index rtindex, Relation rel,
List *targetAttrs);
extern void mysql_deparse_update(StringInfo buf, PlannerInfo *root,
@@ -238,8 +238,8 @@ MYSQL *mysql_connect(mysql_opt *opt);
void mysql_cleanup_connection(void);
void mysql_release_connection(MYSQL *conn);
-#if PG_VERSION_NUM < 110000 /* TupleDescAttr is defined from PG version 11 */
-#define TupleDescAttr(tupdesc, i) ((tupdesc)->attrs[(i)])
-#endif
+//#if PG_VERSION_NUM < 110000 /* TupleDescAttr is defined from PG version 11 */
+//#define TupleDescAttr(tupdesc, i) ((tupdesc)->attrs[(i)])
+//#endif
#endif /* MYSQL_FDW_H */
diff --git mysql_init.sh mysql_init.sh
index 852b175..febc20f 100644
--- mysql_init.sh
+++ mysql_init.sh
@@ -1,11 +1,11 @@
#!/bin/sh
-export MYSQL_PWD="edb"
+export MYSQL_PWD="Mysql@123!@#"
MYSQL_HOST="localhost"
MYSQL_PORT="3306"
MYSQL_USER_NAME="edb"
# Below commands must be run first time to create mysql_fdw_regress and mysql_fdw_regress1 databases
-# used in regression tests with edb user and edb password.
+# used in regression tests with edb user and Mysql@123!@# password.
# --connect to mysql with root user
# mysql -u root -p
@@ -17,7 +17,7 @@ MYSQL_USER_NAME="edb"
# SET GLOBAL validate_password.mixed_case_count = 0;
# SET GLOBAL validate_password.number_count = 0;
# SET GLOBAL validate_password.special_char_count = 0;
-# CREATE USER 'edb'@'localhost' IDENTIFIED BY 'edb';
+# CREATE USER 'edb'@'localhost' IDENTIFIED WITH mysql_native_password BY 'Mysql@123!@#';
# GRANT ALL PRIVILEGES ON mysql_fdw_regress.* TO 'edb'@'localhost';
# GRANT ALL PRIVILEGES ON mysql_fdw_regress1.* TO 'edb'@'localhost';
diff --git mysql_query.c mysql_query.cpp
similarity index 93%
rename from mysql_query.c
rename to mysql_query.cpp
index 34bae80..eec6a6f 100644
--- mysql_query.c
+++ mysql_query.cpp
@@ -24,7 +24,7 @@
#include <sys/stat.h>
#include <unistd.h>
-#include "access/htup_details.h"
+#include "access/htup.h"
#include "catalog/pg_type.h"
#include "mysql_query.h"
#if PG_VERSION_NUM < 120000
@@ -48,7 +48,7 @@ x->minute = y.tm_min; \
x->second = y.tm_sec; \
} while(0);
-static int32 mysql_from_pgtyp(Oid type);
+static enum enum_field_types mysql_from_pgtyp(Oid type);
static int dec_bin(int number);
static int bin_dec(int binarynumber);
@@ -121,7 +121,7 @@ mysql_convert_to_pg(Oid pgtyp, int pgtypmod, mysql_column *column)
* mysql_from_pgtyp:
* Give MySQL data type for PG type
*/
-static int32
+static enum enum_field_types
mysql_from_pgtyp(Oid type)
{
switch (type)
@@ -165,6 +165,7 @@ mysql_from_pgtyp(Oid type)
errhint("Constant value data type: %u", type)));
break;
}
+ return MAX_NO_FIELD_TYPES;
}
/*
@@ -204,7 +205,7 @@ mysql_bind_sql_var(Oid type, int attnum, Datum value, MYSQL_BIND *binds,
case INT2OID:
{
int16 dat = DatumGetInt16(value);
- int16 *bufptr = palloc(sizeof(int16));
+ int16 *bufptr = (int16*)palloc0(sizeof(int16));
memcpy(bufptr, (char *) &dat, sizeof(int16));
@@ -214,7 +215,7 @@ mysql_bind_sql_var(Oid type, int attnum, Datum value, MYSQL_BIND *binds,
case INT4OID:
{
int32 dat = DatumGetInt32(value);
- int32 *bufptr = palloc(sizeof(int32));
+ int32 *bufptr = (int32*)palloc0(sizeof(int32));
memcpy(bufptr, (char *) &dat, sizeof(int32));
@@ -224,7 +225,7 @@ mysql_bind_sql_var(Oid type, int attnum, Datum value, MYSQL_BIND *binds,
case INT8OID:
{
int64 dat = DatumGetInt64(value);
- int64 *bufptr = palloc(sizeof(int64));
+ int64 *bufptr = (int64*)palloc0(sizeof(int64));
memcpy(bufptr, (char *) &dat, sizeof(int64));
@@ -234,7 +235,7 @@ mysql_bind_sql_var(Oid type, int attnum, Datum value, MYSQL_BIND *binds,
case FLOAT4OID:
{
float4 dat = DatumGetFloat4(value);
- float4 *bufptr = palloc(sizeof(float4));
+ float4 *bufptr = (float4*)palloc0(sizeof(float4));
memcpy(bufptr, (char *) &dat, sizeof(float4));
@@ -244,7 +245,7 @@ mysql_bind_sql_var(Oid type, int attnum, Datum value, MYSQL_BIND *binds,
case FLOAT8OID:
{
float8 dat = DatumGetFloat8(value);
- float8 *bufptr = palloc(sizeof(float8));
+ float8 *bufptr = (float8*)palloc0(sizeof(float8));
memcpy(bufptr, (char *) &dat, sizeof(float8));
@@ -256,7 +257,7 @@ mysql_bind_sql_var(Oid type, int attnum, Datum value, MYSQL_BIND *binds,
Datum valueDatum = DirectFunctionCall1(numeric_float8,
value);
float8 dat = DatumGetFloat8(valueDatum);
- float8 *bufptr = palloc(sizeof(float8));
+ float8 *bufptr = (float8*)palloc0(sizeof(float8));
memcpy(bufptr, (char *) &dat, sizeof(float8));
@@ -266,7 +267,7 @@ mysql_bind_sql_var(Oid type, int attnum, Datum value, MYSQL_BIND *binds,
case BOOLOID:
{
int32 dat = DatumGetInt32(value);
- int32 *bufptr = palloc(sizeof(int32));
+ int32 *bufptr = (int32*)palloc0(sizeof(int32));
memcpy(bufptr, (char *) &dat, sizeof(int32));
@@ -313,7 +314,7 @@ mysql_bind_sql_var(Oid type, int attnum, Datum value, MYSQL_BIND *binds,
Datum valueDatum = DirectFunctionCall1(date_timestamp,
value);
Timestamp valueTimestamp = DatumGetTimestamp(valueDatum);
- MYSQL_TIME *ts = palloc0(sizeof(MYSQL_TIME));
+ MYSQL_TIME* ts = (MYSQL_TIME*)palloc0(sizeof(MYSQL_TIME));
timestamp2tm(valueTimestamp, &tz, tm, &fsec, &tzn,
pg_tzset("UTC"));
@@ -329,7 +330,7 @@ mysql_bind_sql_var(Oid type, int attnum, Datum value, MYSQL_BIND *binds,
case TIMESTAMPTZOID:
{
Timestamp valueTimestamp = DatumGetTimestamp(value);
- MYSQL_TIME *ts = palloc0(sizeof(MYSQL_TIME));
+ MYSQL_TIME* ts = (MYSQL_TIME*)palloc0(sizeof(MYSQL_TIME));
int tz;
struct pg_tm tt,
*tm = &tt;
@@ -348,7 +349,7 @@ mysql_bind_sql_var(Oid type, int attnum, Datum value, MYSQL_BIND *binds,
case BITOID:
{
int32 dat;
- int32 *bufptr = palloc0(sizeof(int32));
+ int32 *bufptr = (int32*)palloc0(sizeof(int32));
char *outputString = NULL;
Oid outputFunctionId = InvalidOid;
bool typeVarLength = false;
@@ -379,7 +380,7 @@ mysql_bind_sql_var(Oid type, int attnum, Datum value, MYSQL_BIND *binds,
dat = VARDATA_4B(result);
}
- bufptr = palloc(len);
+ bufptr = (char*)palloc0(len);
memcpy(bufptr, (char *) dat, len);
binds[attnum].buffer = bufptr;
binds[attnum].buffer_length = len;
diff --git option.c option.cpp
similarity index 99%
rename from option.c
rename to option.cpp
index 30563d0..6d68d7e 100644
--- option.c
+++ option.cpp
@@ -58,7 +58,7 @@ static struct MySQLFdwOption valid_options[] =
{NULL, InvalidOid}
};
-extern Datum mysql_fdw_validator(PG_FUNCTION_ARGS);
+extern "C" Datum mysql_fdw_validator(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(mysql_fdw_validator);
diff --git sql/connection_validation.sql sql/connection_validation.sql
index 97749c1..e72dbaa 100644
--- sql/connection_validation.sql
+++ sql/connection_validation.sql
@@ -1,12 +1,12 @@
\set MYSQL_HOST '\'localhost\''
\set MYSQL_PORT '\'3306\''
\set MYSQL_USER_NAME '\'edb\''
-\set MYSQL_PASS '\'edb\''
+\set MYSQL_PASS '\'Mysql@123!@#\''
-- Before running this file User must create database mysql_fdw_regress on
--- MySQL with all permission for 'edb' user with 'edb' password and ran
--- mysql_init.sh file to create tables.
-
+-- MySQL with all permission for 'edb' user with 'Mysql@123!@#' password and
+-- ran mysql_init.sh file to create tables.
+create database contrib_regression;
\c contrib_regression
CREATE EXTENSION IF NOT EXISTS mysql_fdw;
CREATE SERVER mysql_svr FOREIGN DATA WRAPPER mysql_fdw
diff --git sql/dml.sql sql/dml.sql
index 00fb29b..0c45b56 100644
--- sql/dml.sql
+++ sql/dml.sql
@@ -1,11 +1,11 @@
\set MYSQL_HOST '\'localhost\''
\set MYSQL_PORT '\'3306\''
\set MYSQL_USER_NAME '\'edb\''
-\set MYSQL_PASS '\'edb\''
+\set MYSQL_PASS '\'Mysql@123!@#\''
-- Before running this file User must create database mysql_fdw_regress on
--- MySQL with all permission for 'edb' user with 'edb' password and ran
--- mysql_init.sh file to create tables.
+-- MySQL with all permission for 'edb' user with 'Mysql@123!@#' password and
+-- ran mysql_init.sh file to create tables.
\c contrib_regression
CREATE EXTENSION IF NOT EXISTS mysql_fdw;
@@ -101,6 +101,7 @@ BEGIN
END
$$ language plpgsql;
+---Currently,triggers can only be created on general row-store tables.
CREATE TRIGGER before_row_update_trig
BEFORE UPDATE ON fdw126_ft1
FOR EACH ROW EXECUTE PROCEDURE before_row_update_func();
@@ -135,6 +136,7 @@ BEGIN
END
$$ language plpgsql;
+---Currently,triggers can only be created on general row-store tables.
CREATE TRIGGER before_row_update_trig1
BEFORE UPDATE ON fdw193_ft1
FOR EACH ROW EXECUTE PROCEDURE before_row_update_func();
diff --git sql/pushdown.sql sql/pushdown.sql
index 37af50d..1e37149 100644
--- sql/pushdown.sql
+++ sql/pushdown.sql
@@ -1,11 +1,11 @@
\set MYSQL_HOST '\'localhost\''
\set MYSQL_PORT '\'3306\''
\set MYSQL_USER_NAME '\'edb\''
-\set MYSQL_PASS '\'edb\''
+\set MYSQL_PASS '\'Mysql@123!@#\''
-- Before running this file User must create database mysql_fdw_regress on
--- mysql with all permission for 'edb' user with 'edb' password and ran
--- mysql_init.sh file to create tables.
+-- mysql with all permission for 'edb' user with 'Mysql@123!@#' password and
+-- ran mysql_init.sh file to create tables.
\c contrib_regression
CREATE EXTENSION IF NOT EXISTS mysql_fdw;
diff --git sql/select.sql sql/select.sql
index 1ef8d7c..6ce1ffb 100644
--- sql/select.sql
+++ sql/select.sql
@@ -1,11 +1,11 @@
\set MYSQL_HOST '\'localhost\''
\set MYSQL_PORT '\'3306\''
\set MYSQL_USER_NAME '\'edb\''
-\set MYSQL_PASS '\'edb\''
+\set MYSQL_PASS '\'Mysql@123!@#\''
-- Before running this file User must create database mysql_fdw_regress on
--- MySQL with all permission for 'edb' user with 'edb' password and ran
--- mysql_init.sh file to create tables.
+-- MySQL with all permission for 'edb' user with 'Mysql@123!@#' password and
+-- ran mysql_init.sh file to create tables.
\c contrib_regression
CREATE EXTENSION IF NOT EXISTS mysql_fdw;
@@ -222,6 +222,7 @@ SELECT d.c1, d.c2, e.c1, e.c2, e.c6, e.c8
SELECT d.c1, d.c2, e.c1, e.c2, e.c6, e.c8
FROM f_test_tbl2 d FULL OUTER JOIN l_test_tbl1 e ON d.c1 = e.c8 ORDER BY 1, 3;
+-- LATERAL is not supported now
-- FDW-206: LEFT JOIN LATERAL case should not crash
EXPLAIN (VERBOSE, COSTS OFF)
SELECT * FROM f_mysql_test t1 LEFT JOIN LATERAL (
@@ -275,7 +276,7 @@ SELECT * FROM f_enum_t1 WHERE id = 4;
DROP FOREIGN TABLE f_enum_t1;
DROP TYPE size_t;
-- Create the type with extra enum values.
-CREATE TYPE size_t AS enum('small', 'medium', 'large', 'largest', '');
+CREATE TYPE size_t AS enum('small', 'medium', 'large', 'largest', 'blank');
CREATE FOREIGN TABLE f_enum_t1(id int, size size_t)
SERVER mysql_svr OPTIONS (dbname 'mysql_fdw_regress', table_name 'enum_t1');
@@ -300,6 +301,7 @@ EXPLAIN (VERBOSE, COSTS OFF)
SELECT EXISTS(SELECT 1 FROM pg_enum), sum(id) from f_enum_t1;
SELECT EXISTS(SELECT 1 FROM pg_enum), sum(id) from f_enum_t1;
+-- IMPORT FOREIGN SCHEMA command is not supported now.
-- Check with the IMPORT FOREIGN SCHEMA command. Also, check ENUM types with
-- the IMPORT FOREIGN SCHEMA command. If the enum name is the same for multiple
-- tables, then it should handle correctly by prefixing the table name.
diff --git sql/server_options.sql sql/server_options.sql
index b5c981f..85166d2 100644
--- sql/server_options.sql
+++ sql/server_options.sql
@@ -1,11 +1,11 @@
\set MYSQL_HOST '\'localhost\''
\set MYSQL_PORT '\'3306\''
\set MYSQL_USER_NAME '\'edb\''
-\set MYSQL_PASS '\'edb\''
+\set MYSQL_PASS '\'Mysql@123!@#\''
-- Before running this file User must create database mysql_fdw_regress on
--- MySQL with all permission for 'edb' user with 'edb' password and ran
--- mysql_init.sh file to create tables.
+-- MySQL with all permission for 'edb' user with 'Mysql@123!@#' password and
+-- ran mysql_init.sh file to create tables.
\c contrib_regression
CREATE EXTENSION IF NOT EXISTS mysql_fdw;