Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature #4203 - DROP [IF EXISTS] #7946

Merged
merged 2 commits into from
Jan 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions doc/sql.extensions/README.ddl.txt
Original file line number Diff line number Diff line change
Expand Up @@ -629,3 +629,32 @@ Only users with administrator rights can use this option.
(Dmitry Sibiryakov)

If is used twice, an error is returned.


DDL enhancements in Firebird v6.
--------------------------------

1) DROP [IF EXISTS]

Using subclause IF EXISTS, it's now possible to try to drop objects and do not get errors when they di not exists.

DROP EXCEPTION [IF EXISTS] <exception>
DROP INDEX [IF EXISTS] <index>
DROP PROCEDURE [IF EXISTS] <procedure>
DROP TABLE [IF EXISTS] <table>
DROP TRIGGER [IF EXISTS] <trigger>
DROP VIEW [IF EXISTS] <view>
DROP FILTER [IF EXISTS] <filter>
DROP DOMAIN [IF EXISTS] <domain>
DROP [EXTERNAL] FUNCTION [IF EXISTS] <function>
DROP SHADOW [IF EXISTS] <shadow>
DROP ROLE [IF EXISTS] <role>
DROP GENERATOR [IF EXISTS] <generator>
DROP SEQUENCE [IF EXISTS] <sequence>
DROP COLLATION [IF EXISTS] <collation>
DROP USER [IF EXISTS] <user> [USING PLUGIN <plugin>]
DROP PACKAGE [IF EXISTS] <package>
DROP PACKAGE BODY [IF EXISTS] <package>
DROP [GLOBAL] MAPPING [IF EXISTS] <mapping>
ALTER TABLE <table> DROP [IF EXISTS] <column>
ALTER TABLE <table> DROP CONSTRAINT [IF EXISTS] <constraint>
33 changes: 19 additions & 14 deletions src/dsql/DdlNodes.epp
Original file line number Diff line number Diff line change
Expand Up @@ -4335,7 +4335,7 @@ void DropCollationNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratc
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER, DDL_TRIGGER_DROP_COLLATION,
name, NULL);
}
else
else if (!silent)
status_exception::raise(Arg::Gds(isc_dyn_collation_not_found) << Arg::Str(name));

savePoint.release(); // everything is ok
Expand Down Expand Up @@ -5406,7 +5406,7 @@ void DropDomainNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER, DDL_TRIGGER_DROP_DOMAIN,
name, NULL);
}
else
else if (!silent)
{
// msg 89: "Domain not found"
status_exception::raise(Arg::PrivateDyn(89));
Expand Down Expand Up @@ -6236,7 +6236,7 @@ void RelationNode::FieldDefinition::store(thread_db* tdbb, jrd_tra* transaction)
// done by code and system triggers. See the functional description of
// deleteKeyConstraint function for detail.
void RelationNode::deleteLocalField(thread_db* tdbb, jrd_tra* transaction,
const MetaName& relationName, const MetaName& fieldName)
const MetaName& relationName, const MetaName& fieldName, bool silent)
{
AutoCacheRequest request(tdbb, drq_l_dep_flds, DYN_REQUESTS);
bool found = false;
Expand Down Expand Up @@ -6358,7 +6358,7 @@ void RelationNode::deleteLocalField(thread_db* tdbb, jrd_tra* transaction,
}
END_FOR

if (!found)
if (!found && !silent)
{
// msg 176: "column %s does not exist in table/view %s"
status_exception::raise(Arg::PrivateDyn(176) << fieldName << relationName);
Expand Down Expand Up @@ -7828,7 +7828,7 @@ void AlterRelationNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratc
Arg::Gds(isc_dsql_construct_err));
}

deleteLocalField(tdbb, transaction, name, clause->name);
deleteLocalField(tdbb, transaction, name, clause->name, clause->silent);
break;
}

Expand All @@ -7840,8 +7840,8 @@ void AlterRelationNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratc
case Clause::TYPE_DROP_CONSTRAINT:
{
CreateDropConstraint& dropConstraint = constraints.add();
dropConstraint.name =
static_cast<const DropConstraintClause*>(i->getObject())->name;
dropConstraint.name = static_cast<const DropConstraintClause*>(i->getObject())->name;
dropConstraint.silent = static_cast<const DropConstraintClause*>(i->getObject())->silent;
break;
}

Expand Down Expand Up @@ -7933,7 +7933,7 @@ void AlterRelationNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratc
}
END_FOR

if (!found)
if (!found && !constraint->silent)
{
// msg 130: "CONSTRAINT %s does not exist."
status_exception::raise(Arg::PrivateDyn(130) << constraint->name);
Expand Down Expand Up @@ -9222,7 +9222,7 @@ void CreateAlterViewNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScra
for (dsql_fld* relField = modifyingView->rel_fields; relField; relField = relField->fld_next)
{
if (!modifiedFields.exist(relField))
deleteLocalField(tdbb, transaction, name, relField->fld_name);
deleteLocalField(tdbb, transaction, name, relField->fld_name, false);
}
}

Expand Down Expand Up @@ -10154,7 +10154,7 @@ void DropIndexNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, j
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER, DDL_TRIGGER_DROP_INDEX,
name, NULL);
}
else
else if (!silent)
{
// msg 48: "Index not found"
status_exception::raise(Arg::PrivateDyn(48));
Expand Down Expand Up @@ -10283,7 +10283,7 @@ void DropFilterNode::execute(thread_db* tdbb, DsqlCompilerScratch* /*dsqlScratch
}
END_FOR

if (!found)
if (!found && !silent)
{
// msg 37: "Blob Filter %s not found"
status_exception::raise(Arg::PrivateDyn(37) << name);
Expand Down Expand Up @@ -10990,19 +10990,24 @@ void MappingNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd
break;

case MAP_MOD:
case MAP_DROP:
case MAP_COMMENT:
if (!found)
(Arg::Gds(isc_map_not_exists) << name).raise();
break;

case MAP_DROP:
if (!found && !silentDrop)
(Arg::Gds(isc_map_not_exists) << name).raise();
break;
}

fb_assert(ddlTriggerAction > 0 || op == MAP_COMMENT);
fb_assert(ddlTriggerAction > 0 || op == MAP_COMMENT || (op == MAP_DROP && silentDrop));
if (ddlTriggerAction > 0)
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER, ddlTriggerAction, name, NULL);

if (op != MAP_COMMENT)
DFW_post_work(transaction, dfw_clear_cache, NULL, Mapping::MAPPING_CACHE);

savePoint.release(); // everything is ok
}

Expand Down Expand Up @@ -11083,7 +11088,7 @@ void DropRoleNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jr
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER, DDL_TRIGGER_DROP_ROLE,
name, NULL);
}
else
else if (!silent)
{
// msg 155: "Role %s not found"
status_exception::raise(Arg::PrivateDyn(155) << name);
Expand Down
45 changes: 22 additions & 23 deletions src/dsql/DdlNodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -918,6 +918,7 @@ class DropCollationNode : public DdlNode

public:
MetaName name;
bool silent = false;
};


Expand Down Expand Up @@ -1025,6 +1026,7 @@ class DropDomainNode : public DdlNode

public:
MetaName name;
bool silent = false;
};


Expand Down Expand Up @@ -1301,6 +1303,7 @@ class RelationNode : public DdlNode

MetaName name;
Firebird::AutoPtr<Constraint> create;
bool silent = false;
};

struct Clause
Expand Down Expand Up @@ -1484,13 +1487,13 @@ class RelationNode : public DdlNode
{
explicit DropColumnClause(MemoryPool& p)
: Clause(p, TYPE_DROP_COLUMN),
name(p),
cascade(false)
name(p)
{
}

MetaName name;
bool cascade;
bool cascade = false;
bool silent = false;
};

struct DropConstraintClause : public Clause
Expand All @@ -1502,12 +1505,13 @@ class RelationNode : public DdlNode
}

MetaName name;
bool silent = false;
};

RelationNode(MemoryPool& p, RelationSourceNode* aDsqlNode);

static void deleteLocalField(thread_db* tdbb, jrd_tra* transaction,
const MetaName& relationName, const MetaName& fieldName);
const MetaName& relationName, const MetaName& fieldName, bool silent);

static void addToPublication(thread_db* tdbb, jrd_tra* transaction,
const MetaName& tableName, const MetaName& pubTame);
Expand Down Expand Up @@ -1858,6 +1862,7 @@ class DropIndexNode : public DdlNode

public:
MetaName name;
bool silent = false;
};


Expand Down Expand Up @@ -1946,6 +1951,7 @@ class DropFilterNode : public DdlNode

public:
MetaName name;
bool silent = false;
};


Expand Down Expand Up @@ -2081,16 +2087,7 @@ class MappingNode : public DdlNode, private ExecInSecurityDb
: DdlNode(p),
name(p, nm),
fromUtf8(p),
plugin(NULL),
db(NULL),
fromType(NULL),
from(NULL),
to(NULL),
comment(NULL),
op(o),
mode('#'),
global(false),
role(false)
op(o)
{
}

Expand All @@ -2117,16 +2114,17 @@ class MappingNode : public DdlNode, private ExecInSecurityDb
public:
MetaName name;
Firebird::string fromUtf8;
MetaName* plugin;
MetaName* db;
MetaName* fromType;
IntlString* from;
MetaName* to;
Firebird::string* comment;
MetaName* plugin = nullptr;
MetaName* db = nullptr;
MetaName* fromType = nullptr;
IntlString* from = nullptr;
MetaName* to = nullptr;
Firebird::string* comment = nullptr;
OP op;
char mode; // * - any source, P - plugin, M - mapping, S - any serverwide plugin
bool global;
bool role;
char mode = '#'; // * - any source, P - plugin, M - mapping, S - any serverwide plugin
bool global = false;
bool role = false;
bool silentDrop = false;
};


Expand All @@ -2152,6 +2150,7 @@ class DropRoleNode : public DdlNode

public:
MetaName name;
bool silent = false;
};


Expand Down
2 changes: 1 addition & 1 deletion src/dsql/parse-conflicts.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
71 shift/reduce conflicts, 22 reduce/reduce conflicts.
94 shift/reduce conflicts, 22 reduce/reduce conflicts.
Loading
Loading