Skip to content

Commit 25751f5

Browse files
committed
Add pg_analyze_and_rewrite_varparams()
This new function extracts common code from PrepareQuery() and exec_parse_message(). It is then exactly analogous to the existing pg_analyze_and_rewrite_fixedparams() and pg_analyze_and_rewrite_withcb(). To unify these two code paths, this makes PrepareQuery() now subject to log_parser_stats. Also, both paths now invoke TRACE_POSTGRESQL_QUERY_REWRITE_START(). PrepareQuery() no longer checks whether a utility statement was specified. The grammar doesn't allow that anyway, and exec_parse_message() supports it, so restricting it doesn't seem necessary. This also adds QueryEnvironment support to the *varparams functions, for consistency with its cousins, even though it is not used right now. Reviewed-by: Nathan Bossart <bossartn@amazon.com> Discussion: https://www.postgresql.org/message-id/flat/c67ce276-52b4-0239-dc0e-39875bf81840@enterprisedb.com
1 parent 5e0e99a commit 25751f5

File tree

5 files changed

+78
-72
lines changed

5 files changed

+78
-72
lines changed

src/backend/commands/prepare.c

Lines changed: 4 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,7 @@ PrepareQuery(ParseState *pstate, PrepareStmt *stmt,
6363
CachedPlanSource *plansource;
6464
Oid *argtypes = NULL;
6565
int nargs;
66-
Query *query;
6766
List *query_list;
68-
int i;
6967

7068
/*
7169
* Disallow empty-string statement name (conflicts with protocol-level
@@ -97,6 +95,7 @@ PrepareQuery(ParseState *pstate, PrepareStmt *stmt,
9795

9896
if (nargs)
9997
{
98+
int i;
10099
ListCell *l;
101100

102101
argtypes = (Oid *) palloc(nargs * sizeof(Oid));
@@ -115,44 +114,10 @@ PrepareQuery(ParseState *pstate, PrepareStmt *stmt,
115114
* Analyze the statement using these parameter types (any parameters
116115
* passed in from above us will not be visible to it), allowing
117116
* information about unknown parameters to be deduced from context.
117+
* Rewrite the query. The result could be 0, 1, or many queries.
118118
*/
119-
query = parse_analyze_varparams(rawstmt, pstate->p_sourcetext,
120-
&argtypes, &nargs);
121-
122-
/*
123-
* Check that all parameter types were determined.
124-
*/
125-
for (i = 0; i < nargs; i++)
126-
{
127-
Oid argtype = argtypes[i];
128-
129-
if (argtype == InvalidOid || argtype == UNKNOWNOID)
130-
ereport(ERROR,
131-
(errcode(ERRCODE_INDETERMINATE_DATATYPE),
132-
errmsg("could not determine data type of parameter $%d",
133-
i + 1)));
134-
}
135-
136-
/*
137-
* grammar only allows PreparableStmt, so this check should be redundant
138-
*/
139-
switch (query->commandType)
140-
{
141-
case CMD_SELECT:
142-
case CMD_INSERT:
143-
case CMD_UPDATE:
144-
case CMD_DELETE:
145-
/* OK */
146-
break;
147-
default:
148-
ereport(ERROR,
149-
(errcode(ERRCODE_INVALID_PSTATEMENT_DEFINITION),
150-
errmsg("utility statements cannot be prepared")));
151-
break;
152-
}
153-
154-
/* Rewrite the query. The result could be 0, 1, or many queries. */
155-
query_list = QueryRewrite(query);
119+
query_list = pg_analyze_and_rewrite_varparams(rawstmt, pstate->p_sourcetext,
120+
&argtypes, &nargs, NULL);
156121

157122
/* Finish filling in the CachedPlanSource */
158123
CompleteCachedPlan(plansource,

src/backend/parser/analyze.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,8 @@ parse_analyze_fixedparams(RawStmt *parseTree, const char *sourceText,
148148
*/
149149
Query *
150150
parse_analyze_varparams(RawStmt *parseTree, const char *sourceText,
151-
Oid **paramTypes, int *numParams)
151+
Oid **paramTypes, int *numParams,
152+
QueryEnvironment *queryEnv)
152153
{
153154
ParseState *pstate = make_parsestate(NULL);
154155
Query *query;
@@ -160,6 +161,8 @@ parse_analyze_varparams(RawStmt *parseTree, const char *sourceText,
160161

161162
setup_parse_variable_parameters(pstate, paramTypes, numParams);
162163

164+
pstate->p_queryEnv = queryEnv;
165+
163166
query = transformTopLevelStmt(pstate, parseTree);
164167

165168
/* make sure all is well with parameter types */

src/backend/tcop/postgres.c

Lines changed: 64 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -637,9 +637,11 @@ pg_parse_query(const char *query_string)
637637
* NOTE: for reasons mentioned above, this must be separate from raw parsing.
638638
*/
639639
List *
640-
pg_analyze_and_rewrite_fixedparams(RawStmt *parsetree, const char *query_string,
641-
const Oid *paramTypes, int numParams,
642-
QueryEnvironment *queryEnv)
640+
pg_analyze_and_rewrite_fixedparams(RawStmt *parsetree,
641+
const char *query_string,
642+
const Oid *paramTypes,
643+
int numParams,
644+
QueryEnvironment *queryEnv)
643645
{
644646
Query *query;
645647
List *querytree_list;
@@ -668,6 +670,59 @@ pg_analyze_and_rewrite_fixedparams(RawStmt *parsetree, const char *query_string,
668670
return querytree_list;
669671
}
670672

673+
/*
674+
* Do parse analysis and rewriting. This is the same as
675+
* pg_analyze_and_rewrite_fixedparams except that it's okay to deduce
676+
* information about $n symbol datatypes from context.
677+
*/
678+
List *
679+
pg_analyze_and_rewrite_varparams(RawStmt *parsetree,
680+
const char *query_string,
681+
Oid **paramTypes,
682+
int *numParams,
683+
QueryEnvironment *queryEnv)
684+
{
685+
Query *query;
686+
List *querytree_list;
687+
688+
TRACE_POSTGRESQL_QUERY_REWRITE_START(query_string);
689+
690+
/*
691+
* (1) Perform parse analysis.
692+
*/
693+
if (log_parser_stats)
694+
ResetUsage();
695+
696+
query = parse_analyze_varparams(parsetree, query_string, paramTypes, numParams,
697+
queryEnv);
698+
699+
/*
700+
* Check all parameter types got determined.
701+
*/
702+
for (int i = 0; i < *numParams; i++)
703+
{
704+
Oid ptype = (*paramTypes)[i];
705+
706+
if (ptype == InvalidOid || ptype == UNKNOWNOID)
707+
ereport(ERROR,
708+
(errcode(ERRCODE_INDETERMINATE_DATATYPE),
709+
errmsg("could not determine data type of parameter $%d",
710+
i + 1)));
711+
}
712+
713+
if (log_parser_stats)
714+
ShowUsage("PARSE ANALYSIS STATISTICS");
715+
716+
/*
717+
* (2) Rewrite the queries, as necessary
718+
*/
719+
querytree_list = pg_rewrite_query(query);
720+
721+
TRACE_POSTGRESQL_QUERY_REWRITE_DONE(query_string);
722+
723+
return querytree_list;
724+
}
725+
671726
/*
672727
* Do parse analysis and rewriting. This is the same as
673728
* pg_analyze_and_rewrite_fixedparams except that, instead of a fixed list of
@@ -1409,7 +1464,6 @@ exec_parse_message(const char *query_string, /* string to execute */
14091464

14101465
if (parsetree_list != NIL)
14111466
{
1412-
Query *query;
14131467
bool snapshot_set = false;
14141468

14151469
raw_parse_tree = linitial_node(RawStmt, parsetree_list);
@@ -1449,34 +1503,13 @@ exec_parse_message(const char *query_string, /* string to execute */
14491503
/*
14501504
* Analyze and rewrite the query. Note that the originally specified
14511505
* parameter set is not required to be complete, so we have to use
1452-
* parse_analyze_varparams().
1453-
*/
1454-
if (log_parser_stats)
1455-
ResetUsage();
1456-
1457-
query = parse_analyze_varparams(raw_parse_tree,
1458-
query_string,
1459-
&paramTypes,
1460-
&numParams);
1461-
1462-
/*
1463-
* Check all parameter types got determined.
1506+
* pg_analyze_and_rewrite_varparams().
14641507
*/
1465-
for (int i = 0; i < numParams; i++)
1466-
{
1467-
Oid ptype = paramTypes[i];
1468-
1469-
if (ptype == InvalidOid || ptype == UNKNOWNOID)
1470-
ereport(ERROR,
1471-
(errcode(ERRCODE_INDETERMINATE_DATATYPE),
1472-
errmsg("could not determine data type of parameter $%d",
1473-
i + 1)));
1474-
}
1475-
1476-
if (log_parser_stats)
1477-
ShowUsage("PARSE ANALYSIS STATISTICS");
1478-
1479-
querytree_list = pg_rewrite_query(query);
1508+
querytree_list = pg_analyze_and_rewrite_varparams(raw_parse_tree,
1509+
query_string,
1510+
&paramTypes,
1511+
&numParams,
1512+
NULL);
14801513

14811514
/* Done with the snapshot used for parsing */
14821515
if (snapshot_set)

src/include/parser/analyze.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ extern PGDLLIMPORT post_parse_analyze_hook_type post_parse_analyze_hook;
2727
extern Query *parse_analyze_fixedparams(RawStmt *parseTree, const char *sourceText,
2828
const Oid *paramTypes, int numParams, QueryEnvironment *queryEnv);
2929
extern Query *parse_analyze_varparams(RawStmt *parseTree, const char *sourceText,
30-
Oid **paramTypes, int *numParams);
30+
Oid **paramTypes, int *numParams, QueryEnvironment *queryEnv);
3131

3232
extern Query *parse_sub_analyze(Node *parseTree, ParseState *parentParseState,
3333
CommonTableExpr *parentCTE,

src/include/tcop/tcopprot.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ extern List *pg_analyze_and_rewrite_fixedparams(RawStmt *parsetree,
4949
const char *query_string,
5050
const Oid *paramTypes, int numParams,
5151
QueryEnvironment *queryEnv);
52+
extern List *pg_analyze_and_rewrite_varparams(RawStmt *parsetree,
53+
const char *query_string,
54+
Oid **paramTypes,
55+
int *numParams,
56+
QueryEnvironment *queryEnv);
5257
extern List *pg_analyze_and_rewrite_withcb(RawStmt *parsetree,
5358
const char *query_string,
5459
ParserSetupHook parserSetup,

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy