diff options
| author | Kevin Grittner <kgrittn@postgresql.org> | 2013-03-03 18:23:31 -0600 |
|---|---|---|
| committer | Kevin Grittner <kgrittn@postgresql.org> | 2013-03-03 18:23:31 -0600 |
| commit | 3bf3ab8c563699138be02f9dc305b7b77a724307 (patch) | |
| tree | a36ddfded0bea88ee863595f58f62661cc61948b /src/include | |
| parent | b15a6da29217b14f02895af1d9271e84415a91ae (diff) | |
Add a materialized view relations.
A materialized view has a rule just like a view and a heap and
other physical properties like a table. The rule is only used to
populate the table, references in queries refer to the
materialized data.
This is a minimal implementation, but should still be useful in
many cases. Currently data is only populated "on demand" by the
CREATE MATERIALIZED VIEW and REFRESH MATERIALIZED VIEW statements.
It is expected that future releases will add incremental updates
with various timings, and that a more refined concept of defining
what is "fresh" data will be developed. At some point it may even
be possible to have queries use a materialized in place of
references to underlying tables, but that requires the other
above-mentioned features to be working first.
Much of the documentation work by Robert Haas.
Review by Noah Misch, Thom Brown, Robert Haas, Marko Tiikkaja
Security review by KaiGai Kohei, with a decision on how best to
implement sepgsql still pending.
Diffstat (limited to 'src/include')
| -rw-r--r-- | src/include/catalog/heap.h | 1 | ||||
| -rw-r--r-- | src/include/catalog/pg_class.h | 1 | ||||
| -rw-r--r-- | src/include/catalog/pg_proc.h | 2 | ||||
| -rw-r--r-- | src/include/commands/createas.h | 4 | ||||
| -rw-r--r-- | src/include/commands/explain.h | 4 | ||||
| -rw-r--r-- | src/include/commands/matview.h | 28 | ||||
| -rw-r--r-- | src/include/commands/tablecmds.h | 2 | ||||
| -rw-r--r-- | src/include/commands/view.h | 2 | ||||
| -rw-r--r-- | src/include/executor/executor.h | 1 | ||||
| -rw-r--r-- | src/include/nodes/nodes.h | 1 | ||||
| -rw-r--r-- | src/include/nodes/parsenodes.h | 18 | ||||
| -rw-r--r-- | src/include/nodes/primnodes.h | 4 | ||||
| -rw-r--r-- | src/include/parser/kwlist.h | 2 | ||||
| -rw-r--r-- | src/include/tcop/dest.h | 3 | ||||
| -rw-r--r-- | src/include/utils/builtins.h | 1 | ||||
| -rw-r--r-- | src/include/utils/rel.h | 1 |
16 files changed, 70 insertions, 5 deletions
diff --git a/src/include/catalog/heap.h b/src/include/catalog/heap.h index 3a1788d792b..989089a25af 100644 --- a/src/include/catalog/heap.h +++ b/src/include/catalog/heap.h @@ -70,6 +70,7 @@ extern Oid heap_create_with_catalog(const char *relname, bool is_internal); extern void heap_create_init_fork(Relation rel); +extern bool heap_is_matview_init_state(Relation rel); extern void heap_drop_with_catalog(Oid relid); diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h index 820552f0134..fd97141e9ef 100644 --- a/src/include/catalog/pg_class.h +++ b/src/include/catalog/pg_class.h @@ -153,6 +153,7 @@ DESCR(""); #define RELKIND_VIEW 'v' /* view */ #define RELKIND_COMPOSITE_TYPE 'c' /* composite type */ #define RELKIND_FOREIGN_TABLE 'f' /* foreign table */ +#define RELKIND_MATVIEW 'm' /* materialized view */ #define RELPERSISTENCE_PERMANENT 'p' /* regular table */ #define RELPERSISTENCE_UNLOGGED 'u' /* unlogged permanent table */ diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index d9f50d22d2a..0e26ebf219f 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -1980,6 +1980,8 @@ DATA(insert OID = 3842 ( pg_view_is_insertable PGNSP PGUID 12 10 0 0 0 f f f f DESCR("is a view insertable-into"); DATA(insert OID = 3843 ( pg_view_is_updatable PGNSP PGUID 12 10 0 0 0 f f f f t f s 1 0 16 "26" _null_ _null_ _null_ _null_ pg_view_is_updatable _null_ _null_ _null_ )); DESCR("is a view updatable"); +DATA(insert OID = 3846 ( pg_relation_is_scannable PGNSP PGUID 12 10 0 0 0 f f f f t f s 1 0 16 "26" _null_ _null_ _null_ _null_ pg_relation_is_scannable _null_ _null_ _null_ )); +DESCR("is a relation scannable"); /* Deferrable unique constraint trigger */ DATA(insert OID = 1250 ( unique_key_recheck PGNSP PGUID 12 1 0 0 0 f f f f t f v 0 0 2279 "" _null_ _null_ _null_ _null_ unique_key_recheck _null_ _null_ _null_ )); diff --git a/src/include/commands/createas.h b/src/include/commands/createas.h index 2ac718762b6..012334b42e1 100644 --- a/src/include/commands/createas.h +++ b/src/include/commands/createas.h @@ -19,6 +19,10 @@ #include "tcop/dest.h" +extern Query *SetupForCreateTableAs(Query *query, IntoClause *into, + const char *queryString, + ParamListInfo params, DestReceiver *dest); + extern void ExecCreateTableAs(CreateTableAsStmt *stmt, const char *queryString, ParamListInfo params, char *completionTag); diff --git a/src/include/commands/explain.h b/src/include/commands/explain.h index ca213d7f704..24ef493115e 100644 --- a/src/include/commands/explain.h +++ b/src/include/commands/explain.h @@ -67,8 +67,8 @@ extern void ExplainOneUtility(Node *utilityStmt, IntoClause *into, const char *queryString, ParamListInfo params); extern void ExplainOnePlan(PlannedStmt *plannedstmt, IntoClause *into, - ExplainState *es, - const char *queryString, ParamListInfo params); + ExplainState *es, const char *queryString, + DestReceiver *dest, ParamListInfo params); extern void ExplainPrintPlan(ExplainState *es, QueryDesc *queryDesc); diff --git a/src/include/commands/matview.h b/src/include/commands/matview.h new file mode 100644 index 00000000000..6de3c1aa93a --- /dev/null +++ b/src/include/commands/matview.h @@ -0,0 +1,28 @@ +/*------------------------------------------------------------------------- + * + * matview.h + * prototypes for matview.c. + * + * + * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/commands/matview.h + * + *------------------------------------------------------------------------- + */ +#ifndef MATVIEW_H +#define MATVIEW_H + +#include "nodes/params.h" +#include "tcop/dest.h" +#include "utils/relcache.h" + +extern void SetRelationIsScannable(Relation relation); + +extern void ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString, + ParamListInfo params, char *completionTag); + +extern DestReceiver *CreateTransientRelDestReceiver(Oid oid); + +#endif /* MATVIEW_H */ diff --git a/src/include/commands/tablecmds.h b/src/include/commands/tablecmds.h index 27dc5e8ebbb..031c77c9efd 100644 --- a/src/include/commands/tablecmds.h +++ b/src/include/commands/tablecmds.h @@ -78,4 +78,6 @@ extern void AtEOSubXact_on_commit_actions(bool isCommit, extern void RangeVarCallbackOwnsTable(const RangeVar *relation, Oid relId, Oid oldRelId, void *arg); +extern bool isQueryUsingTempRelation(Query *query); + #endif /* TABLECMDS_H */ diff --git a/src/include/commands/view.h b/src/include/commands/view.h index ff80ed6a446..972c7d208ce 100644 --- a/src/include/commands/view.h +++ b/src/include/commands/view.h @@ -18,4 +18,6 @@ extern Oid DefineView(ViewStmt *stmt, const char *queryString); +extern void StoreViewQuery(Oid viewOid, Query *viewParse, bool replace); + #endif /* VIEW_H */ diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h index b1213a06350..aec6c7f7dfe 100644 --- a/src/include/executor/executor.h +++ b/src/include/executor/executor.h @@ -61,6 +61,7 @@ #define EXEC_FLAG_SKIP_TRIGGERS 0x0010 /* skip AfterTrigger calls */ #define EXEC_FLAG_WITH_OIDS 0x0020 /* force OIDs in returned tuples */ #define EXEC_FLAG_WITHOUT_OIDS 0x0040 /* force no OIDs in returned tuples */ +#define EXEC_FLAG_WITH_NO_DATA 0x0080 /* rel scannability doesn't matter */ /* diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h index 0854579fdf7..0d5c007f935 100644 --- a/src/include/nodes/nodes.h +++ b/src/include/nodes/nodes.h @@ -361,6 +361,7 @@ typedef enum NodeTag T_AlterExtensionContentsStmt, T_CreateEventTrigStmt, T_AlterEventTrigStmt, + T_RefreshMatViewStmt, /* * TAGS FOR PARSE TREE NODES (parsenodes.h) diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index d54990d39c1..2229ef0f95a 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -713,6 +713,7 @@ typedef struct RangeTblEntry */ Oid relid; /* OID of the relation */ char relkind; /* relation kind (see pg_class.relkind) */ + bool isResultRel; /* used in target of SELECT INTO or similar */ /* * Fields valid for a subquery RTE (else NULL): @@ -1135,6 +1136,7 @@ typedef enum ObjectType OBJECT_INDEX, OBJECT_LANGUAGE, OBJECT_LARGEOBJECT, + OBJECT_MATVIEW, OBJECT_OPCLASS, OBJECT_OPERATOR, OBJECT_OPFAMILY, @@ -2447,6 +2449,8 @@ typedef struct ExplainStmt * A query written as CREATE TABLE AS will produce this node type natively. * A query written as SELECT ... INTO will be transformed to this form during * parse analysis. + * A query written as CREATE MATERIALIZED view will produce this node type, + * during parse analysis, since it needs all the same data. * * The "query" field is handled similarly to EXPLAIN, though note that it * can be a SELECT or an EXECUTE, but not other DML statements. @@ -2457,10 +2461,22 @@ typedef struct CreateTableAsStmt NodeTag type; Node *query; /* the query (see comments above) */ IntoClause *into; /* destination table */ + ObjectType relkind; /* type of object */ bool is_select_into; /* it was written as SELECT INTO */ } CreateTableAsStmt; /* ---------------------- + * REFRESH MATERIALIZED VIEW Statement + * ---------------------- + */ +typedef struct RefreshMatViewStmt +{ + NodeTag type; + bool skipData; /* true for WITH NO DATA */ + RangeVar *relation; /* relation to insert into */ +} RefreshMatViewStmt; + +/* ---------------------- * Checkpoint Statement * ---------------------- */ @@ -2517,7 +2533,7 @@ typedef struct ConstraintsSetStmt typedef struct ReindexStmt { NodeTag type; - ObjectType kind; /* OBJECT_INDEX, OBJECT_TABLE, OBJECT_DATABASE */ + ObjectType kind; /* OBJECT_INDEX, OBJECT_TABLE, etc. */ RangeVar *relation; /* Table or index to reindex */ const char *name; /* name of database to reindex */ bool do_system; /* include system tables in database case */ diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h index 1d657669e13..27d4e4cd675 100644 --- a/src/include/nodes/primnodes.h +++ b/src/include/nodes/primnodes.h @@ -80,7 +80,8 @@ typedef struct RangeVar } RangeVar; /* - * IntoClause - target information for SELECT INTO and CREATE TABLE AS + * IntoClause - target information for SELECT INTO, CREATE TABLE AS, and + * CREATE MATERIALIZED VIEW */ typedef struct IntoClause { @@ -92,6 +93,7 @@ typedef struct IntoClause OnCommitAction onCommit; /* what do we do at COMMIT? */ char *tableSpaceName; /* table space to use, or NULL */ bool skipData; /* true for WITH NO DATA */ + char relkind; /* RELKIND_RELATION or RELKIND_MATVIEW */ } IntoClause; diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h index 6f67a65f3d1..68a13b7a7ba 100644 --- a/src/include/parser/kwlist.h +++ b/src/include/parser/kwlist.h @@ -232,6 +232,7 @@ PG_KEYWORD("location", LOCATION, UNRESERVED_KEYWORD) PG_KEYWORD("lock", LOCK_P, UNRESERVED_KEYWORD) PG_KEYWORD("mapping", MAPPING, UNRESERVED_KEYWORD) PG_KEYWORD("match", MATCH, UNRESERVED_KEYWORD) +PG_KEYWORD("materialized", MATERIALIZED, UNRESERVED_KEYWORD) PG_KEYWORD("maxvalue", MAXVALUE, UNRESERVED_KEYWORD) PG_KEYWORD("minute", MINUTE_P, UNRESERVED_KEYWORD) PG_KEYWORD("minvalue", MINVALUE, UNRESERVED_KEYWORD) @@ -302,6 +303,7 @@ PG_KEYWORD("recheck", RECHECK, UNRESERVED_KEYWORD) PG_KEYWORD("recursive", RECURSIVE, UNRESERVED_KEYWORD) PG_KEYWORD("ref", REF, UNRESERVED_KEYWORD) PG_KEYWORD("references", REFERENCES, RESERVED_KEYWORD) +PG_KEYWORD("refresh", REFRESH, UNRESERVED_KEYWORD) PG_KEYWORD("reindex", REINDEX, UNRESERVED_KEYWORD) PG_KEYWORD("relative", RELATIVE_P, UNRESERVED_KEYWORD) PG_KEYWORD("release", RELEASE, UNRESERVED_KEYWORD) diff --git a/src/include/tcop/dest.h b/src/include/tcop/dest.h index 6e260bdfa2c..79002184be8 100644 --- a/src/include/tcop/dest.h +++ b/src/include/tcop/dest.h @@ -93,7 +93,8 @@ typedef enum DestTuplestore, /* results sent to Tuplestore */ DestIntoRel, /* results sent to relation (SELECT INTO) */ DestCopyOut, /* results sent to COPY TO code */ - DestSQLFunction /* results sent to SQL-language func mgr */ + DestSQLFunction, /* results sent to SQL-language func mgr */ + DestTransientRel /* results sent to transient relation */ } CommandDest; /* ---------------- diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h index 533539ca293..c0debe400c4 100644 --- a/src/include/utils/builtins.h +++ b/src/include/utils/builtins.h @@ -461,6 +461,7 @@ extern Datum pg_table_size(PG_FUNCTION_ARGS); extern Datum pg_indexes_size(PG_FUNCTION_ARGS); extern Datum pg_relation_filenode(PG_FUNCTION_ARGS); extern Datum pg_relation_filepath(PG_FUNCTION_ARGS); +extern Datum pg_relation_is_scannable(PG_FUNCTION_ARGS); /* genfile.c */ extern bytea *read_binary_file(const char *filename, diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h index c342eaa66f2..06e1531e9a3 100644 --- a/src/include/utils/rel.h +++ b/src/include/utils/rel.h @@ -83,6 +83,7 @@ typedef struct RelationData BackendId rd_backend; /* owning backend id, if temporary relation */ bool rd_islocaltemp; /* rel is a temp rel of this session */ bool rd_isnailed; /* rel is nailed in cache */ + bool rd_isscannable; /* rel can be scanned */ bool rd_isvalid; /* relcache entry is valid */ char rd_indexvalid; /* state of rd_indexlist: 0 = not valid, 1 = * valid, 2 = temporarily forced */ |
