!1970 CREATE DATABASE等三种语法兼容IF NOT EXISTS
Merge pull request !1970 from li_jianqiu/if_not_exists
This commit is contained in:
@ -10,7 +10,7 @@
|
||||
</refnamediv>
|
||||
<refsynopsisdiv>
|
||||
<synopsis>
|
||||
ALTER USER user_name [ [ WITH ] option [ ... ] ];
|
||||
ALTER USER [ IF EXISTS ] user_name [ [ WITH ] option [ ... ] ];
|
||||
ALTER USER user_name
|
||||
RENAME TO new_name;
|
||||
ALTER USER user_name [ IN DATABASE database_name ]
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
</refnamediv>
|
||||
<refsynopsisdiv>
|
||||
<synopsis>
|
||||
CREATE DATABASE database_name
|
||||
CREATE DATABASE [ IF NOT EXISTS ] database_name
|
||||
[ [ WITH ] {[ OWNER [=] user_name ]|
|
||||
[ TEMPLATE [=] template ]|
|
||||
[ ENCODING [=] encoding ]|
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
</refnamediv>
|
||||
<refsynopsisdiv>
|
||||
<synopsis>
|
||||
CREATE SCHEMA schema_name
|
||||
CREATE SCHEMA [ IF NOT EXISTS ] schema_name
|
||||
[ AUTHORIZATION user_name ] [WITH BLOCKCHAIN] [ schema_element [ ... ] ];
|
||||
</synopsis>
|
||||
</refsynopsisdiv>
|
||||
|
||||
@ -5460,6 +5460,7 @@ static CreatedbStmt* _copyCreatedbStmt(const CreatedbStmt* from)
|
||||
CreatedbStmt* newnode = makeNode(CreatedbStmt);
|
||||
|
||||
COPY_STRING_FIELD(dbname);
|
||||
COPY_SCALAR_FIELD(missing_ok);
|
||||
COPY_NODE_FIELD(options);
|
||||
|
||||
return newnode;
|
||||
@ -6039,6 +6040,7 @@ static AlterRoleStmt* _copyAlterRoleStmt(const AlterRoleStmt* from)
|
||||
AlterRoleStmt* newnode = makeNode(AlterRoleStmt);
|
||||
|
||||
COPY_STRING_FIELD(role);
|
||||
COPY_SCALAR_FIELD(missing_ok);
|
||||
COPY_NODE_FIELD(options);
|
||||
COPY_SCALAR_FIELD(action);
|
||||
COPY_SCALAR_FIELD(lockstatus);
|
||||
@ -6113,6 +6115,7 @@ static CreateSchemaStmt* _copyCreateSchemaStmt(const CreateSchemaStmt* from)
|
||||
CreateSchemaStmt* newnode = makeNode(CreateSchemaStmt);
|
||||
|
||||
COPY_STRING_FIELD(schemaname);
|
||||
COPY_SCALAR_FIELD(missing_ok);
|
||||
COPY_STRING_FIELD(authid);
|
||||
COPY_SCALAR_FIELD(hasBlockChain);
|
||||
COPY_NODE_FIELD(schemaElts);
|
||||
|
||||
@ -1662,6 +1662,7 @@ static bool _equalAlterOpFamilyStmt(const AlterOpFamilyStmt* a, const AlterOpFam
|
||||
static bool _equalCreatedbStmt(const CreatedbStmt* a, const CreatedbStmt* b)
|
||||
{
|
||||
COMPARE_STRING_FIELD(dbname);
|
||||
COMPARE_SCALAR_FIELD(missing_ok);
|
||||
COMPARE_NODE_FIELD(options);
|
||||
|
||||
return true;
|
||||
@ -2140,6 +2141,7 @@ static bool _equalCreateRoleStmt(const CreateRoleStmt* a, const CreateRoleStmt*
|
||||
static bool _equalAlterRoleStmt(const AlterRoleStmt* a, const AlterRoleStmt* b)
|
||||
{
|
||||
COMPARE_STRING_FIELD(role);
|
||||
COMPARE_SCALAR_FIELD(missing_ok);
|
||||
COMPARE_NODE_FIELD(options);
|
||||
COMPARE_SCALAR_FIELD(action);
|
||||
COMPARE_SCALAR_FIELD(lockstatus);
|
||||
@ -2198,6 +2200,7 @@ static bool _equalReindexStmt(const ReindexStmt* a, const ReindexStmt* b)
|
||||
static bool _equalCreateSchemaStmt(const CreateSchemaStmt* a, const CreateSchemaStmt* b)
|
||||
{
|
||||
COMPARE_STRING_FIELD(schemaname);
|
||||
COMPARE_SCALAR_FIELD(missing_ok);
|
||||
COMPARE_STRING_FIELD(authid);
|
||||
COMPARE_SCALAR_FIELD(hasBlockChain);
|
||||
COMPARE_NODE_FIELD(schemaElts);
|
||||
|
||||
@ -1627,12 +1627,23 @@ AlterUserStmt:
|
||||
ALTER USER RoleId opt_with AlterOptRoleList
|
||||
{
|
||||
AlterRoleStmt *n = makeNode(AlterRoleStmt);
|
||||
n->missing_ok = FALSE;
|
||||
n->role = $3;
|
||||
n->action = +1; /* add, if there are members */
|
||||
n->options = $5;
|
||||
n->lockstatus = DO_NOTHING;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| ALTER USER IF_P EXISTS RoleId opt_with AlterOptRoleList
|
||||
{
|
||||
AlterRoleStmt *n = makeNode(AlterRoleStmt);
|
||||
n->missing_ok = TRUE;
|
||||
n->role = $5;
|
||||
n->action = +1; /* add, if there are members */
|
||||
n->options = $7;
|
||||
n->lockstatus = DO_NOTHING;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| ALTER USER RoleId opt_with ACCOUNT LOCK_P
|
||||
{
|
||||
AlterRoleStmt *n = makeNode(AlterRoleStmt);
|
||||
@ -1887,6 +1898,7 @@ CreateSchemaStmt:
|
||||
| CREATE SCHEMA ColId OptBlockchainWith OptSchemaEltList
|
||||
{
|
||||
CreateSchemaStmt *n = makeNode(CreateSchemaStmt);
|
||||
n->missing_ok = FALSE;
|
||||
/* ...but not both */
|
||||
n->schemaname = $3;
|
||||
n->authid = NULL;
|
||||
@ -1894,6 +1906,17 @@ CreateSchemaStmt:
|
||||
n->schemaElts = $5;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| CREATE SCHEMA IF_P NOT EXISTS ColId OptBlockchainWith OptSchemaEltList
|
||||
{
|
||||
CreateSchemaStmt *n = makeNode(CreateSchemaStmt);
|
||||
n->missing_ok = TRUE;
|
||||
/* ...but not both */
|
||||
n->schemaname = $6;
|
||||
n->authid = NULL;
|
||||
n->hasBlockChain = $7;
|
||||
n->schemaElts = $8;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
;
|
||||
|
||||
OptSchemaName:
|
||||
@ -15782,9 +15805,19 @@ CreatedbStmt:
|
||||
CreatedbStmt *n = makeNode(CreatedbStmt);
|
||||
IsValidIdent($3);
|
||||
n->dbname = $3;
|
||||
n->missing_ok = FALSE;
|
||||
n->options = $5;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| CREATE DATABASE IF_P NOT EXISTS database_name opt_with createdb_opt_list
|
||||
{
|
||||
CreatedbStmt *n = makeNode(CreatedbStmt);
|
||||
IsValidIdent($6);
|
||||
n->dbname = $6;
|
||||
n->missing_ok = TRUE;
|
||||
n->options = $8;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
;
|
||||
|
||||
createdb_opt_list:
|
||||
|
||||
@ -473,8 +473,14 @@ void createdb(const CreatedbStmt* stmt)
|
||||
* message than "unique index violation". There's a race condition but
|
||||
* we're willing to accept the less friendly message in that case.
|
||||
*/
|
||||
if (OidIsValid(get_database_oid(dbname, true)))
|
||||
ereport(ERROR, (errcode(ERRCODE_DUPLICATE_DATABASE), errmsg("database \"%s\" already exists", dbname)));
|
||||
if (OidIsValid(get_database_oid(dbname, true))) {
|
||||
if (stmt->missing_ok) {
|
||||
ereport(NOTICE, (errmsg("database \"%s\" already exists, skipping", dbname)));
|
||||
return;
|
||||
} else {
|
||||
ereport(ERROR, (errcode(ERRCODE_DUPLICATE_DATABASE), errmsg("database \"%s\" already exists", dbname)));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The source DB can't have any active backends, except this one
|
||||
|
||||
@ -174,6 +174,14 @@ void CreateSchemaCommand(CreateSchemaStmt* stmt, const char* queryString)
|
||||
if (saved_uid != owner_uid)
|
||||
SetUserIdAndSecContext(owner_uid, (uint32)save_sec_context | SECURITY_LOCAL_USERID_CHANGE);
|
||||
|
||||
/* make sure there is no existing namespace of same name */
|
||||
if (stmt->missing_ok) {
|
||||
if (SearchSysCacheExists1(NAMESPACENAME, PointerGetDatum(schemaName))) {
|
||||
ereport(NOTICE, (errmsg("schema \"%s\" already exists,skipping", schemaName)));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create the schema's namespace */
|
||||
namespaceId = NamespaceCreate(schemaName, owner_uid, false, hasBlockChain);
|
||||
|
||||
|
||||
@ -2075,10 +2075,16 @@ void AlterRole(AlterRoleStmt* stmt)
|
||||
str_reset(password);
|
||||
str_reset(replPasswd);
|
||||
|
||||
if (!have_createrole_privilege())
|
||||
if (!have_createrole_privilege()) {
|
||||
ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("Permission denied.")));
|
||||
else
|
||||
ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("role \"%s\" does not exist", stmt->role)));
|
||||
} else {
|
||||
if (stmt->missing_ok) {
|
||||
ereport(NOTICE, (errmsg("role \"%s\" does not exist, skipping", stmt->role)));
|
||||
return;
|
||||
} else {
|
||||
ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("role \"%s\" does not exist", stmt->role)));
|
||||
}
|
||||
}
|
||||
}
|
||||
roleid = HeapTupleGetOid(tuple);
|
||||
|
||||
|
||||
@ -1507,6 +1507,7 @@ typedef struct LoadStmt {
|
||||
typedef struct CreatedbStmt {
|
||||
NodeTag type;
|
||||
char* dbname; /* name of database to create */
|
||||
bool missing_ok; /* skip error if db is missing? */
|
||||
List* options; /* List of DefElem nodes */
|
||||
} CreatedbStmt;
|
||||
|
||||
|
||||
@ -131,6 +131,7 @@ typedef struct DropStmt {
|
||||
typedef struct AlterRoleStmt {
|
||||
NodeTag type;
|
||||
char* role; /* role name */
|
||||
bool missing_ok; /* skip error if a role is missing? */
|
||||
List* options; /* List of DefElem nodes */
|
||||
int action; /* +1 = add members, -1 = drop members */
|
||||
RoleLockType lockstatus;
|
||||
@ -710,6 +711,7 @@ typedef enum TempType {
|
||||
|
||||
typedef struct CreateSchemaStmt {
|
||||
NodeTag type;
|
||||
bool missing_ok; /* just do nothing if it already exists? */
|
||||
char *schemaname; /* the name of the schema to create */
|
||||
char *authid; /* the owner of the created schema */
|
||||
bool hasBlockChain; /* whether this schema has blockchain */
|
||||
|
||||
28
src/test/regress/expected/test_if_not_exists.out
Normal file
28
src/test/regress/expected/test_if_not_exists.out
Normal file
@ -0,0 +1,28 @@
|
||||
create database db_testa;
|
||||
create database if not exists db_testa;
|
||||
NOTICE: database "db_testa" already exists, skipping
|
||||
create database db_testa;
|
||||
ERROR: database "db_testa" already exists
|
||||
create database if not exists db_testb;
|
||||
drop database if exists db_testa;
|
||||
drop database if exists db_testb;
|
||||
|
||||
|
||||
create user test_user with password 'Abcd.123';
|
||||
ALTER USER IF EXISTS test_user IDENTIFIED BY 'Abcd.1234';
|
||||
ALTER USER test_user IDENTIFIED BY 'Abcd.12345';
|
||||
ALTER USER IF EXISTS test_user2 IDENTIFIED BY 'Abcd.1234';
|
||||
NOTICE: role "test_user2" does not exist, skipping
|
||||
ALTER USER test_user2 IDENTIFIED BY 'Abcd.1234';
|
||||
ERROR: role "test_user2" does not exist
|
||||
DROP USER test_user;
|
||||
|
||||
CREATE SCHEMA sch_name;
|
||||
CREATE SCHEMA IF NOT EXISTS sch_name;
|
||||
NOTICE: schema "sch_name" already exists,skipping
|
||||
CREATE SCHEMA IF NOT EXISTS sch_name2;
|
||||
CREATE SCHEMA sch_name2;
|
||||
ERROR: schema "sch_name2" already exists
|
||||
drop SCHEMA sch_name;
|
||||
drop SCHEMA sch_name2;
|
||||
|
||||
@ -559,7 +559,7 @@ test: copyselect copy_error_log copy_support_transform copy_from_support_paralle
|
||||
# Another group of parallel tests
|
||||
# ----------
|
||||
test: create_function_3 vacuum
|
||||
test: drop_if_exists
|
||||
test: drop_if_exists test_if_not_exists
|
||||
#test: constraints
|
||||
|
||||
#test: errors subplan_base
|
||||
|
||||
22
src/test/regress/sql/test_if_not_exists.sql
Normal file
22
src/test/regress/sql/test_if_not_exists.sql
Normal file
@ -0,0 +1,22 @@
|
||||
create database db_testa;
|
||||
create database if not exists db_testa;
|
||||
create database db_testa;
|
||||
create database if not exists db_testb;
|
||||
drop database if exists db_testa;
|
||||
drop database if exists db_testb;
|
||||
|
||||
|
||||
create user test_user with password 'Abcd.123';
|
||||
ALTER USER IF EXISTS test_user IDENTIFIED BY 'Abcd.1234';
|
||||
ALTER USER test_user IDENTIFIED BY 'Abcd.12345';
|
||||
ALTER USER IF EXISTS test_user2 IDENTIFIED BY 'Abcd.1234';
|
||||
ALTER USER test_user2 IDENTIFIED BY 'Abcd.1234';
|
||||
DROP USER test_user;
|
||||
|
||||
CREATE SCHEMA sch_name;
|
||||
CREATE SCHEMA IF NOT EXISTS sch_name;
|
||||
CREATE SCHEMA IF NOT EXISTS sch_name2;
|
||||
CREATE SCHEMA sch_name2;
|
||||
drop SCHEMA sch_name;
|
||||
drop SCHEMA sch_name2;
|
||||
|
||||
Reference in New Issue
Block a user