Fix foreign table ddl failed.

This commit is contained in:
TotaJ
2022-05-13 17:15:28 +08:00
parent 6c5898646e
commit ed95a895b4
7 changed files with 148 additions and 19 deletions

View File

@ -3492,15 +3492,17 @@ void heap_drop_with_catalog(Oid relid)
* When we drop a foreign partition table, we need to delete the corresponding
* tuple in pg_partition.
*/
FdwRoutine* fdwRoutine = GetFdwRoutineByRelId(relid);
if (NULL != fdwRoutine->PartitionTblProcess) {
fdwRoutine->PartitionTblProcess(NULL, relid, HDFS_DROP_PARTITIONED_FOREIGNTBL);
}
FdwRoutine* fdwRoutine = GetFdwRoutineByRelId(relid, true);
if (fdwRoutine != NULL) {
if (NULL != fdwRoutine->PartitionTblProcess) {
fdwRoutine->PartitionTblProcess(NULL, relid, HDFS_DROP_PARTITIONED_FOREIGNTBL);
}
#ifdef ENABLE_MOT
/* Forward drop stmt to MOT FDW. */
MotFdwDropForeignRelation(rel, fdwRoutine);
/* Forward drop stmt to MOT FDW. */
MotFdwDropForeignRelation(rel, fdwRoutine);
#endif
}
}
/* drop enty for pg_partition */

View File

@ -498,8 +498,9 @@ FdwRoutine* GetFdwRoutine(Oid fdwhandler)
/*
* GetFdwRoutineByRelId - look up the handler of the foreign-data wrapper
* for the given foreign table, and retrieve its FdwRoutine struct.
* If missHandlerOk is true, will return NULL if the fdwhandler is invalid.
*/
FdwRoutine* GetFdwRoutineByRelId(Oid relid)
FdwRoutine* GetFdwRoutineByRelId(Oid relid, bool missHandlerOk)
{
HeapTuple tp;
Form_pg_foreign_data_wrapper fdwform;
@ -539,6 +540,9 @@ FdwRoutine* GetFdwRoutineByRelId(Oid relid)
/* Complain if FDW has been set to NO HANDLER. */
if (!OidIsValid(fdwhandler)) {
if (missHandlerOk) {
return NULL;
}
ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("foreign-data wrapper \"%s\" has no handler", NameStr(fdwform->fdwname))));

View File

