@@ -1789,6 +1789,9 @@ void CreateAlterFunctionNode::executeCreate(thread_db* tdbb, DsqlCompilerScratch
17891789
17901790 if (package.isEmpty())
17911791 {
1792+ if (createIfNotExistsOnly && !DYN_UTIL_check_unique_name_nothrow(tdbb, transaction, name, obj_udf))
1793+ return;
1794+
17921795 executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE,
17931796 DDL_TRIGGER_CREATE_FUNCTION, name, NULL);
17941797
@@ -2804,6 +2807,9 @@ void CreateAlterProcedureNode::executeCreate(thread_db* tdbb, DsqlCompilerScratc
28042807
28052808 if (package.isEmpty())
28062809 {
2810+ if (createIfNotExistsOnly && !DYN_UTIL_check_unique_name_nothrow(tdbb, transaction, name, obj_procedure))
2811+ return;
2812+
28072813 executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE,
28082814 DDL_TRIGGER_CREATE_PROCEDURE, name, NULL);
28092815
@@ -3724,9 +3730,14 @@ void CreateAlterTriggerNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlS
37243730void CreateAlterTriggerNode::executeCreate(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
37253731 jrd_tra* transaction)
37263732{
3733+ if (createIfNotExistsOnly && !DYN_UTIL_check_unique_name_nothrow(tdbb, transaction, name, obj_trigger))
3734+ return;
3735+
37273736 executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE, DDL_TRIGGER_CREATE_TRIGGER,
37283737 name, NULL);
37293738
3739+ DYN_UTIL_check_unique_name(tdbb, transaction, name, obj_trigger);
3740+
37303741 store(tdbb, dsqlScratch, transaction);
37313742
37323743 executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER, DDL_TRIGGER_CREATE_TRIGGER,
@@ -4010,9 +4021,14 @@ void CreateCollationNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScra
40104021 // run all statements under savepoint control
40114022 AutoSavePoint savePoint(tdbb, transaction);
40124023
4024+ if (createIfNotExistsOnly && !DYN_UTIL_check_unique_name_nothrow(tdbb, transaction, name, obj_collation))
4025+ return;
4026+
40134027 executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE,
40144028 DDL_TRIGGER_CREATE_COLLATION, name, NULL);
40154029
4030+ DYN_UTIL_check_unique_name(tdbb, transaction, name, obj_collation);
4031+
40164032 AutoCacheRequest request(tdbb, drq_s_colls, DYN_REQUESTS);
40174033
40184034 STORE(REQUEST_HANDLE request TRANSACTION_HANDLE transaction)
@@ -4400,9 +4416,14 @@ void CreateDomainNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch
44004416 // run all statements under savepoint control
44014417 AutoSavePoint savePoint(tdbb, transaction);
44024418
4419+ if (createIfNotExistsOnly && !DYN_UTIL_check_unique_name_nothrow(tdbb, transaction, nameType->name, obj_field))
4420+ return;
4421+
44034422 executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE,
44044423 DDL_TRIGGER_CREATE_DOMAIN, nameType->name, NULL);
44054424
4425+ DYN_UTIL_check_unique_name(tdbb, transaction, nameType->name, obj_field);
4426+
44064427 storeGlobalField(tdbb, transaction, nameType->name, type);
44074428
44084429 if (nameType->defaultClause || check || notNull)
@@ -5539,6 +5560,9 @@ void CreateAlterExceptionNode::executeCreate(thread_db* tdbb, DsqlCompilerScratc
55395560 Attachment* const attachment = transaction->getAttachment();
55405561 const MetaString& ownerName = attachment->getEffectiveUserName();
55415562
5563+ if (createIfNotExistsOnly && !DYN_UTIL_check_unique_name_nothrow(tdbb, transaction, name, obj_exception))
5564+ return;
5565+
55425566 executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE,
55435567 DDL_TRIGGER_CREATE_EXCEPTION, name, NULL);
55445568
@@ -5766,9 +5790,14 @@ void CreateAlterSequenceNode::putErrorPrefix(Firebird::Arg::StatusVector& status
57665790void CreateAlterSequenceNode::executeCreate(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
57675791 jrd_tra* transaction)
57685792{
5793+ if (createIfNotExistsOnly && !DYN_UTIL_check_unique_name_nothrow(tdbb, transaction, name, obj_generator))
5794+ return;
5795+
57695796 executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE, DDL_TRIGGER_CREATE_SEQUENCE,
57705797 name, NULL);
57715798
5799+ DYN_UTIL_check_unique_name(tdbb, transaction, name, obj_generator);
5800+
57725801 const SINT64 val = value.value_or(1);
57735802 SLONG initialStep = 1;
57745803 if (step.has_value())
@@ -5777,6 +5806,7 @@ void CreateAlterSequenceNode::executeCreate(thread_db* tdbb, DsqlCompilerScratch
57775806 if (initialStep == 0)
57785807 status_exception::raise(Arg::Gds(isc_dyn_cant_use_zero_increment) << Arg::Str(name));
57795808 }
5809+
57805810 store(tdbb, transaction, name, fb_sysflag_user, val, initialStep);
57815811
57825812 executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER, DDL_TRIGGER_CREATE_SEQUENCE,
@@ -6398,11 +6428,25 @@ void RelationNode::defineField(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch
63986428 const ObjectsArray<MetaName>* pkCols)
63996429{
64006430 dsql_fld* field = clause->field;
6431+ dsql_rel* relation = dsqlScratch->relation;
6432+
6433+ if (clause->createIfNotExistsOnly)
6434+ {
6435+ AutoCacheRequest request(tdbb, drq_l_rel_fld_name, DYN_REQUESTS);
6436+
6437+ FOR(REQUEST_HANDLE request TRANSACTION_HANDLE transaction)
6438+ RFL IN RDB$RELATION_FIELDS
6439+ WITH RFL.RDB$RELATION_NAME = relation->rel_name.c_str() AND
6440+ RFL.RDB$FIELD_NAME = field->fld_name.c_str()
6441+ {
6442+ return;
6443+ }
6444+ END_FOR
6445+ }
64016446
64026447 // Add the field to the relation being defined for parsing purposes.
64036448
64046449 bool permanent = false;
6405- dsql_rel* relation = dsqlScratch->relation;
64066450 if (relation != NULL)
64076451 {
64086452 if (!(relation->rel_flags & REL_new_relation))
@@ -6596,12 +6640,26 @@ bool RelationNode::defineDefault(thread_db* /*tdbb*/, DsqlCompilerScratch* dsqlS
65966640}
65976641
65986642// Make a constraint object from a legacy node.
6599- void RelationNode::makeConstraint(thread_db* /* tdbb*/ , DsqlCompilerScratch* dsqlScratch,
6643+ void RelationNode::makeConstraint(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
66006644 jrd_tra* transaction, AddConstraintClause* clause,
66016645 ObjectsArray<CreateDropConstraint>& constraints, bool* notNull)
66026646{
66036647 MemoryPool& pool = dsqlScratch->getPool();
66046648
6649+ if (clause->createIfNotExistsOnly)
6650+ {
6651+ AutoCacheRequest request(tdbb, drq_l_rel_con, DYN_REQUESTS);
6652+
6653+ FOR(REQUEST_HANDLE request TRANSACTION_HANDLE transaction)
6654+ RC IN RDB$RELATION_CONSTRAINTS
6655+ WITH RC.RDB$CONSTRAINT_NAME EQ clause->name.c_str() AND
6656+ RC.RDB$RELATION_NAME EQ name.c_str()
6657+ {
6658+ return;
6659+ }
6660+ END_FOR
6661+ }
6662+
66056663 switch (clause->constraintType)
66066664 {
66076665 case AddConstraintClause::CTYPE_NOT_NULL:
@@ -7474,6 +7532,9 @@ void CreateRelationNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
74747532void CreateRelationNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
74757533 jrd_tra* transaction)
74767534{
7535+ if (createIfNotExistsOnly && !DYN_UTIL_check_unique_name_nothrow(tdbb, transaction, name, obj_relation))
7536+ return;
7537+
74777538 saveRelation(tdbb, dsqlScratch, name, false, true);
74787539
74797540 if (externalFile)
@@ -8790,6 +8851,9 @@ void CreateAlterViewNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
87908851void CreateAlterViewNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
87918852 jrd_tra* transaction)
87928853{
8854+ if (createIfNotExistsOnly && !DYN_UTIL_check_unique_name_nothrow(tdbb, transaction, name, obj_relation))
8855+ return;
8856+
87938857 Attachment* const attachment = transaction->tra_attachment;
87948858 const MetaString& ownerName = attachment->getEffectiveUserName();
87958859
@@ -9962,6 +10026,9 @@ void CreateIndexNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
996210026 // run all statements under savepoint control
996310027 AutoSavePoint savePoint(tdbb, transaction);
996410028
10029+ if (createIfNotExistsOnly && !DYN_UTIL_check_unique_name_nothrow(tdbb, transaction, name, obj_index))
10030+ return;
10031+
996510032 executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE, DDL_TRIGGER_CREATE_INDEX,
996610033 name, NULL);
996710034
@@ -10402,6 +10469,9 @@ void CreateShadowNode::execute(thread_db* tdbb, DsqlCompilerScratch* /*dsqlScrat
1040210469 FIRST 1 X IN RDB$FILES
1040310470 WITH X.RDB$SHADOW_NUMBER EQ number
1040410471 {
10472+ if (createIfNotExistsOnly)
10473+ return;
10474+
1040510475 // msg 165: "Shadow %ld already exists"
1040610476 status_exception::raise(Arg::PrivateDyn(165) << Arg::Num(number));
1040710477 }
@@ -10522,6 +10592,10 @@ void CreateAlterRoleNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScra
1052210592
1052310593 // run all statements under savepoint control
1052410594 AutoSavePoint savePoint(tdbb, transaction);
10595+ MetaName dummyName;
10596+
10597+ if (createIfNotExistsOnly && isItSqlRole(tdbb, transaction, name, dummyName))
10598+ return;
1052510599
1052610600 executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE,
1052710601 createFlag ? DDL_TRIGGER_CREATE_ROLE : DDL_TRIGGER_ALTER_ROLE, name, NULL);
@@ -10544,7 +10618,6 @@ void CreateAlterRoleNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScra
1054410618 status_exception::raise(Arg::PrivateDyn(193) << name);
1054510619 }
1054610620
10547- MetaName dummyName;
1054810621 if (createFlag && isItSqlRole(tdbb, transaction, name, dummyName))
1054910622 {
1055010623 // msg 194: "SQL role @1 already exists"
@@ -10701,6 +10774,8 @@ void MappingNode::runInSecurityDb(SecDbContext* secDbContext)
1070110774 {
1070210775 case MAP_ADD:
1070310776 ddl = "CREATE MAPPING ";
10777+ if (createIfNotExistsOnly)
10778+ ddl += "IF NOT EXISTS ";
1070410779 break;
1070510780 case MAP_MOD:
1070610781 ddl = "ALTER MAPPING ";
@@ -11014,6 +11089,8 @@ void MappingNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd
1101411089 case MAP_ADD:
1101511090 if (found)
1101611091 {
11092+ if (createIfNotExistsOnly)
11093+ return;
1101711094 (Arg::Gds(isc_map_already_exists) << name).raise();
1101811095 }
1101911096 // fall through ...
@@ -11261,6 +11338,8 @@ void CreateAlterUserNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScra
1126111338 (Arg::Gds(isc_random) << "Missing user name for ALTER CURRENT USER").raise();
1126211339 }
1126311340
11341+ userData->createIfNotExistsOnly = createIfNotExistsOnly;
11342+
1126411343 Firebird::LocalStatus s;
1126511344 CheckStatusWrapper statusWrapper(&s);
1126611345
0 commit comments