diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/catalog/pg_enum.c | 18 | ||||
-rw-r--r-- | src/backend/commands/typecmds.c | 3 | ||||
-rw-r--r-- | src/backend/nodes/copyfuncs.c | 1 | ||||
-rw-r--r-- | src/backend/nodes/equalfuncs.c | 1 | ||||
-rw-r--r-- | src/backend/parser/gram.y | 25 |
5 files changed, 37 insertions, 11 deletions
diff --git a/src/backend/catalog/pg_enum.c b/src/backend/catalog/pg_enum.c index 8ddb376bc16..f3161efb20b 100644 --- a/src/backend/catalog/pg_enum.c +++ b/src/backend/catalog/pg_enum.c @@ -179,7 +179,8 @@ void AddEnumLabel(Oid enumTypeOid, const char *newVal, const char *neighbor, - bool newValIsAfter) + bool newValIsAfter, + bool skipIfExists) { Relation pg_enum; Oid newOid; @@ -211,6 +212,21 @@ AddEnumLabel(Oid enumTypeOid, */ LockDatabaseObject(TypeRelationId, enumTypeOid, 0, ExclusiveLock); + /* Do the "IF NOT EXISTS" test if specified */ + if (skipIfExists) + { + HeapTuple tup; + + tup = SearchSysCache2(ENUMTYPOIDNAME, + ObjectIdGetDatum(enumTypeOid), + CStringGetDatum(newVal)); + if (HeapTupleIsValid(tup)) + { + ReleaseSysCache(tup); + return; + } + } + pg_enum = heap_open(EnumRelationId, RowExclusiveLock); /* If we have to renumber the existing members, we restart from here */ diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c index 4c9d00386cb..6cb6fd56fd9 100644 --- a/src/backend/commands/typecmds.c +++ b/src/backend/commands/typecmds.c @@ -1188,7 +1188,8 @@ AlterEnum(AlterEnumStmt *stmt) /* Add the new label */ AddEnumLabel(enum_type_oid, stmt->newVal, - stmt->newValNeighbor, stmt->newValIsAfter); + stmt->newValNeighbor, stmt->newValIsAfter, + stmt->skipIfExists); ReleaseSysCache(tup); } diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index f34f7049e43..34d4f40fe23 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -3055,6 +3055,7 @@ _copyAlterEnumStmt(const AlterEnumStmt *from) COPY_STRING_FIELD(newVal); COPY_STRING_FIELD(newValNeighbor); COPY_SCALAR_FIELD(newValIsAfter); + COPY_SCALAR_FIELD(skipIfExists); return newnode; } diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index b4b1c223363..f63f4973db5 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -1439,6 +1439,7 @@ _equalAlterEnumStmt(const AlterEnumStmt *a, const AlterEnumStmt *b) COMPARE_STRING_FIELD(newVal); COMPARE_STRING_FIELD(newValNeighbor); COMPARE_SCALAR_FIELD(newValIsAfter); + COMPARE_SCALAR_FIELD(skipIfExists); return true; } diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 5894cb0885c..ec88b710769 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -470,7 +470,7 @@ static void processCASbits(int cas_bits, int location, const char *constrType, %type <windef> window_definition over_clause window_specification opt_frame_clause frame_extent frame_bound %type <str> opt_existing_window_name - +%type <boolean> opt_if_not_exists /* * Non-keyword token types. These are hard-wired into the "flex" lexer. @@ -4618,35 +4618,42 @@ enum_val_list: Sconst *****************************************************************************/ AlterEnumStmt: - ALTER TYPE_P any_name ADD_P VALUE_P Sconst + ALTER TYPE_P any_name ADD_P VALUE_P opt_if_not_exists Sconst { AlterEnumStmt *n = makeNode(AlterEnumStmt); n->typeName = $3; - n->newVal = $6; + n->newVal = $7; n->newValNeighbor = NULL; n->newValIsAfter = true; + n->skipIfExists = $6; $$ = (Node *) n; } - | ALTER TYPE_P any_name ADD_P VALUE_P Sconst BEFORE Sconst + | ALTER TYPE_P any_name ADD_P VALUE_P opt_if_not_exists Sconst BEFORE Sconst { AlterEnumStmt *n = makeNode(AlterEnumStmt); n->typeName = $3; - n->newVal = $6; - n->newValNeighbor = $8; + n->newVal = $7; + n->newValNeighbor = $9; n->newValIsAfter = false; + n->skipIfExists = $6; $$ = (Node *) n; } - | ALTER TYPE_P any_name ADD_P VALUE_P Sconst AFTER Sconst + | ALTER TYPE_P any_name ADD_P VALUE_P opt_if_not_exists Sconst AFTER Sconst { AlterEnumStmt *n = makeNode(AlterEnumStmt); n->typeName = $3; - n->newVal = $6; - n->newValNeighbor = $8; + n->newVal = $7; + n->newValNeighbor = $9; n->newValIsAfter = true; + n->skipIfExists = $6; $$ = (Node *) n; } ; +opt_if_not_exists: IF_P NOT EXISTS { $$ = true; } + | /* empty */ { $$ = false; } + ; + /***************************************************************************** * |