@ -1694,12 +1694,15 @@ void CreateForeignTable(CreateForeignTableStmt* stmt, Oid relid)
/* @hdfs
* Check column data type and distribute by clause.
*/
FdwRoutine* fdwroutine = GetFdwRoutine(fdw->fdwhandler);
if (NULL != fdwroutine->ValidateTableDef) {
FdwRoutine* fdwroutine = NULL;
if (OidIsValid(fdw->fdwhandler)) {
fdwroutine = GetFdwRoutine(fdw->fdwhandler);
if (NULL != fdwroutine->ValidateTableDef) {
#ifdef ENABLE_MOT
stmt->base.relation->foreignOid = relid;
stmt->base.relation->foreignOid = relid;
#endif
fdwroutine->ValidateTableDef((Node*)stmt);
fdwroutine->ValidateTableDef((Node*)stmt);
}
}
#ifdef ENABLE_MOT
@ -1936,7 +1939,7 @@ void CreateForeignTable(CreateForeignTableStmt* stmt, Oid relid)
/* @hdfs
* When we create a hdfs partition foreign table, we need to do some more processes.
*/
if (NULL != fdwroutine->PartitionTblProcess) {
if (fdwroutine != NULL && NULL != fdwroutine->PartitionTblProcess) {
fdwroutine->PartitionTblProcess((Node*)stmt, relid, HDFS_CREATE_PARTITIONED_FOREIGNTBL);
CommandCounterIncrement();
}

View File

@ -6821,9 +6821,9 @@ void AlterTable(Oid relid, LOCKMODE lockmode, AlterTableStmt* stmt)
* Each type foreign table has own mchanism, we use function pointor to realize. For example,
* wheather support alter owner, support alter colomn type, etc.
*/
FdwRoutine* fdwroutine = GetFdwRoutineByRelId(relid);
FdwRoutine* fdwroutine = GetFdwRoutineByRelId(relid, true);
if (NULL != fdwroutine->ValidateTableDef) {
if (fdwroutine != NULL && NULL != fdwroutine->ValidateTableDef) {
fdwroutine->ValidateTableDef((Node*)stmt);
}

View File

@ -199,7 +199,7 @@ typedef struct FdwRoutine {
/* Functions in foreign/foreign.c */
extern FdwRoutine* GetFdwRoutine(Oid fdwhandler);
extern FdwRoutine* GetFdwRoutineByRelId(Oid relid);
extern FdwRoutine* GetFdwRoutineByRelId(Oid relid, bool missHandlerOk = false);
extern FdwRoutine* GetFdwRoutineByServerId(Oid serverid);
extern FdwRoutine* GetFdwRoutineForRelation(Relation relation, bool makecopy);

View File

@ -1,6 +1,7 @@
--clear audit log
SELECT pg_delete_audit('1012-11-10', '3012-11-11');
\! @abs_bindir@/gs_guc reload -D @abs_srcdir@/tmp_check/datanode1/ -c "audit_system_object=67108863" > /dev/null 2>&1
select pg_sleep(1);
CREATE ROLE regress_test_foreign SYSADMIN IDENTIFIED BY 'test-1234';
@ -10,20 +11,36 @@ ALTER FOREIGN DATA WRAPPER fdw_audit_dummy OPTIONS (a '1', b '2');
ALTER FOREIGN DATA WRAPPER fdw_audit_dummy OWNER TO regress_test_foreign;
ALTER FOREIGN DATA WRAPPER fdw_audit_dummy RENAME TO fdw_audit_dummy2;
CREATE SERVER s1 FOREIGN DATA WRAPPER fdw_audit_dummy2;
ALTER SERVER s1 VERSION '1.1';
ALTER SERVER s1 OPTIONS (connect_timeout '30');
ALTER SERVER s1 OWNER TO regress_test_foreign;
ALTER SERVER s1 RENAME to s1new;
CREATE FOREIGN TABLE f1 (a int, b int, c text) SERVER s1new;
\d f1
ALTER FOREIGN TABLE f1 OPTIONS (schema_name 'S 1', table_name 'T 1');
\d f1
ALTER FOREIGN TABLE f1 ALTER COLUMN a OPTIONS (column_name 'A 1');
\d f1
ALTER FOREIGN TABLE f1 DROP COLUMN b;
\d f1
ALTER FOREIGN TABLE f1 ADD COLUMN d int;
\d f1
ALTER FOREIGN TABLE f1 ALTER COLUMN a TYPE float;
\d f1
ALTER FOREIGN TABLE f1 RENAME to f1new;
\d f1new
DROP FOREIGN TABLE f1new;
DROP SERVER s1new;
DROP FOREIGN DATA WRAPPER IF EXISTS fdw_audit_dummy2;
DROP ROLE regress_test_foreign;
SELECT object_name,detail_info FROM pg_query_audit('2022-01-13 9:30:00', '2031-12-12 22:00:00') where type = 'ddl_foreign_data_wrapper' or type = 'ddl_serverforhadoop' order by object_name,detail_info;
SELECT object_name,detail_info FROM pg_query_audit('2022-01-13 9:30:00', '2031-12-12 22:00:00') where type = 'ddl_foreign_data_wrapper' or type = 'ddl_serverforhadoop' or type = 'ddl_table' order by object_name,detail_info;
--clear audit log
SELECT pg_delete_audit('1012-11-10', '3012-11-11');
\! @abs_bindir@/gs_guc reload -D @abs_srcdir@/tmp_check/datanode1/ -c "audit_system_object" > /dev/null 2>&1
select pg_sleep(1);

View File

@ -6,6 +6,12 @@ SELECT pg_delete_audit('1012-11-10', '3012-11-11');
(1 row)
\! @abs_bindir@/gs_guc reload -D @abs_srcdir@/tmp_check/datanode1/ -c "audit_system_object=67108863" > /dev/null 2>&1
select pg_sleep(1);
pg_sleep
----------
(1 row)
CREATE ROLE regress_test_foreign SYSADMIN IDENTIFIED BY 'test-1234';
CREATE FOREIGN DATA WRAPPER fdw_audit_dummy;
ALTER FOREIGN DATA WRAPPER fdw_audit_dummy NO VALIDATOR;
@ -17,12 +23,103 @@ ALTER SERVER s1 VERSION '1.1';
ALTER SERVER s1 OPTIONS (connect_timeout '30');
ALTER SERVER s1 OWNER TO regress_test_foreign;
ALTER SERVER s1 RENAME to s1new;
CREATE FOREIGN TABLE f1 (a int, b int, c text) SERVER s1new;
\d f1
Foreign table "public.f1"
Column | Type | Modifiers | FDW Options
--------+---------+-----------+-------------
a | integer | |
b | integer | |
c | text | |
Server: s1new
FDW permition: read only
ALTER FOREIGN TABLE f1 OPTIONS (schema_name 'S 1', table_name 'T 1');
\d f1
Foreign table "public.f1"
Column | Type | Modifiers | FDW Options
--------+---------+-----------+-------------
a | integer | |
b | integer | |
c | text | |
Server: s1new
FDW Options: (schema_name 'S 1', table_name 'T 1')
FDW permition: read only
ALTER FOREIGN TABLE f1 ALTER COLUMN a OPTIONS (column_name 'A 1');
\d f1
Foreign table "public.f1"
Column | Type | Modifiers | FDW Options
--------+---------+-----------+---------------------
a | integer | | (column_name 'A 1')
b | integer | |
c | text | |
Server: s1new
FDW Options: (schema_name 'S 1', table_name 'T 1')
FDW permition: read only
ALTER FOREIGN TABLE f1 DROP COLUMN b;
\d f1
Foreign table "public.f1"
Column | Type | Modifiers | FDW Options
--------+---------+-----------+---------------------
a | integer | | (column_name 'A 1')
c | text | |
Server: s1new
FDW Options: (schema_name 'S 1', table_name 'T 1')
FDW permition: read only
ALTER FOREIGN TABLE f1 ADD COLUMN d int;
\d f1
Foreign table "public.f1"
Column | Type | Modifiers | FDW Options
--------+---------+-----------+---------------------
a | integer | | (column_name 'A 1')
c | text | |
d | integer | |
Server: s1new
FDW Options: (schema_name 'S 1', table_name 'T 1')
FDW permition: read only
ALTER FOREIGN TABLE f1 ALTER COLUMN a TYPE float;
\d f1
Foreign table "public.f1"
Column | Type | Modifiers | FDW Options
--------+------------------+-----------+---------------------
a | double precision | | (column_name 'A 1')
c | text | |
d | integer | |
Server: s1new
FDW Options: (schema_name 'S 1', table_name 'T 1')
FDW permition: read only
ALTER FOREIGN TABLE f1 RENAME to f1new;
\d f1new
Foreign table "public.f1new"
Column | Type | Modifiers | FDW Options
--------+------------------+-----------+---------------------
a | double precision | | (column_name 'A 1')
c | text | |
d | integer | |
Server: s1new
FDW Options: (schema_name 'S 1', table_name 'T 1')
FDW permition: read only
DROP FOREIGN TABLE f1new;
DROP SERVER s1new;
DROP FOREIGN DATA WRAPPER IF EXISTS fdw_audit_dummy2;
DROP ROLE regress_test_foreign;
SELECT object_name,detail_info FROM pg_query_audit('2022-01-13 9:30:00', '2031-12-12 22:00:00') where type = 'ddl_foreign_data_wrapper' or type = 'ddl_serverforhadoop' order by object_name,detail_info;
SELECT object_name,detail_info FROM pg_query_audit('2022-01-13 9:30:00', '2031-12-12 22:00:00') where type = 'ddl_foreign_data_wrapper' or type = 'ddl_serverforhadoop' or type = 'ddl_table' order by object_name,detail_info;
object_name | detail_info
------------------+---------------------------------------------------------------------------
f1 | ALTER FOREIGN TABLE f1 ADD COLUMN d int;
f1 | ALTER FOREIGN TABLE f1 ALTER COLUMN a OPTIONS (column_name 'A 1');
f1 | ALTER FOREIGN TABLE f1 ALTER COLUMN a TYPE float;
f1 | ALTER FOREIGN TABLE f1 DROP COLUMN b;
f1 | ALTER FOREIGN TABLE f1 OPTIONS (schema_name 'S 1', table_name 'T 1');
f1 | ALTER FOREIGN TABLE f1 RENAME to f1new;
f1 | CREATE FOREIGN TABLE f1 (a int, b int, c text) SERVER s1new;
f1new | DROP FOREIGN TABLE f1new;
fdw_audit_dummy | ALTER FOREIGN DATA WRAPPER fdw_audit_dummy NO VALIDATOR;
fdw_audit_dummy | ALTER FOREIGN DATA WRAPPER fdw_audit_dummy OPTIONS (a '1', b '2');
fdw_audit_dummy | ALTER FOREIGN DATA WRAPPER fdw_audit_dummy OWNER TO regress_test_foreign;
@ -35,7 +132,7 @@ SELECT object_name,detail_info FROM pg_query_audit('2022-01-13 9:30:00', '2031-1
s1 | ALTER SERVER s1 VERSION '1.1';
s1 | CREATE SERVER s1 FOREIGN DATA WRAPPER fdw_audit_dummy2;
s1new | DROP SERVER s1new;
(12 rows)
(20 rows)
--clear audit log
SELECT pg_delete_audit('1012-11-10', '3012-11-11');
@ -45,3 +142,9 @@ SELECT pg_delete_audit('1012-11-10', '3012-11-11');
(1 row)
\! @abs_bindir@/gs_guc reload -D @abs_srcdir@/tmp_check/datanode1/ -c "audit_system_object" > /dev/null 2>&1
select pg_sleep(1);
pg_sleep
----------
(1 row)