@@ -1832,6 +1832,9 @@ void CreateAlterFunctionNode::executeCreate(thread_db* tdbb, DsqlCompilerScratch
18321832
18331833 if (package.isEmpty())
18341834 {
1835+ if (createIfNotExistsOnly && !DYN_UTIL_check_unique_name_nothrow(tdbb, transaction, name, obj_udf))
1836+ return;
1837+
18351838 executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE,
18361839 DDL_TRIGGER_CREATE_FUNCTION, name, NULL);
18371840
@@ -2847,6 +2850,9 @@ void CreateAlterProcedureNode::executeCreate(thread_db* tdbb, DsqlCompilerScratc
28472850
28482851 if (package.isEmpty())
28492852 {
2853+ if (createIfNotExistsOnly && !DYN_UTIL_check_unique_name_nothrow(tdbb, transaction, name, obj_procedure))
2854+ return;
2855+
28502856 executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE,
28512857 DDL_TRIGGER_CREATE_PROCEDURE, name, NULL);
28522858
@@ -3766,9 +3772,14 @@ void CreateAlterTriggerNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlS
37663772void CreateAlterTriggerNode::executeCreate(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
37673773 jrd_tra* transaction)
37683774{
3775+ if (createIfNotExistsOnly && !DYN_UTIL_check_unique_name_nothrow(tdbb, transaction, name, obj_trigger))
3776+ return;
3777+
37693778 executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE, DDL_TRIGGER_CREATE_TRIGGER,
37703779 name, NULL);
37713780
3781+ DYN_UTIL_check_unique_name(tdbb, transaction, name, obj_trigger);
3782+
37723783 store(tdbb, dsqlScratch, transaction);
37733784
37743785 executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER, DDL_TRIGGER_CREATE_TRIGGER,
@@ -4052,9 +4063,14 @@ void CreateCollationNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScra
40524063 // run all statements under savepoint control
40534064 AutoSavePoint savePoint(tdbb, transaction);
40544065
4066+ if (createIfNotExistsOnly && !DYN_UTIL_check_unique_name_nothrow(tdbb, transaction, name, obj_collation))
4067+ return;
4068+
40554069 executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE,
40564070 DDL_TRIGGER_CREATE_COLLATION, name, NULL);
40574071
4072+ DYN_UTIL_check_unique_name(tdbb, transaction, name, obj_collation);
4073+
40584074 AutoCacheRequest request(tdbb, drq_s_colls, DYN_REQUESTS);
40594075
40604076 STORE(REQUEST_HANDLE request TRANSACTION_HANDLE transaction)
@@ -4442,9 +4458,14 @@ void CreateDomainNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch
44424458 // run all statements under savepoint control
44434459 AutoSavePoint savePoint(tdbb, transaction);
44444460
4461+ if (createIfNotExistsOnly && !DYN_UTIL_check_unique_name_nothrow(tdbb, transaction, nameType->name, obj_field))
4462+ return;
4463+
44454464 executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE,
44464465 DDL_TRIGGER_CREATE_DOMAIN, nameType->name, NULL);
44474466
4467+ DYN_UTIL_check_unique_name(tdbb, transaction, nameType->name, obj_field);
4468+
44484469 storeGlobalField(tdbb, transaction, nameType->name, type);
44494470
44504471 if (nameType->defaultClause || check || notNull)
@@ -5581,6 +5602,9 @@ void CreateAlterExceptionNode::executeCreate(thread_db* tdbb, DsqlCompilerScratc
55815602 Attachment* const attachment = transaction->getAttachment();
55825603 const MetaString& ownerName = attachment->getEffectiveUserName();
55835604
5605+ if (createIfNotExistsOnly && !DYN_UTIL_check_unique_name_nothrow(tdbb, transaction, name, obj_exception))
5606+ return;
5607+
55845608 executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE,
55855609 DDL_TRIGGER_CREATE_EXCEPTION, name, NULL);
55865610
@@ -5808,9 +5832,14 @@ void CreateAlterSequenceNode::putErrorPrefix(Firebird::Arg::StatusVector& status
58085832void CreateAlterSequenceNode::executeCreate(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
58095833 jrd_tra* transaction)
58105834{
5835+ if (createIfNotExistsOnly && !DYN_UTIL_check_unique_name_nothrow(tdbb, transaction, name, obj_generator))
5836+ return;
5837+
58115838 executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE, DDL_TRIGGER_CREATE_SEQUENCE,
58125839 name, NULL);
58135840
5841+ DYN_UTIL_check_unique_name(tdbb, transaction, name, obj_generator);
5842+
58145843 const SINT64 val = value.value_or(1);
58155844 SLONG initialStep = 1;
58165845 if (step.has_value())
@@ -5819,6 +5848,7 @@ void CreateAlterSequenceNode::executeCreate(thread_db* tdbb, DsqlCompilerScratch
58195848 if (initialStep == 0)
58205849 status_exception::raise(Arg::Gds(isc_dyn_cant_use_zero_increment) << Arg::Str(name));
58215850 }
5851+
58225852 store(tdbb, transaction, name, fb_sysflag_user, val, initialStep);
58235853
58245854 executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER, DDL_TRIGGER_CREATE_SEQUENCE,
@@ -6440,11 +6470,25 @@ void RelationNode::defineField(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch
64406470 const ObjectsArray<MetaName>* pkCols)
64416471{
64426472 dsql_fld* field = clause->field;
6473+ dsql_rel* relation = dsqlScratch->relation;
6474+
6475+ if (clause->createIfNotExistsOnly)
6476+ {
6477+ AutoCacheRequest request(tdbb, drq_l_rel_fld_name, DYN_REQUESTS);
6478+
6479+ FOR(REQUEST_HANDLE request TRANSACTION_HANDLE transaction)
6480+ RFL IN RDB$RELATION_FIELDS
6481+ WITH RFL.RDB$RELATION_NAME = relation->rel_name.c_str() AND
6482+ RFL.RDB$FIELD_NAME = field->fld_name.c_str()
6483+ {
6484+ return;
6485+ }
6486+ END_FOR
6487+ }
64436488
64446489 // Add the field to the relation being defined for parsing purposes.
64456490
64466491 bool permanent = false;
6447- dsql_rel* relation = dsqlScratch->relation;
64486492 if (relation != NULL)
64496493 {
64506494 if (!(relation->rel_flags & REL_new_relation))
@@ -6638,12 +6682,26 @@ bool RelationNode::defineDefault(thread_db* /*tdbb*/, DsqlCompilerScratch* dsqlS
66386682}
66396683
66406684// Make a constraint object from a legacy node.
6641- void RelationNode::makeConstraint(thread_db* /* tdbb*/ , DsqlCompilerScratch* dsqlScratch,
6685+ void RelationNode::makeConstraint(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
66426686 jrd_tra* transaction, AddConstraintClause* clause,
66436687 ObjectsArray<CreateDropConstraint>& constraints, bool* notNull)
66446688{
66456689 MemoryPool& pool = dsqlScratch->getPool();
66466690
6691+ if (clause->createIfNotExistsOnly)
6692+ {
6693+ AutoCacheRequest request(tdbb, drq_l_rel_con, DYN_REQUESTS);
6694+
6695+ FOR(REQUEST_HANDLE request TRANSACTION_HANDLE transaction)
6696+ RC IN RDB$RELATION_CONSTRAINTS
6697+ WITH RC.RDB$CONSTRAINT_NAME EQ clause->name.c_str() AND
6698+ RC.RDB$RELATION_NAME EQ name.c_str()
6699+ {
6700+ return;
6701+ }
6702+ END_FOR
6703+ }
6704+
66476705 switch (clause->constraintType)
66486706 {
66496707 case AddConstraintClause::CTYPE_NOT_NULL:
@@ -7516,6 +7574,9 @@ void CreateRelationNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
75167574void CreateRelationNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
75177575 jrd_tra* transaction)
75187576{
7577+ if (createIfNotExistsOnly && !DYN_UTIL_check_unique_name_nothrow(tdbb, transaction, name, obj_relation))
7578+ return;
7579+
75197580 saveRelation(tdbb, dsqlScratch, name, false, true);
75207581
75217582 if (externalFile)
@@ -8944,6 +9005,9 @@ void CreateAlterViewNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
89449005void CreateAlterViewNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
89459006 jrd_tra* transaction)
89469007{
9008+ if (createIfNotExistsOnly && !DYN_UTIL_check_unique_name_nothrow(tdbb, transaction, name, obj_relation))
9009+ return;
9010+
89479011 Attachment* const attachment = transaction->tra_attachment;
89489012 const MetaString& ownerName = attachment->getEffectiveUserName();
89499013
@@ -10116,6 +10180,9 @@ void CreateIndexNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
1011610180 // run all statements under savepoint control
1011710181 AutoSavePoint savePoint(tdbb, transaction);
1011810182
10183+ if (createIfNotExistsOnly && !DYN_UTIL_check_unique_name_nothrow(tdbb, transaction, name, obj_index))
10184+ return;
10185+
1011910186 executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE, DDL_TRIGGER_CREATE_INDEX,
1012010187 name, NULL);
1012110188
@@ -10558,6 +10625,9 @@ void CreateShadowNode::execute(thread_db* tdbb, DsqlCompilerScratch* /*dsqlScrat
1055810625 FIRST 1 X IN RDB$FILES
1055910626 WITH X.RDB$SHADOW_NUMBER EQ number
1056010627 {
10628+ if (createIfNotExistsOnly)
10629+ return;
10630+
1056110631 // msg 165: "Shadow %ld already exists"
1056210632 status_exception::raise(Arg::PrivateDyn(165) << Arg::Num(number));
1056310633 }
@@ -10678,6 +10748,10 @@ void CreateAlterRoleNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScra
1067810748
1067910749 // run all statements under savepoint control
1068010750 AutoSavePoint savePoint(tdbb, transaction);
10751+ MetaName dummyName;
10752+
10753+ if (createIfNotExistsOnly && isItSqlRole(tdbb, transaction, name, dummyName))
10754+ return;
1068110755
1068210756 executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE,
1068310757 createFlag ? DDL_TRIGGER_CREATE_ROLE : DDL_TRIGGER_ALTER_ROLE, name, NULL);
@@ -10700,7 +10774,6 @@ void CreateAlterRoleNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScra
1070010774 status_exception::raise(Arg::PrivateDyn(193) << name);
1070110775 }
1070210776
10703- MetaName dummyName;
1070410777 if (createFlag && isItSqlRole(tdbb, transaction, name, dummyName))
1070510778 {
1070610779 // msg 194: "SQL role @1 already exists"
@@ -10857,6 +10930,8 @@ void MappingNode::runInSecurityDb(SecDbContext* secDbContext)
1085710930 {
1085810931 case MAP_ADD:
1085910932 ddl = "CREATE MAPPING ";
10933+ if (createIfNotExistsOnly)
10934+ ddl += "IF NOT EXISTS ";
1086010935 break;
1086110936 case MAP_MOD:
1086210937 ddl = "ALTER MAPPING ";
@@ -11170,6 +11245,8 @@ void MappingNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd
1117011245 case MAP_ADD:
1117111246 if (found)
1117211247 {
11248+ if (createIfNotExistsOnly)
11249+ return;
1117311250 (Arg::Gds(isc_map_already_exists) << name).raise();
1117411251 }
1117511252 // fall through ...
@@ -11417,6 +11494,8 @@ void CreateAlterUserNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScra
1141711494 (Arg::Gds(isc_random) << "Missing user name for ALTER CURRENT USER").raise();
1141811495 }
1141911496
11497+ userData->createIfNotExistsOnly = createIfNotExistsOnly;
11498+
1142011499 Firebird::LocalStatus s;
1142111500 CheckStatusWrapper statusWrapper(&s);
1142211501
0 commit comments