mirror of https://github.com/citusdata/citus.git
Deparse CALL statement instead of using original query string
parent
90e1f1442a
commit
ca478defeb
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
#include "catalog/pg_proc.h"
|
#include "catalog/pg_proc.h"
|
||||||
#include "commands/defrem.h"
|
#include "commands/defrem.h"
|
||||||
|
#include "distributed/citus_ruleutils.h"
|
||||||
#include "distributed/colocation_utils.h"
|
#include "distributed/colocation_utils.h"
|
||||||
#include "distributed/commands.h"
|
#include "distributed/commands.h"
|
||||||
#include "distributed/commands/multi_copy.h"
|
#include "distributed/commands/multi_copy.h"
|
||||||
|
@ -38,15 +39,13 @@
|
||||||
|
|
||||||
static bool CallFuncExprRemotely(CallStmt *callStmt,
|
static bool CallFuncExprRemotely(CallStmt *callStmt,
|
||||||
DistObjectCacheEntry *procedure,
|
DistObjectCacheEntry *procedure,
|
||||||
FuncExpr *funcExpr, const char *queryString,
|
FuncExpr *funcExpr, DestReceiver *dest);
|
||||||
DestReceiver *dest);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CallDistributedProcedureRemotely calls a stored procedure on the worker if possible.
|
* CallDistributedProcedureRemotely calls a stored procedure on the worker if possible.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
CallDistributedProcedureRemotely(CallStmt *callStmt, const char *queryString,
|
CallDistributedProcedureRemotely(CallStmt *callStmt, DestReceiver *dest)
|
||||||
DestReceiver *dest)
|
|
||||||
{
|
{
|
||||||
DistObjectCacheEntry *procedure = NULL;
|
DistObjectCacheEntry *procedure = NULL;
|
||||||
FuncExpr *funcExpr = callStmt->funcexpr;
|
FuncExpr *funcExpr = callStmt->funcexpr;
|
||||||
|
@ -58,7 +57,7 @@ CallDistributedProcedureRemotely(CallStmt *callStmt, const char *queryString,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return CallFuncExprRemotely(callStmt, procedure, funcExpr, queryString, dest);
|
return CallFuncExprRemotely(callStmt, procedure, funcExpr, dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -67,7 +66,7 @@ CallDistributedProcedureRemotely(CallStmt *callStmt, const char *queryString,
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
CallFuncExprRemotely(CallStmt *callStmt, DistObjectCacheEntry *procedure,
|
CallFuncExprRemotely(CallStmt *callStmt, DistObjectCacheEntry *procedure,
|
||||||
FuncExpr *funcExpr, const char *queryString, DestReceiver *dest)
|
FuncExpr *funcExpr, DestReceiver *dest)
|
||||||
{
|
{
|
||||||
Oid colocatedRelationId = InvalidOid;
|
Oid colocatedRelationId = InvalidOid;
|
||||||
Const *partitionValue = NULL;
|
Const *partitionValue = NULL;
|
||||||
|
@ -78,6 +77,7 @@ CallFuncExprRemotely(CallStmt *callStmt, DistObjectCacheEntry *procedure,
|
||||||
Var *partitionColumn = NULL;
|
Var *partitionColumn = NULL;
|
||||||
ShardPlacement *placement = NULL;
|
ShardPlacement *placement = NULL;
|
||||||
WorkerNode *workerNode = NULL;
|
WorkerNode *workerNode = NULL;
|
||||||
|
StringInfo callCommand = NULL;
|
||||||
|
|
||||||
if (IsMultiStatementTransaction())
|
if (IsMultiStatementTransaction())
|
||||||
{
|
{
|
||||||
|
@ -160,6 +160,10 @@ CallFuncExprRemotely(CallStmt *callStmt, DistObjectCacheEntry *procedure,
|
||||||
|
|
||||||
ereport(DEBUG1, (errmsg("pushing down the procedure")));
|
ereport(DEBUG1, (errmsg("pushing down the procedure")));
|
||||||
|
|
||||||
|
/* build remote command with fully qualified names */
|
||||||
|
callCommand = makeStringInfo();
|
||||||
|
appendStringInfo(callCommand, "CALL %s", pg_get_rule_expr((Node *) funcExpr));
|
||||||
|
|
||||||
{
|
{
|
||||||
Tuplestorestate *tupleStore = tuplestore_begin_heap(true, false, work_mem);
|
Tuplestorestate *tupleStore = tuplestore_begin_heap(true, false, work_mem);
|
||||||
TupleDesc tupleDesc = CallStmtResultDesc(callStmt);
|
TupleDesc tupleDesc = CallStmtResultDesc(callStmt);
|
||||||
|
@ -170,7 +174,7 @@ CallFuncExprRemotely(CallStmt *callStmt, DistObjectCacheEntry *procedure,
|
||||||
task->jobId = INVALID_JOB_ID;
|
task->jobId = INVALID_JOB_ID;
|
||||||
task->taskId = 0;
|
task->taskId = 0;
|
||||||
task->taskType = DDL_TASK;
|
task->taskType = DDL_TASK;
|
||||||
task->queryString = pstrdup(queryString);
|
task->queryString = callCommand->data;
|
||||||
task->replicationModel = REPLICATION_MODEL_INVALID;
|
task->replicationModel = REPLICATION_MODEL_INVALID;
|
||||||
task->dependedTaskList = NIL;
|
task->dependedTaskList = NIL;
|
||||||
task->anchorShardId = placement->shardId;
|
task->anchorShardId = placement->shardId;
|
||||||
|
|
|
@ -209,7 +209,7 @@ multi_ProcessUtility(PlannedStmt *pstmt,
|
||||||
* the worker this can avoid making many network round trips.
|
* the worker this can avoid making many network round trips.
|
||||||
*/
|
*/
|
||||||
if (context == PROCESS_UTILITY_TOPLEVEL &&
|
if (context == PROCESS_UTILITY_TOPLEVEL &&
|
||||||
CallDistributedProcedureRemotely(callStmt, queryString, dest))
|
CallDistributedProcedureRemotely(callStmt, dest))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -451,6 +451,48 @@ pg_get_query_def(Query *query, StringInfo buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* pg_get_rule_expr deparses an expression and returns the result as a string.
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
pg_get_rule_expr(Node *expression)
|
||||||
|
{
|
||||||
|
bool showImplicitCasts = true;
|
||||||
|
deparse_context context;
|
||||||
|
OverrideSearchPath *overridePath = NULL;
|
||||||
|
StringInfo buffer = makeStringInfo();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set search_path to NIL so that all objects outside of pg_catalog will be
|
||||||
|
* schema-prefixed. pg_catalog will be added automatically when we call
|
||||||
|
* PushOverrideSearchPath(), since we set addCatalog to true;
|
||||||
|
*/
|
||||||
|
overridePath = GetOverrideSearchPath(CurrentMemoryContext);
|
||||||
|
overridePath->schemas = NIL;
|
||||||
|
overridePath->addCatalog = true;
|
||||||
|
PushOverrideSearchPath(overridePath);
|
||||||
|
|
||||||
|
context.buf = buffer;
|
||||||
|
context.namespaces = NIL;
|
||||||
|
context.windowClause = NIL;
|
||||||
|
context.windowTList = NIL;
|
||||||
|
context.varprefix = false;
|
||||||
|
context.prettyFlags = 0;
|
||||||
|
context.wrapColumn = WRAP_COLUMN_DEFAULT;
|
||||||
|
context.indentLevel = 0;
|
||||||
|
context.special_exprkind = EXPR_KIND_NONE;
|
||||||
|
context.distrelid = InvalidOid;
|
||||||
|
context.shardid = INVALID_SHARD_ID;
|
||||||
|
|
||||||
|
get_rule_expr(expression, &context, showImplicitCasts);
|
||||||
|
|
||||||
|
/* revert back to original search_path */
|
||||||
|
PopOverrideSearchPath();
|
||||||
|
|
||||||
|
return buffer->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* set_rtable_names: select RTE aliases to be used in printing a query
|
* set_rtable_names: select RTE aliases to be used in printing a query
|
||||||
*
|
*
|
||||||
|
|
|
@ -451,6 +451,48 @@ pg_get_query_def(Query *query, StringInfo buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* pg_get_rule_expr deparses an expression and returns the result as a string.
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
pg_get_rule_expr(Node *expression)
|
||||||
|
{
|
||||||
|
bool showImplicitCasts = true;
|
||||||
|
deparse_context context;
|
||||||
|
OverrideSearchPath *overridePath = NULL;
|
||||||
|
StringInfo buffer = makeStringInfo();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set search_path to NIL so that all objects outside of pg_catalog will be
|
||||||
|
* schema-prefixed. pg_catalog will be added automatically when we call
|
||||||
|
* PushOverrideSearchPath(), since we set addCatalog to true;
|
||||||
|
*/
|
||||||
|
overridePath = GetOverrideSearchPath(CurrentMemoryContext);
|
||||||
|
overridePath->schemas = NIL;
|
||||||
|
overridePath->addCatalog = true;
|
||||||
|
PushOverrideSearchPath(overridePath);
|
||||||
|
|
||||||
|
context.buf = buffer;
|
||||||
|
context.namespaces = NIL;
|
||||||
|
context.windowClause = NIL;
|
||||||
|
context.windowTList = NIL;
|
||||||
|
context.varprefix = false;
|
||||||
|
context.prettyFlags = 0;
|
||||||
|
context.wrapColumn = WRAP_COLUMN_DEFAULT;
|
||||||
|
context.indentLevel = 0;
|
||||||
|
context.special_exprkind = EXPR_KIND_NONE;
|
||||||
|
context.distrelid = InvalidOid;
|
||||||
|
context.shardid = INVALID_SHARD_ID;
|
||||||
|
|
||||||
|
get_rule_expr(expression, &context, showImplicitCasts);
|
||||||
|
|
||||||
|
/* revert back to original search_path */
|
||||||
|
PopOverrideSearchPath();
|
||||||
|
|
||||||
|
return buffer->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* set_rtable_names: select RTE aliases to be used in printing a query
|
* set_rtable_names: select RTE aliases to be used in printing a query
|
||||||
*
|
*
|
||||||
|
|
|
@ -452,6 +452,48 @@ pg_get_query_def(Query *query, StringInfo buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* pg_get_rule_expr deparses an expression and returns the result as a string.
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
pg_get_rule_expr(Node *expression)
|
||||||
|
{
|
||||||
|
bool showImplicitCasts = true;
|
||||||
|
deparse_context context;
|
||||||
|
OverrideSearchPath *overridePath = NULL;
|
||||||
|
StringInfo buffer = makeStringInfo();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set search_path to NIL so that all objects outside of pg_catalog will be
|
||||||
|
* schema-prefixed. pg_catalog will be added automatically when we call
|
||||||
|
* PushOverrideSearchPath(), since we set addCatalog to true;
|
||||||
|
*/
|
||||||
|
overridePath = GetOverrideSearchPath(CurrentMemoryContext);
|
||||||
|
overridePath->schemas = NIL;
|
||||||
|
overridePath->addCatalog = true;
|
||||||
|
PushOverrideSearchPath(overridePath);
|
||||||
|
|
||||||
|
context.buf = buffer;
|
||||||
|
context.namespaces = NIL;
|
||||||
|
context.windowClause = NIL;
|
||||||
|
context.windowTList = NIL;
|
||||||
|
context.varprefix = false;
|
||||||
|
context.prettyFlags = 0;
|
||||||
|
context.wrapColumn = WRAP_COLUMN_DEFAULT;
|
||||||
|
context.indentLevel = 0;
|
||||||
|
context.special_exprkind = EXPR_KIND_NONE;
|
||||||
|
context.distrelid = InvalidOid;
|
||||||
|
context.shardid = INVALID_SHARD_ID;
|
||||||
|
|
||||||
|
get_rule_expr(expression, &context, showImplicitCasts);
|
||||||
|
|
||||||
|
/* revert back to original search_path */
|
||||||
|
PopOverrideSearchPath();
|
||||||
|
|
||||||
|
return buffer->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* set_rtable_names: select RTE aliases to be used in printing a query
|
* set_rtable_names: select RTE aliases to be used in printing a query
|
||||||
*
|
*
|
||||||
|
|
|
@ -43,6 +43,7 @@ extern const char * RoleSpecString(RoleSpec *spec);
|
||||||
|
|
||||||
/* Function declarations for version dependent PostgreSQL ruleutils functions */
|
/* Function declarations for version dependent PostgreSQL ruleutils functions */
|
||||||
extern void pg_get_query_def(Query *query, StringInfo buffer);
|
extern void pg_get_query_def(Query *query, StringInfo buffer);
|
||||||
|
char * pg_get_rule_expr(Node *expression);
|
||||||
extern void deparse_shard_query(Query *query, Oid distrelid, int64 shardid,
|
extern void deparse_shard_query(Query *query, Oid distrelid, int64 shardid,
|
||||||
StringInfo buffer);
|
StringInfo buffer);
|
||||||
extern char * generate_relation_name(Oid relid, List *namespaces);
|
extern char * generate_relation_name(Oid relid, List *namespaces);
|
||||||
|
|
|
@ -26,8 +26,7 @@ extern List * PlanClusterStmt(ClusterStmt *clusterStmt, const char *clusterComma
|
||||||
#if PG_VERSION_NUM >= 110000
|
#if PG_VERSION_NUM >= 110000
|
||||||
|
|
||||||
/* call.c */
|
/* call.c */
|
||||||
extern bool CallDistributedProcedureRemotely(CallStmt *callStmt, const char *callCommand,
|
extern bool CallDistributedProcedureRemotely(CallStmt *callStmt, DestReceiver *dest);
|
||||||
DestReceiver *dest);
|
|
||||||
#endif /* PG_VERSION_NUM >= 110000 */
|
#endif /* PG_VERSION_NUM >= 110000 */
|
||||||
|
|
||||||
/* extension.c - forward declarations */
|
/* extension.c - forward declarations */
|
||||||
|
|
Loading…
Reference in New Issue