Yury Zhuravlev wrote:
Please. Patch in attachment.You already have a patch? If yes I'm glad to review it.
Fix bug, forgot change attr number in parser. And, I forgot example:
PREPARE usrrptplan (int) IF NOT EXISTS AS SELECT * FROM pg_operator; PREPARE New patch in attachment. -- Yury Zhuravlev Postgres Professional: http://www.postgrespro.com The Russian Postgres Company
diff --git a/src/backend/commands/prepare.c b/src/backend/commands/prepare.c index cec37ce..63d164f 100644 --- a/src/backend/commands/prepare.c +++ b/src/backend/commands/prepare.c @@ -59,6 +59,7 @@ PrepareQuery(PrepareStmt *stmt, const char *queryString) int nargs; Query *query; List *query_list; + bool found; int i; /* @@ -70,6 +71,24 @@ PrepareQuery(PrepareStmt *stmt, const char *queryString) (errcode(ERRCODE_INVALID_PSTATEMENT_DEFINITION), errmsg("invalid statement name: must not be empty"))); + /* Find entry in hash table */ + if(prepared_queries) + { + hash_search(prepared_queries, + stmt->name, + HASH_FIND, + &found); + + /* Shouldn't get a duplicate entry */ + if (found && stmt->if_not_exists) + return; + else if (found && !stmt->if_not_exists) + ereport(ERROR, + (errcode(ERRCODE_DUPLICATE_PSTATEMENT), + errmsg("prepared statement \"%s\" already exists", + stmt->name))); + } + /* * Create the CachedPlanSource before we do parse analysis, since it needs * to see the unmodified raw parse tree. diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index df7c2fa..be8ac78 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -4021,6 +4021,7 @@ _copyPrepareStmt(const PrepareStmt *from) COPY_STRING_FIELD(name); COPY_NODE_FIELD(argtypes); COPY_NODE_FIELD(query); + COPY_SCALAR_FIELD(if_not_exists); return newnode; } diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index b9c3959..fbd248b 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -2017,6 +2017,7 @@ _equalPrepareStmt(const PrepareStmt *a, const PrepareStmt *b) COMPARE_STRING_FIELD(name); COMPARE_NODE_FIELD(argtypes); COMPARE_NODE_FIELD(query); + COMPARE_SCALAR_FIELD(if_not_exists); return true; } diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index b9aeb31..6eb69e3 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -9443,6 +9443,16 @@ PrepareStmt: PREPARE name prep_type_clause AS PreparableStmt n->name = $2; n->argtypes = $3; n->query = $5; + n->if_not_exists = false; + $$ = (Node *) n; + } + | PREPARE name prep_type_clause IF_P NOT EXISTS AS PreparableStmt + { + PrepareStmt *n = makeNode(PrepareStmt); + n->name = $2; + n->argtypes = $3; + n->query = $8; + n->if_not_exists = true; $$ = (Node *) n; } ; diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 2fd0629..f08dee4 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -2986,6 +2986,7 @@ typedef struct PrepareStmt char *name; /* Name of plan, arbitrary */ List *argtypes; /* Types of parameters (List of TypeName) */ Node *query; /* The query itself (as a raw parsetree) */ + bool if_not_exists; } PrepareStmt;
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers