添加create if not exists语法

This commit is contained in:
he-shaoyu
2023-08-29 16:04:29 +08:00
parent 4d1cfb2d2a
commit ee14277d76
10 changed files with 72 additions and 4 deletions

View File

@ -16,7 +16,7 @@
<refsynopsisdiv>
<synopsis>
CREATE [ LARGE ] SEQUENCE <replaceable class="parameter">name</replaceable> [ INCREMENT [ BY ] <replaceable class="parameter">increment</replaceable> ]
CREATE [ LARGE ] SEQUENCE [ IF NOT EXISTS ] <replaceable class="parameter">name</replaceable> [ INCREMENT [ BY ] <replaceable class="parameter">increment</replaceable> ]
[ MINVALUE <replaceable class="parameter">minvalue</replaceable> | NO MINVALUE | NOMINVALUE] [ MAXVALUE <replaceable class="parameter">maxvalue</replaceable> | NO MAXVALUE | NOMAXVALUE]
[ START [ WITH ] <replaceable class="parameter">start</replaceable> ] [ CACHE <replaceable class="parameter">cache</replaceable> ] [ [ NO ] CYCLE | NOCYCLE]
[ OWNED BY { <replaceable class="parameter">table_name</replaceable>.<replaceable class="parameter">column_name</replaceable> | NONE } ];

View File

@ -5901,6 +5901,7 @@ static CreateSeqStmt* _copyCreateSeqStmt(const CreateSeqStmt* from)
COPY_SCALAR_FIELD(uuid);
COPY_SCALAR_FIELD(canCreateTempSeq);
COPY_SCALAR_FIELD(is_large);
COPY_SCALAR_FIELD(missing_ok);
return newnode;
}

View File

@ -1893,6 +1893,7 @@ static bool _equalCreateSeqStmt(const CreateSeqStmt* a, const CreateSeqStmt* b)
COMPARE_SCALAR_FIELD(uuid);
COMPARE_SCALAR_FIELD(canCreateTempSeq);
COMPARE_SCALAR_FIELD(is_large);
COMPARE_SCALAR_FIELD(missing_ok);
return true;
}

View File

@ -9861,6 +9861,34 @@ CreateSeqStmt:
n->sequence = $5;
n->options = $6;
n->missing_ok = false;
n->ownerId = InvalidOid;
/* PGXC_BEGIN */
n->is_serial = false;
/* PGXC_END */
n->uuid = 0;
n->canCreateTempSeq = false;
$$ = (Node *)n;
}
| CREATE OptTemp opt_large_seq SEQUENCE IF_P NOT EXISTS qualified_name OptSeqOptList
{
CreateSeqStmt *n = makeNode(CreateSeqStmt);
$8->relpersistence = $2;
n->is_large = $3;
#ifdef ENABLE_MULTIPLE_NODES
if (n->is_large) {
const char* message = "large sequence is not supported.";
InsertErrorMessage(message, u_sess->plsql_cxt.plpgsql_yylloc);
ereport(ERROR,
(errmodule(MOD_PARSER),
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("large sequence is not supported.")));
}
#endif
n->sequence = $8;
n->options = $9;
n->missing_ok = true;
n->ownerId = InvalidOid;
/* PGXC_BEGIN */
n->is_serial = false;

View File

@ -821,6 +821,18 @@ static ObjectAddress DefineSequence(CreateSeqStmt* seq)
bool isUseLocalSeq = false;
Oid namespaceOid = InvalidOid;
ObjectAddress address;
Oid existing_relid = InvalidOid;
Oid namespaceId = InvalidOid;
char rel_kind = large ? RELKIND_LARGE_SEQUENCE : RELKIND_SEQUENCE;
if (seq->missing_ok) {
namespaceId = RangeVarGetAndCheckCreationNamespace(seq->sequence, NoLock, &existing_relid, rel_kind);
if (existing_relid != InvalidOid) {
char* namespace_of_existing_rel = get_namespace_name(namespaceId);
ereport(NOTICE, (errmodule(MOD_COMMAND), errmsg("relation \"%s\" already exists in schema \"%s\", skipping", seq->sequence->relname, namespace_of_existing_rel)));
return InvalidObjectAddress;
}
}
#ifdef PGXC /* PGXC_COORD */
GTM_Sequence start_value = 1;
@ -996,7 +1008,6 @@ static ObjectAddress DefineSequence(CreateSeqStmt* seq)
stmt->tablespacename = NULL;
stmt->if_not_exists = false;
stmt->charset = PG_INVALID_ENCODING;
char rel_kind = large ? RELKIND_LARGE_SEQUENCE : RELKIND_SEQUENCE;
address = DefineRelation(stmt, rel_kind, seq->ownerId, NULL);
seqoid = address.objectId;
Assert(seqoid != InvalidOid);

View File

@ -1131,6 +1131,7 @@ typedef struct CreateSeqStmt {
int64 uuid; /* UUID of the sequence, mark unique sequence globally */
bool canCreateTempSeq; /* create sequence when "create table (like )" */
bool is_large;
bool missing_ok; /* skip error if a Sequence is exists */
} CreateSeqStmt;
typedef struct AlterSeqStmt {

View File

@ -0,0 +1,14 @@
create schema create_sequence_if_not_exists;
set current_schema = create_sequence_if_not_exists;
create sequence seq start with 1;
create sequence seq start with 1;
ERROR: relation "seq" already exists in schema "create_sequence_if_not_exists"
DETAIL: creating new table with existing name in the same schema
create sequence if not exists seq start with 1;
NOTICE: relation "seq" already exists in schema "create_sequence_if_not_exists", skipping
drop sequence seq;
create sequence if not exists seq start with 1;
create sequence if not exists seq start with 2;
NOTICE: relation "seq" already exists in schema "create_sequence_if_not_exists", skipping
drop sequence seq;
drop schema create_sequence_if_not_exists;

View File

@ -639,7 +639,7 @@ test: copy_new_gram copy_gbk_test copy_gb18030_test
# Another group of parallel tests
# ----------
test: create_function_3 vacuum
test: drop_if_exists drop_database test_if_not_exists test_create_index_if_not_exists
test: drop_if_exists drop_database test_if_not_exists test_create_index_if_not_exists test_create_sequence_if_not_exists
#test: constraints
#test: errors subplan_base

View File

@ -436,7 +436,7 @@ test: stable_function_shippable
# Another group of parallel tests
# ----------
test: create_function_3 vacuum
test: drop_if_exists drop_database test_if_not_exists test_create_index_if_not_exists
test: drop_if_exists drop_database test_if_not_exists test_create_index_if_not_exists test_create_sequence_if_not_exists
#test: constraints
#test: errors subplan_base

View File

@ -0,0 +1,12 @@
create schema create_sequence_if_not_exists;
set current_schema = create_sequence_if_not_exists;
create sequence seq start with 1;
create sequence seq start with 1;
create sequence if not exists seq start with 1;
drop sequence seq;
create sequence if not exists seq start with 1;
create sequence if not exists seq start with 2;
drop sequence seq;
drop schema create_sequence_if_not_exists;