Skip to content

Commit

Permalink
CREATE FOREIGN TABLE LIKE.
Browse files Browse the repository at this point in the history
Allow user to use LIKE to create foreign tables, ex:
CREATE FOREIGN TABLE ft(LIKE t1);
Foreign table ft will use t1's column definitions as its own.

In CBDB, we usually use foreign tables to import data from outside
data source.
Each target table usually has an associated foreign table.
This is very useful if target table has a lot of columns, making
it easy to create a foreign table without defining columns
one by one, and avoid mistake.

Distribution policy is not inherited for this case because it
should be defined with options by users.

Authored-by: Zhang Mingli avamingli@gmail.com
  • Loading branch information
avamingli committed Aug 7, 2024
1 parent 1ce51c5 commit 4122a93
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 0 deletions.
11 changes: 11 additions & 0 deletions src/backend/parser/parse_utilcmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -396,13 +396,19 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString)
likeDistributedBy, bQuiet);
}

/*
* CBDB: for a foreign table, do not inherit source table's distribution policy.
* It should be decided by OPTIONS, ex: mpp_execute all segments.
*/
#if 0
if (IsA(stmt, CreateForeignTableStmt))
{
DistributedBy *ft_distributedBy = ((CreateForeignTableStmt *)stmt)->distributedBy;
if (ft_distributedBy || likeDistributedBy)
stmt->distributedBy = transformDistributedBy(pstate, &cxt, ft_distributedBy,
likeDistributedBy, bQuiet);
}
#endif

/*
* Postprocess check constraints.
Expand Down Expand Up @@ -1071,11 +1077,16 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("LIKE INCLUDING may not be used with this kind of relation")));

/*
* CBDB: Support CREATE FOREIGN TABLE LIKE.
*/
#if 0
/* we could support LIKE in many cases, but worry about it another day */
if (cxt->isforeign)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("LIKE is not supported for creating foreign tables")));
#endif

/* Open the relation referenced by the LIKE clause */
relation = relation_openrv(table_like_clause->relation, AccessShareLock);
Expand Down
38 changes: 38 additions & 0 deletions src/test/regress/expected/gp_foreign_data.out
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,44 @@ CREATE FOREIGN TABLE ft5 (
Server: s1
FDW options: (delimiter ',', mpp_execute 'all segments', num_segments '5')

-- CREATE FOREIGN TABLE LIKE
CREATE TABLE ft_source_table(a INT, b INT, c INT) DISTRIBUTED BY (b);
CREATE FOREIGN TABLE ft_like (LIKE ft_source_table) SERVER s0;
\d+ ft_like
Foreign table "public.ft_like"
Column | Type | Collation | Nullable | Default | FDW options | Storage | Stats target | Description
--------+---------+-----------+----------+---------+-------------+---------+--------------+-------------
a | integer | | | | | plain | |
b | integer | | | | | plain | |
c | integer | | | | | plain | |
Server: s0

-- shoule be null
SELECT * FROM gp_distribution_policy WHERE localoid = 'ft_like'::regclass::oid;
localoid | policytype | numsegments | distkey | distclass
----------+------------+-------------+---------+-----------
(0 rows)

CREATE FOREIGN TABLE ft_like1 (LIKE ft_source_table) SERVER s0
OPTIONS (delimiter ',', mpp_execute 'all segments', num_segments '3');
\d+ ft_like1
Foreign table "public.ft_like1"
Column | Type | Collation | Nullable | Default | FDW options | Storage | Stats target | Description
--------+---------+-----------+----------+---------+-------------+---------+--------------+-------------
a | integer | | | | | plain | |
b | integer | | | | | plain | |
c | integer | | | | | plain | |
Server: s0
FDW options: (delimiter ',', mpp_execute 'all segments', num_segments '3')

SELECT * FROM gp_distribution_policy WHERE localoid = 'ft_like1'::regclass::oid;
localoid | policytype | numsegments | distkey | distclass
----------+------------+-------------+---------+-----------
(0 rows)

DROP TABLE ft_source_table;
DROP FOREIGN TABLE ft_like;
DROP FOREIGN TABLE ft_like1;
--start_ignore
DROP FOREIGN DATA WRAPPER dummy CASCADE;
--end_ignore
15 changes: 15 additions & 0 deletions src/test/regress/sql/gp_foreign_data.sql
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,21 @@ CREATE FOREIGN TABLE ft5 (
) SERVER s1 OPTIONS (delimiter ',', mpp_execute 'all segments', num_segments '5');
\d+ ft5

-- CREATE FOREIGN TABLE LIKE
CREATE TABLE ft_source_table(a INT, b INT, c INT) DISTRIBUTED BY (b);
CREATE FOREIGN TABLE ft_like (LIKE ft_source_table) SERVER s0;
\d+ ft_like
-- shoule be null
SELECT * FROM gp_distribution_policy WHERE localoid = 'ft_like'::regclass::oid;
CREATE FOREIGN TABLE ft_like1 (LIKE ft_source_table) SERVER s0
OPTIONS (delimiter ',', mpp_execute 'all segments', num_segments '3');
\d+ ft_like1
SELECT * FROM gp_distribution_policy WHERE localoid = 'ft_like1'::regclass::oid;

DROP TABLE ft_source_table;
DROP FOREIGN TABLE ft_like;
DROP FOREIGN TABLE ft_like1;

--start_ignore
DROP FOREIGN DATA WRAPPER dummy CASCADE;
--end_ignore

0 comments on commit 4122a93

Please sign in to comment.