diff options
Diffstat (limited to 'src/include')
| -rw-r--r-- | src/include/catalog/catversion.h | 2 | ||||
| -rw-r--r-- | src/include/commands/copy.h | 3 | ||||
| -rw-r--r-- | src/include/commands/explain.h | 1 | ||||
| -rw-r--r-- | src/include/commands/portalcmds.h | 2 | ||||
| -rw-r--r-- | src/include/commands/prepare.h | 3 | ||||
| -rw-r--r-- | src/include/commands/schemacmds.h | 3 | ||||
| -rw-r--r-- | src/include/commands/view.h | 3 | ||||
| -rw-r--r-- | src/include/executor/execdesc.h | 9 | ||||
| -rw-r--r-- | src/include/nodes/nodes.h | 1 | ||||
| -rw-r--r-- | src/include/nodes/parsenodes.h | 65 | ||||
| -rw-r--r-- | src/include/nodes/plannodes.h | 15 | ||||
| -rw-r--r-- | src/include/parser/analyze.h | 8 | ||||
| -rw-r--r-- | src/include/tcop/tcopprot.h | 5 | ||||
| -rw-r--r-- | src/include/tcop/utility.h | 8 | ||||
| -rw-r--r-- | src/include/utils/plancache.h | 12 | ||||
| -rw-r--r-- | src/include/utils/portal.h | 5 |
16 files changed, 95 insertions, 50 deletions
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 95cfd53eeca..29604b6f4ed 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 201612231 +#define CATALOG_VERSION_NO 201701141 #endif diff --git a/src/include/commands/copy.h b/src/include/commands/copy.h index 4785631cef9..d63ca0f5e99 100644 --- a/src/include/commands/copy.h +++ b/src/include/commands/copy.h @@ -22,7 +22,8 @@ /* CopyStateData is private in commands/copy.c */ typedef struct CopyStateData *CopyState; -extern Oid DoCopy(ParseState *state, const CopyStmt *stmt, +extern void DoCopy(ParseState *state, const CopyStmt *stmt, + int stmt_location, int stmt_len, uint64 *processed); extern void ProcessCopyOptions(ParseState *pstate, CopyState cstate, bool is_from, List *options); diff --git a/src/include/commands/explain.h b/src/include/commands/explain.h index 1820dd66bb2..9191e186c15 100644 --- a/src/include/commands/explain.h +++ b/src/include/commands/explain.h @@ -49,6 +49,7 @@ typedef struct ExplainState /* Hook for plugins to get control in ExplainOneQuery() */ typedef void (*ExplainOneQuery_hook_type) (Query *query, + int cursorOptions, IntoClause *into, ExplainState *es, const char *queryString, diff --git a/src/include/commands/portalcmds.h b/src/include/commands/portalcmds.h index 0ae9b7213cd..8f0e6c48f49 100644 --- a/src/include/commands/portalcmds.h +++ b/src/include/commands/portalcmds.h @@ -18,7 +18,7 @@ #include "utils/portal.h" -extern void PerformCursorOpen(PlannedStmt *stmt, ParamListInfo params, +extern void PerformCursorOpen(DeclareCursorStmt *cstmt, ParamListInfo params, const char *queryString, bool isTopLevel); extern void PerformPortalFetch(FetchStmt *stmt, DestReceiver *dest, diff --git a/src/include/commands/prepare.h b/src/include/commands/prepare.h index 0a3a8addca1..d8d22edbbcd 100644 --- a/src/include/commands/prepare.h +++ b/src/include/commands/prepare.h @@ -35,7 +35,8 @@ typedef struct /* Utility statements PREPARE, EXECUTE, DEALLOCATE, EXPLAIN EXECUTE */ -extern void PrepareQuery(PrepareStmt *stmt, const char *queryString); +extern void PrepareQuery(PrepareStmt *stmt, const char *queryString, + int stmt_location, int stmt_len); extern void ExecuteQuery(ExecuteStmt *stmt, IntoClause *intoClause, const char *queryString, ParamListInfo params, DestReceiver *dest, char *completionTag); diff --git a/src/include/commands/schemacmds.h b/src/include/commands/schemacmds.h index 087878ddc33..f07a389c7f6 100644 --- a/src/include/commands/schemacmds.h +++ b/src/include/commands/schemacmds.h @@ -19,7 +19,8 @@ #include "nodes/parsenodes.h" extern Oid CreateSchemaCommand(CreateSchemaStmt *parsetree, - const char *queryString); + const char *queryString, + int stmt_location, int stmt_len); extern void RemoveSchemaById(Oid schemaOid); diff --git a/src/include/commands/view.h b/src/include/commands/view.h index 648665ebe5d..39763913c80 100644 --- a/src/include/commands/view.h +++ b/src/include/commands/view.h @@ -19,7 +19,8 @@ extern void validateWithCheckOption(char *value); -extern ObjectAddress DefineView(ViewStmt *stmt, const char *queryString); +extern ObjectAddress DefineView(ViewStmt *stmt, const char *queryString, + int stmt_location, int stmt_len); extern void StoreViewQuery(Oid viewOid, Query *viewParse, bool replace); diff --git a/src/include/executor/execdesc.h b/src/include/executor/execdesc.h index 2c221255dcb..c99ea818158 100644 --- a/src/include/executor/execdesc.h +++ b/src/include/executor/execdesc.h @@ -34,8 +34,7 @@ typedef struct QueryDesc { /* These fields are provided by CreateQueryDesc */ CmdType operation; /* CMD_SELECT, CMD_UPDATE, etc. */ - PlannedStmt *plannedstmt; /* planner's output, or null if utility */ - Node *utilitystmt; /* utility statement, or null */ + PlannedStmt *plannedstmt; /* planner's output (could be utility, too) */ const char *sourceText; /* source text of the query */ Snapshot snapshot; /* snapshot to use for query */ Snapshot crosscheck_snapshot; /* crosscheck for RI update/delete */ @@ -61,12 +60,6 @@ extern QueryDesc *CreateQueryDesc(PlannedStmt *plannedstmt, ParamListInfo params, int instrument_options); -extern QueryDesc *CreateUtilityQueryDesc(Node *utilitystmt, - const char *sourceText, - Snapshot snapshot, - DestReceiver *dest, - ParamListInfo params); - extern void FreeQueryDesc(QueryDesc *qdesc); #endif /* EXECDESC_H */ diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h index a1bb0ac5cb8..4c4319bcabf 100644 --- a/src/include/nodes/nodes.h +++ b/src/include/nodes/nodes.h @@ -301,6 +301,7 @@ typedef enum NodeTag /* * TAGS FOR STATEMENT NODES (mostly in parsenodes.h) */ + T_RawStmt, T_Query, T_PlannedStmt, T_InsertStmt, diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 7ceaa22c33b..edb5cd21521 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -7,7 +7,9 @@ * This is a byte (not character) offset in the original source text, to be * used for positioning an error cursor when there is an error related to * the node. Access to the original source text is needed to make use of - * the location. + * the location. At the topmost (statement) level, we also provide a + * statement length, likewise measured in bytes, for convenience in + * identifying statement boundaries in multi-statement source strings. * * * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group @@ -89,9 +91,7 @@ typedef uint32 AclMode; /* a bitmask of privilege bits */ * for further processing by the rewriter and planner. * * Utility statements (i.e. non-optimizable statements) have the - * utilityStmt field set, and the Query itself is mostly dummy. - * DECLARE CURSOR is a special case: it is represented like a SELECT, - * but the original DeclareCursorStmt is stored in utilityStmt. + * utilityStmt field set, and the rest of the Query is mostly dummy. * * Planning converts a Query tree into a Plan tree headed by a PlannedStmt * node --- the Query structure is not used by the executor. @@ -108,8 +108,7 @@ typedef struct Query bool canSetTag; /* do I set the command result tag? */ - Node *utilityStmt; /* non-null if this is DECLARE CURSOR or a - * non-optimizable statement */ + Node *utilityStmt; /* non-null if commandType == CMD_UTILITY */ int resultRelation; /* rtable index of target relation for * INSERT/UPDATE/DELETE; 0 for SELECT */ @@ -162,6 +161,15 @@ typedef struct Query * are only added during rewrite and * therefore are not written out as * part of Query. */ + + /* + * The following two fields identify the portion of the source text string + * containing this query. They are typically only populated in top-level + * Queries, not in sub-queries. When not set, they might both be zero, or + * both be -1 meaning "unknown". + */ + int stmt_location; /* start location, or -1 if unknown */ + int stmt_len; /* length in bytes; 0 means "rest of string" */ } Query; @@ -1308,6 +1316,30 @@ typedef struct TriggerTransition } TriggerTransition; /***************************************************************************** + * Raw Grammar Output Statements + *****************************************************************************/ + +/* + * RawStmt --- container for any one statement's raw parse tree + * + * Parse analysis converts a raw parse tree headed by a RawStmt node into + * an analyzed statement headed by a Query node. For optimizable statements, + * the conversion is complex. For utility statements, the parser usually just + * transfers the raw parse tree (sans RawStmt) into the utilityStmt field of + * the Query node, and all the useful work happens at execution time. + * + * stmt_location/stmt_len identify the portion of the source text string + * containing this raw statement (useful for multi-statement strings). + */ +typedef struct RawStmt +{ + NodeTag type; + Node *stmt; /* raw parse tree */ + int stmt_location; /* start location, or -1 if unknown */ + int stmt_len; /* length in bytes; 0 means "rest of string" */ +} RawStmt; + +/***************************************************************************** * Optimizable Statements *****************************************************************************/ @@ -1474,6 +1506,9 @@ typedef struct SetOperationStmt * statements do need attention from parse analysis, and this is * done by routines in parser/parse_utilcmd.c after ProcessUtility * receives the command for execution. + * DECLARE CURSOR, EXPLAIN, and CREATE TABLE AS are special cases: + * they contain optimizable statements, which get processed normally + * by parser/analyze.c. *****************************************************************************/ /* @@ -1794,7 +1829,7 @@ typedef struct CopyStmt NodeTag type; RangeVar *relation; /* the relation to copy */ Node *query; /* the query (SELECT or DML statement with - * RETURNING) to copy */ + * RETURNING) to copy, as a raw parse tree */ List *attlist; /* List of column names (as Strings), or NIL * for all columns */ bool is_from; /* TO or FROM */ @@ -2472,9 +2507,9 @@ typedef struct SecLabelStmt /* ---------------------- * Declare Cursor Statement * - * Note: the "query" field of DeclareCursorStmt is only used in the raw grammar - * output. After parse analysis it's set to null, and the Query points to the - * DeclareCursorStmt, not vice versa. + * The "query" field is initially a raw parse tree, and is converted to a + * Query node during parse analysis. Note that rewriting and planning + * of the query are always postponed until execution. * ---------------------- */ #define CURSOR_OPT_BINARY 0x0001 /* BINARY */ @@ -2493,7 +2528,7 @@ typedef struct DeclareCursorStmt NodeTag type; char *portalname; /* name of the portal (cursor) */ int options; /* bitmask of options (see above) */ - Node *query; /* the raw SELECT query */ + Node *query; /* the query (see comments above) */ } DeclareCursorStmt; /* ---------------------- @@ -2841,7 +2876,7 @@ typedef struct ViewStmt NodeTag type; RangeVar *view; /* the view to be created */ List *aliases; /* target column names */ - Node *query; /* the SELECT query */ + Node *query; /* the SELECT query (as a raw parse tree) */ bool replace; /* replace an existing view? */ List *options; /* options from WITH clause */ ViewCheckOption withCheckOption; /* WITH CHECK OPTION */ @@ -2950,9 +2985,9 @@ typedef struct VacuumStmt /* ---------------------- * Explain Statement * - * The "query" field is either a raw parse tree (SelectStmt, InsertStmt, etc) - * or a Query node if parse analysis has been done. Note that rewriting and - * planning of the query are always postponed until execution of EXPLAIN. + * The "query" field is initially a raw parse tree, and is converted to a + * Query node during parse analysis. Note that rewriting and planning + * of the query are always postponed until execution. * ---------------------- */ typedef struct ExplainStmt diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h index 692a62698ed..6810f8c0993 100644 --- a/src/include/nodes/plannodes.h +++ b/src/include/nodes/plannodes.h @@ -31,13 +31,18 @@ * * The output of the planner is a Plan tree headed by a PlannedStmt node. * PlannedStmt holds the "one time" information needed by the executor. + * + * For simplicity in APIs, we also wrap utility statements in PlannedStmt + * nodes; in such cases, commandType == CMD_UTILITY, the statement itself + * is in the utilityStmt field, and the rest of the struct is mostly dummy. + * (We do use canSetTag, stmt_location, stmt_len, and possibly queryId.) * ---------------- */ typedef struct PlannedStmt { NodeTag type; - CmdType commandType; /* select|insert|update|delete */ + CmdType commandType; /* select|insert|update|delete|utility */ uint32 queryId; /* query identifier (copied from Query) */ @@ -60,8 +65,6 @@ typedef struct PlannedStmt /* rtable indexes of target relations for INSERT/UPDATE/DELETE */ List *resultRelations; /* integer list of RT indexes, or NIL */ - Node *utilityStmt; /* non-null if this is DECLARE CURSOR */ - List *subplans; /* Plan trees for SubPlan expressions */ Bitmapset *rewindPlanIDs; /* indices of subplans that require REWIND */ @@ -73,6 +76,12 @@ typedef struct PlannedStmt List *invalItems; /* other dependencies, as PlanInvalItems */ int nParamExec; /* number of PARAM_EXEC Params used */ + + Node *utilityStmt; /* non-null if this is utility stmt */ + + /* statement location in source string (copied from Query) */ + int stmt_location; /* start location, or -1 if unknown */ + int stmt_len; /* length in bytes; 0 means "rest of string" */ } PlannedStmt; /* macro for fetching the Plan associated with a SubPlan node */ diff --git a/src/include/parser/analyze.h b/src/include/parser/analyze.h index 3bf4edd0bf2..a7e5c55ab4f 100644 --- a/src/include/parser/analyze.h +++ b/src/include/parser/analyze.h @@ -22,19 +22,19 @@ typedef void (*post_parse_analyze_hook_type) (ParseState *pstate, extern PGDLLIMPORT post_parse_analyze_hook_type post_parse_analyze_hook; -extern Query *parse_analyze(Node *parseTree, const char *sourceText, +extern Query *parse_analyze(RawStmt *parseTree, const char *sourceText, Oid *paramTypes, int numParams); -extern Query *parse_analyze_varparams(Node *parseTree, const char *sourceText, +extern Query *parse_analyze_varparams(RawStmt *parseTree, const char *sourceText, Oid **paramTypes, int *numParams); extern Query *parse_sub_analyze(Node *parseTree, ParseState *parentParseState, CommonTableExpr *parentCTE, bool locked_from_parent); -extern Query *transformTopLevelStmt(ParseState *pstate, Node *parseTree); +extern Query *transformTopLevelStmt(ParseState *pstate, RawStmt *parseTree); extern Query *transformStmt(ParseState *pstate, Node *parseTree); -extern bool analyze_requires_snapshot(Node *parseTree); +extern bool analyze_requires_snapshot(RawStmt *parseTree); extern const char *LCS_asString(LockClauseStrength strength); extern void CheckSelectLocking(Query *qry, LockClauseStrength strength); diff --git a/src/include/tcop/tcopprot.h b/src/include/tcop/tcopprot.h index 54da6b65efb..1958be85b72 100644 --- a/src/include/tcop/tcopprot.h +++ b/src/include/tcop/tcopprot.h @@ -47,9 +47,10 @@ typedef enum extern int log_statement; extern List *pg_parse_query(const char *query_string); -extern List *pg_analyze_and_rewrite(Node *parsetree, const char *query_string, +extern List *pg_analyze_and_rewrite(RawStmt *parsetree, + const char *query_string, Oid *paramTypes, int numParams); -extern List *pg_analyze_and_rewrite_params(Node *parsetree, +extern List *pg_analyze_and_rewrite_params(RawStmt *parsetree, const char *query_string, ParserSetupHook parserSetup, void *parserSetupArg); diff --git a/src/include/tcop/utility.h b/src/include/tcop/utility.h index 42c52a1c757..4f8d3539001 100644 --- a/src/include/tcop/utility.h +++ b/src/include/tcop/utility.h @@ -24,16 +24,16 @@ typedef enum } ProcessUtilityContext; /* Hook for plugins to get control in ProcessUtility() */ -typedef void (*ProcessUtility_hook_type) (Node *parsetree, +typedef void (*ProcessUtility_hook_type) (PlannedStmt *pstmt, const char *queryString, ProcessUtilityContext context, ParamListInfo params, DestReceiver *dest, char *completionTag); extern PGDLLIMPORT ProcessUtility_hook_type ProcessUtility_hook; -extern void ProcessUtility(Node *parsetree, const char *queryString, +extern void ProcessUtility(PlannedStmt *pstmt, const char *queryString, ProcessUtilityContext context, ParamListInfo params, DestReceiver *dest, char *completionTag); -extern void standard_ProcessUtility(Node *parsetree, const char *queryString, +extern void standard_ProcessUtility(PlannedStmt *pstmt, const char *queryString, ProcessUtilityContext context, ParamListInfo params, DestReceiver *dest, char *completionTag); @@ -47,6 +47,6 @@ extern const char *CreateCommandTag(Node *parsetree); extern LogStmtLevel GetCommandLogLevel(Node *parsetree); -extern bool CommandIsReadOnly(Node *parsetree); +extern bool CommandIsReadOnly(PlannedStmt *pstmt); #endif /* UTILITY_H */ diff --git a/src/include/utils/plancache.h b/src/include/utils/plancache.h index 9ee0bc6e9f1..84952d56e70 100644 --- a/src/include/utils/plancache.h +++ b/src/include/utils/plancache.h @@ -18,6 +18,9 @@ #include "access/tupdesc.h" #include "nodes/params.h" +/* Forward declaration, to avoid including parsenodes.h here */ +struct RawStmt; + #define CACHEDPLANSOURCE_MAGIC 195726186 #define CACHEDPLAN_MAGIC 953717834 @@ -76,7 +79,7 @@ typedef struct CachedPlanSource { int magic; /* should equal CACHEDPLANSOURCE_MAGIC */ - Node *raw_parse_tree; /* output of raw_parser(), or NULL */ + struct RawStmt *raw_parse_tree; /* output of raw_parser(), or NULL */ const char *query_string; /* source text of query */ const char *commandTag; /* command tag (a constant!), or NULL */ Oid *param_types; /* array of parameter type OIDs, or NULL */ @@ -126,8 +129,7 @@ typedef struct CachedPlanSource typedef struct CachedPlan { int magic; /* should equal CACHEDPLAN_MAGIC */ - List *stmt_list; /* list of statement nodes (PlannedStmts and - * bare utility statements) */ + List *stmt_list; /* list of PlannedStmts */ bool is_oneshot; /* is it a "oneshot" plan? */ bool is_saved; /* is CachedPlan in a long-lived context? */ bool is_valid; /* is the stmt_list currently valid? */ @@ -144,10 +146,10 @@ typedef struct CachedPlan extern void InitPlanCache(void); extern void ResetPlanCache(void); -extern CachedPlanSource *CreateCachedPlan(Node *raw_parse_tree, +extern CachedPlanSource *CreateCachedPlan(struct RawStmt *raw_parse_tree, const char *query_string, const char *commandTag); -extern CachedPlanSource *CreateOneShotCachedPlan(Node *raw_parse_tree, +extern CachedPlanSource *CreateOneShotCachedPlan(struct RawStmt *raw_parse_tree, const char *query_string, const char *commandTag); extern void CompleteCachedPlan(CachedPlanSource *plansource, diff --git a/src/include/utils/portal.h b/src/include/utils/portal.h index 8359416b15e..dc76acd0a42 100644 --- a/src/include/utils/portal.h +++ b/src/include/utils/portal.h @@ -133,7 +133,7 @@ typedef struct PortalData /* The query or queries the portal will execute */ const char *sourceText; /* text of query (as of 8.4, never NULL) */ const char *commandTag; /* command tag for original query */ - List *stmts; /* PlannedStmts and/or utility statements */ + List *stmts; /* list of PlannedStmts */ CachedPlan *cplan; /* CachedPlan, if stmts are from one */ ParamListInfo portalParams; /* params to pass to query */ @@ -201,7 +201,6 @@ typedef struct PortalData */ #define PortalGetQueryDesc(portal) ((portal)->queryDesc) #define PortalGetHeapMemory(portal) ((portal)->heap) -#define PortalGetPrimaryStmt(portal) PortalListGetPrimaryStmt((portal)->stmts) /* Prototypes for functions in utils/mmgr/portalmem.c */ @@ -232,7 +231,7 @@ extern void PortalDefineQuery(Portal portal, const char *commandTag, List *stmts, CachedPlan *cplan); -extern Node *PortalListGetPrimaryStmt(List *stmts); +extern PlannedStmt *PortalGetPrimaryStmt(Portal portal); extern void PortalCreateHoldStore(Portal portal); extern void PortalHashTableDeleteAll(void); extern bool ThereAreNoReadyPortals(void); |
