summaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
authorTom Lane2012-03-20 01:37:19 +0000
committerTom Lane2012-03-20 01:38:12 +0000
commit9dbf2b7d75de5af38d087cbe2b1147dd0fd10f0a (patch)
treed58e41d2855f7ac2a5c4c1c4893aaf6f03e1aabc /src/include
parent77503a7638a35eedd9cb08d9ca4c54deb203521d (diff)
Restructure SELECT INTO's parsetree representation into CreateTableAsStmt.
Making this operation look like a utility statement seems generally a good idea, and particularly so in light of the desire to provide command triggers for utility statements. The original choice of representing it as SELECT with an IntoClause appendage had metastasized into rather a lot of places, unfortunately, so that this patch is a great deal more complicated than one might at first expect. In particular, keeping EXPLAIN working for SELECT INTO and CREATE TABLE AS subcommands required restructuring some EXPLAIN-related APIs. Add-on code that calls ExplainOnePlan or ExplainOneUtility, or uses ExplainOneQuery_hook, will need adjustment. Also, the cases PREPARE ... SELECT INTO and CREATE RULE ... SELECT INTO, which formerly were accepted though undocumented, are no longer accepted. The PREPARE case can be replaced with use of CREATE TABLE AS EXECUTE. The CREATE RULE case doesn't seem to have much real-world use (since the rule would work only once before failing with "table already exists"), so we'll not bother with that one. Both SELECT INTO and CREATE TABLE AS still return a command tag of "SELECT nnnn". There was some discussion of returning "CREATE TABLE nnnn", but for the moment backwards compatibility wins the day. Andres Freund and Tom Lane
Diffstat (limited to 'src/include')
-rw-r--r--src/include/catalog/catversion.h2
-rw-r--r--src/include/commands/createas.h29
-rw-r--r--src/include/commands/explain.h7
-rw-r--r--src/include/commands/prepare.h9
-rw-r--r--src/include/executor/executor.h11
-rw-r--r--src/include/nodes/execnodes.h2
-rw-r--r--src/include/nodes/nodes.h1
-rw-r--r--src/include/nodes/parsenodes.h26
-rw-r--r--src/include/nodes/plannodes.h2
-rw-r--r--src/include/parser/analyze.h2
-rw-r--r--src/include/tcop/pquery.h2
-rw-r--r--src/include/tcop/utility.h2
12 files changed, 75 insertions, 20 deletions
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index 59fd53d2c5f..5d896bd11ae 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 201203111
+#define CATALOG_VERSION_NO 201203191
#endif
diff --git a/src/include/commands/createas.h b/src/include/commands/createas.h
new file mode 100644
index 00000000000..ed65ccd8ee3
--- /dev/null
+++ b/src/include/commands/createas.h
@@ -0,0 +1,29 @@
+/*-------------------------------------------------------------------------
+ *
+ * createas.h
+ * prototypes for createas.c.
+ *
+ *
+ * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/commands/createas.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef CREATEAS_H
+#define CREATEAS_H
+
+#include "nodes/params.h"
+#include "nodes/parsenodes.h"
+#include "tcop/dest.h"
+
+
+extern void ExecCreateTableAs(CreateTableAsStmt *stmt, const char *queryString,
+ ParamListInfo params, char *completionTag);
+
+extern int GetIntoRelEFlags(IntoClause *intoClause);
+
+extern DestReceiver *CreateIntoRelDestReceiver(IntoClause *intoClause);
+
+#endif /* CREATEAS_H */
diff --git a/src/include/commands/explain.h b/src/include/commands/explain.h
index a987c431242..e4e98bfb043 100644
--- a/src/include/commands/explain.h
+++ b/src/include/commands/explain.h
@@ -42,6 +42,7 @@ typedef struct ExplainState
/* Hook for plugins to get control in ExplainOneQuery() */
typedef void (*ExplainOneQuery_hook_type) (Query *query,
+ IntoClause *into,
ExplainState *es,
const char *queryString,
ParamListInfo params);
@@ -59,10 +60,12 @@ extern void ExplainInitState(ExplainState *es);
extern TupleDesc ExplainResultDesc(ExplainStmt *stmt);
-extern void ExplainOneUtility(Node *utilityStmt, ExplainState *es,
+extern void ExplainOneUtility(Node *utilityStmt, IntoClause *into,
+ ExplainState *es,
const char *queryString, ParamListInfo params);
-extern void ExplainOnePlan(PlannedStmt *plannedstmt, ExplainState *es,
+extern void ExplainOnePlan(PlannedStmt *plannedstmt, IntoClause *into,
+ ExplainState *es,
const char *queryString, ParamListInfo params);
extern void ExplainPrintPlan(ExplainState *es, QueryDesc *queryDesc);
diff --git a/src/include/commands/prepare.h b/src/include/commands/prepare.h
index 472a357c299..f688be77a32 100644
--- a/src/include/commands/prepare.h
+++ b/src/include/commands/prepare.h
@@ -35,11 +35,12 @@ typedef struct
/* Utility statements PREPARE, EXECUTE, DEALLOCATE, EXPLAIN EXECUTE */
extern void PrepareQuery(PrepareStmt *stmt, const char *queryString);
-extern void ExecuteQuery(ExecuteStmt *stmt, const char *queryString,
- ParamListInfo params,
+extern void ExecuteQuery(ExecuteStmt *stmt, IntoClause *intoClause,
+ const char *queryString, ParamListInfo params,
DestReceiver *dest, char *completionTag);
extern void DeallocateQuery(DeallocateStmt *stmt);
-extern void ExplainExecuteQuery(ExecuteStmt *execstmt, ExplainState *es,
+extern void ExplainExecuteQuery(ExecuteStmt *execstmt, IntoClause *into,
+ ExplainState *es,
const char *queryString, ParamListInfo params);
/* Low-level access to stored prepared statements */
@@ -52,6 +53,6 @@ extern void DropPreparedStatement(const char *stmt_name, bool showError);
extern TupleDesc FetchPreparedStatementResultDesc(PreparedStatement *stmt);
extern List *FetchPreparedStatementTargetList(PreparedStatement *stmt);
-void DropAllPreparedStatements(void);
+extern void DropAllPreparedStatements(void);
#endif /* PREPARE_H */
diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h
index 7f276695712..f5503a56634 100644
--- a/src/include/executor/executor.h
+++ b/src/include/executor/executor.h
@@ -30,8 +30,8 @@
*
* EXPLAIN_ONLY indicates that the plan tree is being initialized just so
* EXPLAIN can print it out; it will not be run. Hence, no side-effects
- * of startup should occur (such as creating a SELECT INTO target table).
- * However, error checks (such as permission checks) should be performed.
+ * of startup should occur. However, error checks (such as permission checks)
+ * should be performed.
*
* REWIND indicates that the plan node should try to efficiently support
* rescans without parameter changes. (Nodes must support ExecReScan calls
@@ -49,12 +49,18 @@
* AfterTriggerBeginQuery/AfterTriggerEndQuery. This does not necessarily
* mean that the plan can't queue any AFTER triggers; just that the caller
* is responsible for there being a trigger context for them to be queued in.
+ *
+ * WITH/WITHOUT_OIDS tell the executor to emit tuples with or without space
+ * for OIDs, respectively. These are currently used only for CREATE TABLE AS.
+ * If neither is set, the plan may or may not produce tuples including OIDs.
*/
#define EXEC_FLAG_EXPLAIN_ONLY 0x0001 /* EXPLAIN, no ANALYZE */
#define EXEC_FLAG_REWIND 0x0002 /* need efficient rescan */
#define EXEC_FLAG_BACKWARD 0x0004 /* need backward scan */
#define EXEC_FLAG_MARK 0x0008 /* need mark/restore */
#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 */
/*
@@ -204,7 +210,6 @@ extern void EvalPlanQualFetchRowMarks(EPQState *epqstate);
extern TupleTableSlot *EvalPlanQualNext(EPQState *epqstate);
extern void EvalPlanQualBegin(EPQState *epqstate, EState *parentestate);
extern void EvalPlanQualEnd(EPQState *epqstate);
-extern DestReceiver *CreateIntoRelDestReceiver(void);
/*
* prototypes from functions in execProcnode.c
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 5207102f6c9..b48a03b4b25 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -371,8 +371,6 @@ typedef struct EState
int es_top_eflags; /* eflags passed to ExecutorStart */
int es_instrument; /* OR of InstrumentOption flags */
- bool es_select_into; /* true if doing SELECT INTO */
- bool es_into_oids; /* true to generate OIDs in SELECT INTO */
bool es_finished; /* true when ExecutorFinish is done */
List *es_exprcontexts; /* List of ExprContexts within EState */
diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h
index 905458fd50b..fdcc80edbb5 100644
--- a/src/include/nodes/nodes.h
+++ b/src/include/nodes/nodes.h
@@ -303,6 +303,7 @@ typedef enum NodeTag
T_DropdbStmt,
T_VacuumStmt,
T_ExplainStmt,
+ T_CreateTableAsStmt,
T_CreateSeqStmt,
T_AlterSeqStmt,
T_VariableSetStmt,
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index ab5563997d4..07a1ab75502 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -84,7 +84,7 @@ typedef uint32 AclMode; /* a bitmask of privilege bits */
/*
* Query -
- * Parse analysis turns all statements into a Query tree (via transformStmt)
+ * Parse analysis turns all statements into a Query tree
* for further processing by the rewriter and planner.
*
* Utility statements (i.e. non-optimizable statements) have the
@@ -111,8 +111,6 @@ typedef struct Query
int resultRelation; /* rtable index of target relation for
* INSERT/UPDATE/DELETE; 0 for SELECT */
- IntoClause *intoClause; /* target for SELECT INTO / CREATE TABLE AS */
-
bool hasAggs; /* has aggregates in tlist or havingQual */
bool hasWindowFuncs; /* has window functions in tlist */
bool hasSubLinks; /* has subquery SubLink */
@@ -1009,7 +1007,7 @@ typedef struct SelectStmt
*/
List *distinctClause; /* NULL, list of DISTINCT ON exprs, or
* lcons(NIL,NIL) for all (SELECT DISTINCT) */
- IntoClause *intoClause; /* target for SELECT INTO / CREATE TABLE AS */
+ IntoClause *intoClause; /* target for SELECT INTO */
List *targetList; /* the target list (of ResTarget) */
List *fromClause; /* the FROM clause */
Node *whereClause; /* WHERE qualification */
@@ -2396,6 +2394,25 @@ typedef struct ExplainStmt
} ExplainStmt;
/* ----------------------
+ * CREATE TABLE AS Statement (a/k/a SELECT INTO)
+ *
+ * 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.
+ *
+ * The "query" field is handled similarly to EXPLAIN, though note that it
+ * can be a SELECT or an EXECUTE, but not other DML statements.
+ * ----------------------
+ */
+typedef struct CreateTableAsStmt
+{
+ NodeTag type;
+ Node *query; /* the query (see comments above) */
+ IntoClause *into; /* destination table */
+ bool is_select_into; /* it was written as SELECT INTO */
+} CreateTableAsStmt;
+
+/* ----------------------
* Checkpoint Statement
* ----------------------
*/
@@ -2509,7 +2526,6 @@ typedef struct ExecuteStmt
{
NodeTag type;
char *name; /* The name of the plan to execute */
- IntoClause *into; /* Optional table to store results in */
List *params; /* Values to assign to parameters */
} ExecuteStmt;
diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h
index e6bb3239f42..c7c1a154fc4 100644
--- a/src/include/nodes/plannodes.h
+++ b/src/include/nodes/plannodes.h
@@ -54,8 +54,6 @@ typedef struct PlannedStmt
Node *utilityStmt; /* non-null if this is DECLARE CURSOR */
- IntoClause *intoClause; /* target for SELECT INTO / CREATE TABLE AS */
-
List *subplans; /* Plan trees for SubPlan expressions */
Bitmapset *rewindPlanIDs; /* indices of subplans that require REWIND */
diff --git a/src/include/parser/analyze.h b/src/include/parser/analyze.h
index b8987db214b..8367db8b8c5 100644
--- a/src/include/parser/analyze.h
+++ b/src/include/parser/analyze.h
@@ -25,6 +25,8 @@ extern Query *parse_analyze_varparams(Node *parseTree, const char *sourceText,
extern Query *parse_sub_analyze(Node *parseTree, ParseState *parentParseState,
CommonTableExpr *parentCTE,
bool locked_from_parent);
+
+extern Query *transformTopLevelStmt(ParseState *pstate, Node *parseTree);
extern Query *transformStmt(ParseState *pstate, Node *parseTree);
extern bool analyze_requires_snapshot(Node *parseTree);
diff --git a/src/include/tcop/pquery.h b/src/include/tcop/pquery.h
index 98b825a1067..22aad2e96cc 100644
--- a/src/include/tcop/pquery.h
+++ b/src/include/tcop/pquery.h
@@ -28,7 +28,7 @@ extern List *FetchPortalTargetList(Portal portal);
extern List *FetchStatementTargetList(Node *stmt);
extern void PortalStart(Portal portal, ParamListInfo params,
- bool use_active_snapshot);
+ int eflags, bool use_active_snapshot);
extern void PortalSetResultFormat(Portal portal, int nFormats,
int16 *formats);
diff --git a/src/include/tcop/utility.h b/src/include/tcop/utility.h
index 14f0fa8e9dc..54190b2f6ce 100644
--- a/src/include/tcop/utility.h
+++ b/src/include/tcop/utility.h
@@ -34,6 +34,8 @@ extern bool UtilityReturnsTuples(Node *parsetree);
extern TupleDesc UtilityTupleDescriptor(Node *parsetree);
+extern Query *UtilityContainsQuery(Node *parsetree);
+
extern const char *CreateCommandTag(Node *parsetree);
extern LogStmtLevel GetCommandLogLevel(Node *parsetree);