Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

FDW extension patch#7

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
NextNext commit
Patch status at 20151001
  • Loading branch information
@pramsey
pramsey committedOct 3, 2015
commit3f5b45b606a781a603578ac73dc79e67da38b275
6 changes: 4 additions & 2 deletionscontrib/postgres_fdw/Makefile
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
# contrib/postgres_fdw/Makefile

MODULE_big = postgres_fdw
OBJS = postgres_fdw.o option.o deparse.o connection.o $(WIN32RES)
OBJS = postgres_fdw.o option.o deparse.o connection.oshippable.o$(WIN32RES)
PGFILEDESC = "postgres_fdw - foreign data wrapper for PostgreSQL"

PG_CPPFLAGS = -I$(libpq_srcdir)
Expand All@@ -10,7 +10,9 @@ SHLIB_LINK = $(libpq)
EXTENSION = postgres_fdw
DATA = postgres_fdw--1.0.sql

REGRESS = postgres_fdw
# Note: shippable tests depend on postgres_fdw tests setup
REGRESS = postgres_fdw shippable
EXTRA_INSTALL = contrib/cube

ifdef USE_PGXS
PG_CONFIG = pg_config
Expand Down
30 changes: 24 additions & 6 deletionscontrib/postgres_fdw/deparse.c
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -233,6 +233,9 @@ foreign_expr_walker(Node *node,
Oidcollation;
FDWCollateState state;

/* Access extension metadata from fpinfo on baserel */
PgFdwRelationInfo *fpinfo = (PgFdwRelationInfo *)(glob_cxt->foreignrel->fdw_private);

/* Need do nothing for empty subexpressions */
if (node == NULL)
return true;
Expand DownExpand Up@@ -378,7 +381,8 @@ foreign_expr_walker(Node *node,
* can't be sent to remote because it might have incompatible
* semantics on remote side.
*/
if (!is_builtin(fe->funcid))
if (!is_builtin(fe->funcid) &&
!is_shippable(fe->funcid, fpinfo->extensions))
return false;

/*
Expand DownExpand Up@@ -426,7 +430,8 @@ foreign_expr_walker(Node *node,
* (If the operator is, surely its underlying function is
* too.)
*/
if (!is_builtin(oe->opno))
if (!is_builtin(oe->opno) &&
!is_shippable(oe->opno, fpinfo->extensions))
return false;

/*
Expand DownExpand Up@@ -466,7 +471,8 @@ foreign_expr_walker(Node *node,
/*
* Again, only built-in operators can be sent to remote.
*/
if (!is_builtin(oe->opno))
if (!is_builtin(oe->opno) &&
!is_shippable(oe->opno, fpinfo->extensions))
return false;

/*
Expand DownExpand Up@@ -616,7 +622,9 @@ foreign_expr_walker(Node *node,
* If result type of given expression is not built-in, it can't be sent to
* remote because it might have incompatible semantics on remote side.
*/
if (check_type && !is_builtin(exprType(node)))
if (check_type &&
!is_builtin(exprType(node)) &&
!is_shippable(exprType(node), fpinfo->extensions))
return false;

/*
Expand DownExpand Up@@ -1351,6 +1359,9 @@ deparseConst(Const *node, deparse_expr_cxt *context)
boolisfloat = false;
boolneedlabel;

/* Access extension metadata from fpinfo on baserel */
PgFdwRelationInfo *fpinfo = (PgFdwRelationInfo *)(context->foreignrel->fdw_private);

if (node->constisnull)
{
appendStringInfoString(buf, "NULL");
Expand DownExpand Up@@ -1428,9 +1439,16 @@ deparseConst(Const *node, deparse_expr_cxt *context)
break;
}
if (needlabel)
{
/*
* References to extension types need to be fully qualified,
* but references to built-in types shouldn't be.
*/
appendStringInfo(buf, "::%s",
format_type_with_typemod(node->consttype,
node->consttypmod));
is_shippable(node->consttype, fpinfo->extensions) ?
format_type_be_qualified(node->consttype) :
format_type_with_typemod(node->consttype, node->consttypmod));
}
}

/*
Expand Down
139 changes: 139 additions & 0 deletionscontrib/postgres_fdw/expected/shippable.out
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
-- ===================================================================
-- create FDW objects
-- ===================================================================
-- Error, extension isn't installed yet
ALTER SERVER loopback OPTIONS (ADD extensions 'cube');
ERROR: required extension "cube" is not installed
HINT: Extension must be installed locally before it can be used on a remote server.
-- Try again
CREATE EXTENSION cube;
ALTER SERVER loopback OPTIONS (ADD extensions 'cube');
ALTER SERVER loopback OPTIONS (DROP extensions);
-- ===================================================================
-- create objects used through FDW loopback server
-- ===================================================================
CREATE SCHEMA "SH 1";
CREATE TABLE "SH 1"."TBL 1" (
"C 1" int NOT NULL,
c2 int NOT NULL,
c3 cube,
c4 timestamptz
);
INSERT INTO "SH 1"."TBL 1"
SELECT id,
2 * id,
cube(id,2*id),
'1970-01-01'::timestamptz + ((id % 100) || ' days')::interval
FROM generate_series(1, 1000) id;
ANALYZE "SH 1"."TBL 1";
-- ===================================================================
-- create foreign table
-- ===================================================================
CREATE FOREIGN TABLE shft1 (
"C 1" int NOT NULL,
c2 int NOT NULL,
c3 cube,
c4 timestamptz
) SERVER loopback
OPTIONS (schema_name 'SH 1', table_name 'TBL 1');
-- ===================================================================
-- simple queries
-- ===================================================================
-- without operator shipping
EXPLAIN (COSTS false) SELECT * FROM shft1 LIMIT 1;
QUERY PLAN
-----------------------------
Limit
-> Foreign Scan on shft1
(2 rows)

EXPLAIN VERBOSE SELECT c2 FROM shft1 WHERE c3 && cube(1.5,2.5);
QUERY PLAN
---------------------------------------------------------------------
Foreign Scan on public.shft1 (cost=100.00..205.06 rows=15 width=4)
Output: c2
Filter: (shft1.c3 && '(1.5),(2.5)'::cube)
Remote SQL: SELECT c2, c3 FROM "SH 1"."TBL 1"
(4 rows)

SELECT c2 FROM shft1 WHERE c3 && cube(1.5,2.5);
c2
----
2
4
(2 rows)

EXPLAIN VERBOSE SELECT c2 FROM shft1 WHERE c3 && '(1.5),(2.5)'::cube;
QUERY PLAN
---------------------------------------------------------------------
Foreign Scan on public.shft1 (cost=100.00..205.06 rows=15 width=4)
Output: c2
Filter: (shft1.c3 && '(1.5),(2.5)'::cube)
Remote SQL: SELECT c2, c3 FROM "SH 1"."TBL 1"
(4 rows)

-- with operator shipping
ALTER SERVER loopback OPTIONS (ADD extensions 'cube');
EXPLAIN VERBOSE SELECT c2 FROM shft1 WHERE c3 && cube(1.5,2.5);
QUERY PLAN
---------------------------------------------------------------------------------------------------------
Foreign Scan on public.shft1 (cost=100.00..146.86 rows=15 width=4)
Output: c2
Remote SQL: SELECT c2 FROM "SH 1"."TBL 1" WHERE ((c3 OPERATOR(public.&&) '(1.5),(2.5)'::public.cube))
(3 rows)

SELECT c2 FROM shft1 WHERE c3 && cube(1.5,2.5);
c2
----
2
4
(2 rows)

EXPLAIN VERBOSE SELECT c2 FROM shft1 WHERE c3 && '(1.5),(2.5)'::cube;
QUERY PLAN
---------------------------------------------------------------------------------------------------------
Foreign Scan on public.shft1 (cost=100.00..146.86 rows=15 width=4)
Output: c2
Remote SQL: SELECT c2 FROM "SH 1"."TBL 1" WHERE ((c3 OPERATOR(public.&&) '(1.5),(2.5)'::public.cube))
(3 rows)

EXPLAIN VERBOSE SELECT cube_dim(c3) FROM shft1 WHERE c3 && '(1.5),(2.5)'::cube;
QUERY PLAN
---------------------------------------------------------------------------------------------------------
Foreign Scan on public.shft1 (cost=100.00..128.43 rows=7 width=32)
Output: cube_dim(c3)
Remote SQL: SELECT c3 FROM "SH 1"."TBL 1" WHERE ((c3 OPERATOR(public.&&) '(1.5),(2.5)'::public.cube))
(3 rows)

SELECT cube_dim(c3) FROM shft1 WHERE c3 && '(1.5),(2.5)'::cube;
cube_dim
----------
1
1
(2 rows)

EXPLAIN VERBOSE SELECT c2 FROM shft1 WHERE cube_dim(c3) = 1 LIMIT 2;
QUERY PLAN
-------------------------------------------------------------------------------------
Limit (cost=100.00..107.22 rows=2 width=4)
Output: c2
-> Foreign Scan on public.shft1 (cost=100.00..154.18 rows=15 width=4)
Output: c2
Remote SQL: SELECT c2 FROM "SH 1"."TBL 1" WHERE ((public.cube_dim(c3) = 1))
(5 rows)

SELECT c2 FROM shft1 WHERE cube_dim(c3) = 1 LIMIT 2;
c2
----
2
4
(2 rows)

-- ===================================================================
-- clean up
-- ===================================================================
DROP FOREIGN TABLE shft1;
DROP TABLE "SH 1"."TBL 1";
DROP SCHEMA "SH 1";
DROP EXTENSION cube;
ALTER SERVER loopback OPTIONS (DROP extensions);
55 changes: 55 additions & 0 deletionscontrib/postgres_fdw/option.c
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,6 +19,8 @@
#include "catalog/pg_foreign_table.h"
#include "catalog/pg_user_mapping.h"
#include "commands/defrem.h"
#include "commands/extension.h"
#include "utils/builtins.h"


/*
Expand DownExpand Up@@ -124,6 +126,11 @@ postgres_fdw_validator(PG_FUNCTION_ARGS)
errmsg("%s requires a non-negative numeric value",
def->defname)));
}
else if (strcmp(def->defname, "extensions") == 0)
{
/* this must have already-installed extensions */
(void) ExtractExtensionList(defGetString(def), false);
}
}

