mirror of https://github.com/postgres/postgres
Fix EXPLAIN and EXECUTE commands to pass portal parameters through to
the executor. This allows, for example, JDBC clients to use '?' bound parameters in these commands. Per gripe from Virag Saksena.
This commit is contained in:
parent
4ab76b1c20
commit
9a39423436
|
@ -7,7 +7,7 @@
|
|||
* Portions Copyright (c) 1994-5, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/commands/explain.c,v 1.141 2005/11/26 22:14:56 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/commands/explain.c,v 1.142 2005/11/29 01:25:49 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -45,7 +45,7 @@ typedef struct ExplainState
|
|||
} ExplainState;
|
||||
|
||||
static void ExplainOneQuery(Query *query, ExplainStmt *stmt,
|
||||
TupOutputState *tstate);
|
||||
ParamListInfo params, TupOutputState *tstate);
|
||||
static double elapsed_time(instr_time *starttime);
|
||||
static void explain_outNode(StringInfo str,
|
||||
Plan *plan, PlanState *planstate,
|
||||
|
@ -67,7 +67,7 @@ static void show_sort_keys(List *tlist, int nkeys, AttrNumber *keycols,
|
|||
* execute an EXPLAIN command
|
||||
*/
|
||||
void
|
||||
ExplainQuery(ExplainStmt *stmt, DestReceiver *dest)
|
||||
ExplainQuery(ExplainStmt *stmt, ParamListInfo params, DestReceiver *dest)
|
||||
{
|
||||
Query *query = stmt->query;
|
||||
TupOutputState *tstate;
|
||||
|
@ -91,9 +91,9 @@ ExplainQuery(ExplainStmt *stmt, DestReceiver *dest)
|
|||
{
|
||||
/* Rewriter will not cope with utility statements */
|
||||
if (query->utilityStmt && IsA(query->utilityStmt, DeclareCursorStmt))
|
||||
ExplainOneQuery(query, stmt, tstate);
|
||||
ExplainOneQuery(query, stmt, params, tstate);
|
||||
else if (query->utilityStmt && IsA(query->utilityStmt, ExecuteStmt))
|
||||
ExplainExecuteQuery(stmt, tstate);
|
||||
ExplainExecuteQuery(stmt, params, tstate);
|
||||
else
|
||||
do_text_output_oneline(tstate, "Utility statements have no plan structure");
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ ExplainQuery(ExplainStmt *stmt, DestReceiver *dest)
|
|||
/* Explain every plan */
|
||||
foreach(l, rewritten)
|
||||
{
|
||||
ExplainOneQuery(lfirst(l), stmt, tstate);
|
||||
ExplainOneQuery(lfirst(l), stmt, params, tstate);
|
||||
/* put a blank line between plans */
|
||||
if (lnext(l) != NULL)
|
||||
do_text_output_oneline(tstate, "");
|
||||
|
@ -150,7 +150,8 @@ ExplainResultDesc(ExplainStmt *stmt)
|
|||
* print out the execution plan for one query
|
||||
*/
|
||||
static void
|
||||
ExplainOneQuery(Query *query, ExplainStmt *stmt, TupOutputState *tstate)
|
||||
ExplainOneQuery(Query *query, ExplainStmt *stmt, ParamListInfo params,
|
||||
TupOutputState *tstate)
|
||||
{
|
||||
Plan *plan;
|
||||
QueryDesc *queryDesc;
|
||||
|
@ -208,7 +209,7 @@ ExplainOneQuery(Query *query, ExplainStmt *stmt, TupOutputState *tstate)
|
|||
/* Create a QueryDesc requesting no output */
|
||||
queryDesc = CreateQueryDesc(query, plan,
|
||||
ActiveSnapshot, InvalidSnapshot,
|
||||
None_Receiver, NULL,
|
||||
None_Receiver, params,
|
||||
stmt->analyze);
|
||||
|
||||
ExplainOnePlan(queryDesc, stmt, tstate);
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
* Copyright (c) 2002-2005, PostgreSQL Global Development Group
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/commands/prepare.c,v 1.42 2005/10/21 16:43:33 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/commands/prepare.c,v 1.43 2005/11/29 01:25:49 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -121,7 +121,8 @@ PrepareQuery(PrepareStmt *stmt)
|
|||
* Implements the 'EXECUTE' utility statement.
|
||||
*/
|
||||
void
|
||||
ExecuteQuery(ExecuteStmt *stmt, DestReceiver *dest, char *completionTag)
|
||||
ExecuteQuery(ExecuteStmt *stmt, ParamListInfo params,
|
||||
DestReceiver *dest, char *completionTag)
|
||||
{
|
||||
PreparedStatement *entry;
|
||||
char *query_string;
|
||||
|
@ -150,6 +151,7 @@ ExecuteQuery(ExecuteStmt *stmt, DestReceiver *dest, char *completionTag)
|
|||
* of query, in case parameters are pass-by-reference.
|
||||
*/
|
||||
estate = CreateExecutorState();
|
||||
estate->es_param_list_info = params;
|
||||
paramLI = EvaluateParams(estate, stmt->params, entry->argtype_list);
|
||||
}
|
||||
|
||||
|
@ -538,7 +540,8 @@ DropPreparedStatement(const char *stmt_name, bool showError)
|
|||
* Implements the 'EXPLAIN EXECUTE' utility statement.
|
||||
*/
|
||||
void
|
||||
ExplainExecuteQuery(ExplainStmt *stmt, TupOutputState *tstate)
|
||||
ExplainExecuteQuery(ExplainStmt *stmt, ParamListInfo params,
|
||||
TupOutputState *tstate)
|
||||
{
|
||||
ExecuteStmt *execstmt = (ExecuteStmt *) stmt->query->utilityStmt;
|
||||
PreparedStatement *entry;
|
||||
|
@ -568,6 +571,7 @@ ExplainExecuteQuery(ExplainStmt *stmt, TupOutputState *tstate)
|
|||
* of query, in case parameters are pass-by-reference.
|
||||
*/
|
||||
estate = CreateExecutorState();
|
||||
estate->es_param_list_info = params;
|
||||
paramLI = EvaluateParams(estate, execstmt->params,
|
||||
entry->argtype_list);
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.249 2005/11/22 18:17:22 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.250 2005/11/29 01:25:49 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -365,7 +365,7 @@ check_xact_readonly(Node *parsetree)
|
|||
* general utility function invoker
|
||||
*
|
||||
* parsetree: the parse tree for the utility statement
|
||||
* params: parameters to use during execution (currently only used by DECLARE)
|
||||
* params: parameters to use during execution
|
||||
* dest: where to send results
|
||||
* completionTag: points to a buffer of size COMPLETION_TAG_BUFSIZE
|
||||
* in which to store a command completion status string.
|
||||
|
@ -648,7 +648,8 @@ ProcessUtility(Node *parsetree,
|
|||
break;
|
||||
|
||||
case T_ExecuteStmt:
|
||||
ExecuteQuery((ExecuteStmt *) parsetree, dest, completionTag);
|
||||
ExecuteQuery((ExecuteStmt *) parsetree, params,
|
||||
dest, completionTag);
|
||||
break;
|
||||
|
||||
case T_DeallocateStmt:
|
||||
|
@ -891,7 +892,7 @@ ProcessUtility(Node *parsetree,
|
|||
break;
|
||||
|
||||
case T_ExplainStmt:
|
||||
ExplainQuery((ExplainStmt *) parsetree, dest);
|
||||
ExplainQuery((ExplainStmt *) parsetree, params, dest);
|
||||
break;
|
||||
|
||||
case T_VariableSetStmt:
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994-5, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/commands/explain.h,v 1.24 2004/12/31 22:03:28 pgsql Exp $
|
||||
* $PostgreSQL: pgsql/src/include/commands/explain.h,v 1.25 2005/11/29 01:25:50 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -18,7 +18,8 @@
|
|||
#include "tcop/dest.h"
|
||||
|
||||
|
||||
extern void ExplainQuery(ExplainStmt *stmt, DestReceiver *dest);
|
||||
extern void ExplainQuery(ExplainStmt *stmt, ParamListInfo params,
|
||||
DestReceiver *dest);
|
||||
|
||||
extern TupleDesc ExplainResultDesc(ExplainStmt *stmt);
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*
|
||||
* Copyright (c) 2002-2005, PostgreSQL Global Development Group
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/commands/prepare.h,v 1.14 2005/06/22 17:45:46 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/include/commands/prepare.h,v 1.15 2005/11/29 01:25:50 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -42,10 +42,11 @@ typedef struct
|
|||
|
||||
/* Utility statements PREPARE, EXECUTE, DEALLOCATE, EXPLAIN EXECUTE */
|
||||
extern void PrepareQuery(PrepareStmt *stmt);
|
||||
extern void ExecuteQuery(ExecuteStmt *stmt, DestReceiver *dest,
|
||||
char *completionTag);
|
||||
extern void ExecuteQuery(ExecuteStmt *stmt, ParamListInfo params,
|
||||
DestReceiver *dest, char *completionTag);
|
||||
extern void DeallocateQuery(DeallocateStmt *stmt);
|
||||
extern void ExplainExecuteQuery(ExplainStmt *stmt, TupOutputState *tstate);
|
||||
extern void ExplainExecuteQuery(ExplainStmt *stmt, ParamListInfo params,
|
||||
TupOutputState *tstate);
|
||||
|
||||
/* Low-level access to stored prepared statements */
|
||||
extern void StorePreparedStatement(const char *stmt_name,
|
||||
|
|
Loading…
Reference in New Issue