0001-Return-command-tag-REPLACE-X-for-CREATE-OR-REPLACE-s.patch
text/x-patch
Filename: 0001-Return-command-tag-REPLACE-X-for-CREATE-OR-REPLACE-s.patch
Type: text/x-patch
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch 0001
Subject: Return command tag 'REPLACE X' for CREATE OR REPLACE statements.
| File | + | − |
|---|---|---|
| src/backend/catalog/pg_aggregate.c | 2 | 1 |
| src/backend/catalog/pg_proc.c | 5 | 1 |
| src/backend/commands/functioncmds.c | 10 | 3 |
| src/backend/commands/proclang.c | 22 | 12 |
| src/backend/commands/view.c | 12 | 10 |
| src/backend/rewrite/rewriteDefine.c | 22 | 11 |
| src/backend/tcop/utility.c | 39 | 4 |
| src/include/catalog/pg_proc_fn.h | 2 | 1 |
| src/include/commands/defrem.h | 1 | 1 |
| src/include/commands/proclang.h | 1 | 1 |
| src/include/commands/view.h | 1 | 1 |
| src/include/rewrite/rewriteDefine.h | 2 | 2 |
From 25a19ca972e6f02ba350b6e4112935ff1ed44b24 Mon Sep 17 00:00:00 2001
From: Marti Raudsepp <marti@juffo.org>
Date: Sun, 28 Nov 2010 16:49:41 +0200
Subject: [PATCH 1/2] Return command tag 'REPLACE X' for CREATE OR REPLACE statements.
This affects CREATE OR REPLACE LANGUAGE/VIEW/RULE/FUNCTION
Related functions that previously returned "void" have been changed to
"bool" to report status up. Others have a new argument bool *didReplace.
---
src/backend/catalog/pg_aggregate.c | 3 +-
src/backend/catalog/pg_proc.c | 6 ++++-
src/backend/commands/functioncmds.c | 13 ++++++++--
src/backend/commands/proclang.c | 34 ++++++++++++++++++---------
src/backend/commands/view.c | 22 +++++++++--------
src/backend/rewrite/rewriteDefine.c | 33 ++++++++++++++++++---------
src/backend/tcop/utility.c | 43 +++++++++++++++++++++++++++++++---
src/include/catalog/pg_proc_fn.h | 3 +-
src/include/commands/defrem.h | 2 +-
src/include/commands/proclang.h | 2 +-
src/include/commands/view.h | 2 +-
src/include/rewrite/rewriteDefine.h | 4 +-
12 files changed, 119 insertions(+), 48 deletions(-)
diff --git a/src/backend/catalog/pg_aggregate.c b/src/backend/catalog/pg_aggregate.c
index 86e8c6b..95e4469 100644
--- a/src/backend/catalog/pg_aggregate.c
+++ b/src/backend/catalog/pg_aggregate.c
@@ -229,7 +229,8 @@ AggregateCreate(const char *aggName,
NIL, /* parameterDefaults */
PointerGetDatum(NULL), /* proconfig */
1, /* procost */
- 0); /* prorows */
+ 0, /* prorows */
+ NULL); /* didReplace */
/*
* Okay to create the pg_aggregate entry.
diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c
index 2ab87d2..8b15efc 100644
--- a/src/backend/catalog/pg_proc.c
+++ b/src/backend/catalog/pg_proc.c
@@ -85,7 +85,8 @@ ProcedureCreate(const char *procedureName,
List *parameterDefaults,
Datum proconfig,
float4 procost,
- float4 prorows)
+ float4 prorows,
+ bool *didReplace)
{
Oid retval;
int parameterCount;
@@ -650,6 +651,9 @@ ProcedureCreate(const char *procedureName,
AtEOXact_GUC(true, save_nestlevel);
}
+ if(didReplace)
+ *didReplace = is_update;
+
return retval;
}
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 2a2b7c7..4678d9c 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -768,8 +768,11 @@ interpret_AS_clause(Oid languageOid, const char *languageName,
/*
* CreateFunction
* Execute a CREATE FUNCTION utility statement.
+ *
+ * Returns TRUE if function was replaced via "CREATE OR REPLACE", FALSE
+ * if created.
*/
-void
+bool
CreateFunction(CreateFunctionStmt *stmt, const char *queryString)
{
char *probin_str;
@@ -791,7 +794,8 @@ CreateFunction(CreateFunctionStmt *stmt, const char *queryString)
Oid requiredResultType;
bool isWindowFunc,
isStrict,
- security;
+ security,
+ didReplace;
char volatility;
ArrayType *proconfig;
float4 procost;
@@ -958,7 +962,10 @@ CreateFunction(CreateFunctionStmt *stmt, const char *queryString)
parameterDefaults,
PointerGetDatum(proconfig),
procost,
- prorows);
+ prorows,
+ &didReplace);
+
+ return didReplace;
}
diff --git a/src/backend/commands/proclang.c b/src/backend/commands/proclang.c
index 3860105..7a1520c 100644
--- a/src/backend/commands/proclang.c
+++ b/src/backend/commands/proclang.c
@@ -49,7 +49,7 @@ typedef struct
char *tmpllibrary; /* path of shared library */
} PLTemplate;
-static void create_proc_lang(const char *languageName, bool replace,
+static bool create_proc_lang(const char *languageName, bool replace,
Oid languageOwner, Oid handlerOid, Oid inlineOid,
Oid valOid, bool trusted);
static PLTemplate *find_language_template(const char *languageName);
@@ -59,9 +59,12 @@ static void AlterLanguageOwner_internal(HeapTuple tup, Relation rel,
/* ---------------------------------------------------------------------
* CREATE PROCEDURAL LANGUAGE
+ *
+ * Returns TRUE if language was replaced via "CREATE OR REPLACE", FALSE
+ * if created.
* ---------------------------------------------------------------------
*/
-void
+bool
CreateProceduralLanguage(CreatePLangStmt *stmt)
{
char *languageName;
@@ -146,7 +149,8 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
NIL,
PointerGetDatum(NULL),
1,
- 0);
+ 0,
+ NULL);
}
/*
@@ -181,7 +185,8 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
NIL,
PointerGetDatum(NULL),
1,
- 0);
+ 0,
+ NULL);
}
}
else
@@ -219,16 +224,17 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
NIL,
PointerGetDatum(NULL),
1,
- 0);
+ 0,
+ NULL);
}
}
else
valOid = InvalidOid;
/* ok, create it */
- create_proc_lang(languageName, stmt->replace, GetUserId(),
- handlerOid, inlineOid,
- valOid, pltemplate->tmpltrusted);
+ return create_proc_lang(languageName, stmt->replace, GetUserId(),
+ handlerOid, inlineOid,
+ valOid, pltemplate->tmpltrusted);
}
else
{
@@ -301,16 +307,18 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
valOid = InvalidOid;
/* ok, create it */
- create_proc_lang(languageName, stmt->replace, GetUserId(),
- handlerOid, inlineOid,
- valOid, stmt->pltrusted);
+ return create_proc_lang(languageName, stmt->replace, GetUserId(),
+ handlerOid, inlineOid,
+ valOid, stmt->pltrusted);
}
}
/*
* Guts of language creation.
+ *
+ * Returns TRUE if function was replaced, FALSE otherwise.
*/
-static void
+static bool
create_proc_lang(const char *languageName, bool replace,
Oid languageOwner, Oid handlerOid, Oid inlineOid,
Oid valOid, bool trusted)
@@ -431,6 +439,8 @@ create_proc_lang(const char *languageName, bool replace,
LanguageRelationId, myself.objectId, 0);
heap_close(rel, RowExclusiveLock);
+
+ return is_update;
}
/*
diff --git a/src/backend/commands/view.c b/src/backend/commands/view.c
index a684172..41d4321 100644
--- a/src/backend/commands/view.c
+++ b/src/backend/commands/view.c
@@ -303,20 +303,20 @@ checkViewTupleDesc(TupleDesc newdesc, TupleDesc olddesc)
*/
}
-static void
+static bool
DefineViewRules(Oid viewOid, Query *viewParse, bool replace)
{
/*
* Set up the ON SELECT rule. Since the query has already been through
* parse analysis, we use DefineQueryRewrite() directly.
*/
- DefineQueryRewrite(pstrdup(ViewSelectRuleName),
- viewOid,
- NULL,
- CMD_SELECT,
- true,
- replace,
- list_make1(viewParse));
+ return DefineQueryRewrite(pstrdup(ViewSelectRuleName),
+ viewOid,
+ NULL,
+ CMD_SELECT,
+ true,
+ replace,
+ list_make1(viewParse));
/*
* Someday: automatic ON INSERT, etc
@@ -392,8 +392,10 @@ UpdateRangeTableOfViewParse(Oid viewOid, Query *viewParse)
/*
* DefineView
* Execute a CREATE VIEW command.
+ *
+ * Returns TRUE if view was replaced via "CREATE OR REPLACE"
*/
-void
+bool
DefineView(ViewStmt *stmt, const char *queryString)
{
Query *viewParse;
@@ -489,5 +491,5 @@ DefineView(ViewStmt *stmt, const char *queryString)
/*
* Now create the rules associated with the view.
*/
- DefineViewRules(viewOid, viewParse, stmt->replace);
+ return DefineViewRules(viewOid, viewParse, stmt->replace);
}
diff --git a/src/backend/rewrite/rewriteDefine.c b/src/backend/rewrite/rewriteDefine.c
index 99c397b..518154e 100644
--- a/src/backend/rewrite/rewriteDefine.c
+++ b/src/backend/rewrite/rewriteDefine.c
@@ -56,7 +56,8 @@ InsertRule(char *rulname,
bool evinstead,
Node *event_qual,
List *action,
- bool replace)
+ bool replace,
+ bool *didReplace)
{
char *evqual = nodeToString(event_qual);
char *actiontree = nodeToString((Node *) action);
@@ -184,14 +185,18 @@ InsertRule(char *rulname,
heap_close(pg_rewrite_desc, RowExclusiveLock);
+ *didReplace = is_update;
+
return rewriteObjectId;
}
/*
* DefineRule
* Execute a CREATE RULE command.
+ *
+ * Returns TRUE if rule was replaced via "CREATE OR REPLACE".
*/
-void
+bool
DefineRule(RuleStmt *stmt, const char *queryString)
{
List *actions;
@@ -205,13 +210,13 @@ DefineRule(RuleStmt *stmt, const char *queryString)
relId = RangeVarGetRelid(stmt->relation, false);
/* ... and execute */
- DefineQueryRewrite(stmt->rulename,
- relId,
- whereClause,
- stmt->event,
- stmt->instead,
- stmt->replace,
- actions);
+ return DefineQueryRewrite(stmt->rulename,
+ relId,
+ whereClause,
+ stmt->event,
+ stmt->instead,
+ stmt->replace,
+ actions);
}
@@ -221,8 +226,10 @@ DefineRule(RuleStmt *stmt, const char *queryString)
*
* This is essentially the same as DefineRule() except that the rule's
* action and qual have already been passed through parse analysis.
+ *
+ * Returns TRUE if rule was replaced, FALSE otherwise.
*/
-void
+bool
DefineQueryRewrite(char *rulename,
Oid event_relid,
Node *event_qual,
@@ -237,6 +244,7 @@ DefineQueryRewrite(char *rulename,
ListCell *l;
Query *query;
bool RelisBecomingView = false;
+ bool didReplace = false;
/*
* If we are installing an ON SELECT rule, we had better grab
@@ -487,7 +495,8 @@ DefineQueryRewrite(char *rulename,
is_instead,
event_qual,
action,
- replace);
+ replace,
+ &didReplace);
/*
* Set pg_class 'relhasrules' field TRUE for event relation. If
@@ -512,6 +521,8 @@ DefineQueryRewrite(char *rulename,
/* Close rel, but keep lock till commit... */
heap_close(event_relation, NoLock);
+
+ return didReplace;
}
/*
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 9500037..b1120d0 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -336,6 +336,8 @@ standard_ProcessUtility(Node *parsetree,
DestReceiver *dest,
char *completionTag)
{
+ bool didReplace;
+
check_xact_readonly(parsetree);
if (completionTag)
@@ -891,11 +893,28 @@ standard_ProcessUtility(Node *parsetree,
break;
case T_ViewStmt: /* CREATE VIEW */
- DefineView((ViewStmt *) parsetree, queryString);
+ didReplace = DefineView((ViewStmt *) parsetree, queryString);
+
+ if (completionTag)
+ {
+ if (didReplace)
+ strcpy(completionTag, "REPLACE VIEW");
+ else
+ strcpy(completionTag, "CREATE VIEW");
+ }
break;
case T_CreateFunctionStmt: /* CREATE FUNCTION */
- CreateFunction((CreateFunctionStmt *) parsetree, queryString);
+ didReplace = CreateFunction((CreateFunctionStmt *) parsetree,
+ queryString);
+
+ if (completionTag)
+ {
+ if (didReplace)
+ strcpy(completionTag, "REPLACE FUNCTION");
+ else
+ strcpy(completionTag, "CREATE FUNCTION");
+ }
break;
case T_AlterFunctionStmt: /* ALTER FUNCTION */
@@ -939,7 +958,15 @@ standard_ProcessUtility(Node *parsetree,
break;
case T_RuleStmt: /* CREATE RULE */
- DefineRule((RuleStmt *) parsetree, queryString);
+ didReplace = DefineRule((RuleStmt *) parsetree, queryString);
+
+ if (completionTag)
+ {
+ if (didReplace)
+ strcpy(completionTag, "REPLACE RULE");
+ else
+ strcpy(completionTag, "CREATE RULE");
+ }
break;
case T_CreateSeqStmt:
@@ -1110,7 +1137,15 @@ standard_ProcessUtility(Node *parsetree,
break;
case T_CreatePLangStmt:
- CreateProceduralLanguage((CreatePLangStmt *) parsetree);
+ didReplace = CreateProceduralLanguage((CreatePLangStmt *) parsetree);
+
+ if (completionTag)
+ {
+ if (didReplace)
+ strcpy(completionTag, "REPLACE LANGUAGE");
+ else
+ strcpy(completionTag, "CREATE LANGUAGE");
+ }
break;
case T_DropPLangStmt:
diff --git a/src/include/catalog/pg_proc_fn.h b/src/include/catalog/pg_proc_fn.h
index 09d779f..2e354b7 100644
--- a/src/include/catalog/pg_proc_fn.h
+++ b/src/include/catalog/pg_proc_fn.h
@@ -37,7 +37,8 @@ extern Oid ProcedureCreate(const char *procedureName,
List *parameterDefaults,
Datum proconfig,
float4 procost,
- float4 prorows);
+ float4 prorows,
+ bool *didReplace);
extern bool function_parse_error_transpose(const char *prosrc);
diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h
index a806f9e..530cc74 100644
--- a/src/include/commands/defrem.h
+++ b/src/include/commands/defrem.h
@@ -52,7 +52,7 @@ extern List *ChooseIndexColumnNames(List *indexElems);
extern Oid GetDefaultOpClass(Oid type_id, Oid am_id);
/* commands/functioncmds.c */
-extern void CreateFunction(CreateFunctionStmt *stmt, const char *queryString);
+extern bool CreateFunction(CreateFunctionStmt *stmt, const char *queryString);
extern void RemoveFunction(RemoveFuncStmt *stmt);
extern void RemoveFunctionById(Oid funcOid);
extern void SetFunctionReturnType(Oid funcOid, Oid newRetType);
diff --git a/src/include/commands/proclang.h b/src/include/commands/proclang.h
index aa1fb34..be91f3b 100644
--- a/src/include/commands/proclang.h
+++ b/src/include/commands/proclang.h
@@ -14,7 +14,7 @@
#include "nodes/parsenodes.h"
-extern void CreateProceduralLanguage(CreatePLangStmt *stmt);
+extern bool CreateProceduralLanguage(CreatePLangStmt *stmt);
extern void DropProceduralLanguage(DropPLangStmt *stmt);
extern void DropProceduralLanguageById(Oid langOid);
extern void RenameLanguage(const char *oldname, const char *newname);
diff --git a/src/include/commands/view.h b/src/include/commands/view.h
index 9751e32..f58122c 100644
--- a/src/include/commands/view.h
+++ b/src/include/commands/view.h
@@ -16,6 +16,6 @@
#include "nodes/parsenodes.h"
-extern void DefineView(ViewStmt *stmt, const char *queryString);
+extern bool DefineView(ViewStmt *stmt, const char *queryString);
#endif /* VIEW_H */
diff --git a/src/include/rewrite/rewriteDefine.h b/src/include/rewrite/rewriteDefine.h
index 4bf474b..052c002 100644
--- a/src/include/rewrite/rewriteDefine.h
+++ b/src/include/rewrite/rewriteDefine.h
@@ -22,9 +22,9 @@
#define RULE_FIRES_ON_REPLICA 'R'
#define RULE_DISABLED 'D'
-extern void DefineRule(RuleStmt *stmt, const char *queryString);
+extern bool DefineRule(RuleStmt *stmt, const char *queryString);
-extern void DefineQueryRewrite(char *rulename,
+extern bool DefineQueryRewrite(char *rulename,
Oid event_relid,
Node *event_qual,
CmdType event_type,
--
1.7.3.5