PG_RETURN_VOID();
Expand DownExpand Up@@ -153,6 +160,8 @@ InitPgFdwOptions(void)
/* updatable is available on both server and table */
{"updatable", ForeignServerRelationId, false},
{"updatable", ForeignTableRelationId, false},
/* extensions is available on server */
{"extensions", ForeignServerRelationId, false},
{NULL, InvalidOid, false}
};

Expand DownExpand Up@@ -293,3 +302,49 @@ ExtractConnectionOptions(List *defelems, const char **keywords,
}
return i;
}

/*
* Parse a comma-separated string and return a List of the Oids of the
* extensions in the string. If an extension provided cannot be looked
* up in the catalog (it hasn't been installed or doesn't exist) then
* throw up an error.
*/
List *
ExtractExtensionList(char *extensionString, bool populateList)
{
List *extlist;
List *extensionOids = NIL;
ListCell *l;

if (!SplitIdentifierString(extensionString, ',', &extlist))
{
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid extension list syntax")));
}

foreach(l, extlist)
{
const char *extension_name = (const char *) lfirst(l);
Oid extension_oid = get_extension_oid(extension_name, true);

if (!OidIsValid(extension_oid))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("required extension \"%s\" is not installed",
extension_name),
errhint("Extension must be installed locally before it can be used on a remote server.")));
else if (populateList)
{
/*
* Only add this extension OID to the list if it is not already
* in included.
*/
if (!list_member_oid(extensionOids, extension_oid))
extensionOids = lappend_oid(extensionOids, extension_oid);
}
}

list_free(extlist);
return extensionOids;
}
37 changes: 4 additions & 33 deletionscontrib/postgres_fdw/postgres_fdw.c
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -47,39 +47,6 @@ PG_MODULE_MAGIC;
/* Default CPU cost to process 1 row (above and beyond cpu_tuple_cost). */
#define DEFAULT_FDW_TUPLE_COST0.01

/*
* FDW-specific planner information kept in RelOptInfo.fdw_private for a
* foreign table. This information is collected by postgresGetForeignRelSize.
*/
typedef struct PgFdwRelationInfo
{
/* baserestrictinfo clauses, broken down into safe and unsafe subsets. */
List *remote_conds;
List *local_conds;

/* Bitmap of attr numbers we need to fetch from the remote server. */
Bitmapset *attrs_used;

/* Cost and selectivity of local_conds. */
QualCostlocal_conds_cost;
Selectivity local_conds_sel;

/* Estimated size and cost for a scan with baserestrictinfo quals. */
doublerows;
intwidth;
Coststartup_cost;
Costtotal_cost;

/* Options extracted from catalogs. */
booluse_remote_estimate;
Costfdw_startup_cost;
Costfdw_tuple_cost;

/* Cached catalog information. */
ForeignTable *table;
ForeignServer *server;
UserMapping *user;/* only set in use_remote_estimate mode */
} PgFdwRelationInfo;

/*
* Indexes of FDW-private information stored in fdw_private lists.
Expand DownExpand Up@@ -405,6 +372,7 @@ postgresGetForeignRelSize(PlannerInfo *root,
fpinfo->use_remote_estimate = false;
fpinfo->fdw_startup_cost = DEFAULT_FDW_STARTUP_COST;
fpinfo->fdw_tuple_cost = DEFAULT_FDW_TUPLE_COST;
fpinfo->extensions = NIL;

foreach(lc, fpinfo->server->options)
{
Expand All@@ -416,6 +384,9 @@ postgresGetForeignRelSize(PlannerInfo *root,
fpinfo->fdw_startup_cost = strtod(defGetString(def), NULL);
else if (strcmp(def->defname, "fdw_tuple_cost") == 0)
fpinfo->fdw_tuple_cost = strtod(defGetString(def), NULL);
else if (strcmp(def->defname, "extensions") == 0)
fpinfo->extensions =
ExtractExtensionList(defGetString(def), true);
}
foreach(lc, fpinfo->table->options)
{
Expand Down
Loading

[8]ページ先頭

©2009-2025 Movatter.jp