mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-02-02 10:40:38 +01:00
Implemented #7046: Make ability to add comment to mapping ('COMMENT ON MAPPING ... IS ...')
This commit is contained in:
parent
65efac2a56
commit
c3b172d4e2
@ -158,6 +158,7 @@ basic_type:
|
||||
- PACKAGE
|
||||
- USER (ability to store comment depends upon user management plugin)
|
||||
- SECURITY CLASS (not implemented because Borland hid them).
|
||||
- [GLOBAL] MAPPING
|
||||
|
||||
|
||||
5) Allow setting and dropping default values from table fields.
|
||||
|
@ -10500,6 +10500,7 @@ string MappingNode::internalPrint(NodePrinter& printer) const
|
||||
NODE_PRINT(printer, fromType);
|
||||
NODE_PRINT(printer, from);
|
||||
NODE_PRINT(printer, to);
|
||||
NODE_PRINT(printer, comment);
|
||||
NODE_PRINT(printer, op);
|
||||
NODE_PRINT(printer, mode);
|
||||
NODE_PRINT(printer, global);
|
||||
@ -10558,10 +10559,22 @@ void MappingNode::runInSecurityDb(SecDbContext* secDbContext)
|
||||
case MAP_RPL:
|
||||
ddl = "CREATE OR ALTER MAPPING ";
|
||||
break;
|
||||
case MAP_COMMENT:
|
||||
ddl = "COMMENT ON MAPPING ";
|
||||
break;
|
||||
}
|
||||
addItem(ddl, name.c_str());
|
||||
|
||||
if (op == MAP_COMMENT)
|
||||
{
|
||||
ddl += " IS ";
|
||||
if (comment)
|
||||
addItem(ddl, comment->c_str(), '\'');
|
||||
else
|
||||
ddl += "NULL";
|
||||
}
|
||||
|
||||
addItem(ddl, name.c_str());
|
||||
if (op != MAP_DROP)
|
||||
else if (op != MAP_DROP)
|
||||
{
|
||||
ddl += " USING ";
|
||||
switch (mode)
|
||||
@ -10654,6 +10667,7 @@ void MappingNode::runInSecurityDb(SecDbContext* secDbContext)
|
||||
(Arg::Gds(isc_map_already_exists) << name).raise();
|
||||
break;
|
||||
|
||||
case MAP_COMMENT:
|
||||
case MAP_MOD:
|
||||
case MAP_DROP:
|
||||
if (!hasLine)
|
||||
@ -10676,6 +10690,10 @@ void MappingNode::runInSecurityDb(SecDbContext* secDbContext)
|
||||
Field<Varying> f2(full, 255);
|
||||
Field<Varying> nm2(full, MAX_SQL_IDENTIFIER_LEN);
|
||||
|
||||
Message cmnt;
|
||||
Field<Varying> c3(cmnt, MAX_VARY_COLUMN_SIZE);
|
||||
Field<Varying> nm3(cmnt, MAX_SQL_IDENTIFIER_LEN);
|
||||
|
||||
toType = role ? 1 : 0;
|
||||
if (to)
|
||||
t = to->c_str();
|
||||
@ -10688,7 +10706,9 @@ void MappingNode::runInSecurityDb(SecDbContext* secDbContext)
|
||||
type2 = fromType->c_str();
|
||||
if (from)
|
||||
f2 = fromUtf8.c_str();
|
||||
nm2 = name.c_str();
|
||||
if (comment)
|
||||
c3 = comment->c_str();
|
||||
nm3 = nm2 = name.c_str();
|
||||
|
||||
Message* msg = NULL;
|
||||
const char* sql = NULL;
|
||||
@ -10707,6 +10727,11 @@ void MappingNode::runInSecurityDb(SecDbContext* secDbContext)
|
||||
"where RDB$MAP_NAME = ?";
|
||||
msg = &full;
|
||||
break;
|
||||
case MAP_COMMENT:
|
||||
sql = "update RDB$AUTH_MAPPING set RDB$DESCRIPTION = ? "
|
||||
"where RDB$MAP_NAME = ?";
|
||||
msg = &cmnt;
|
||||
break;
|
||||
case MAP_DROP:
|
||||
sql = "delete from RDBAUTH_MAPPING where RDB$MAP_NAME = ?";
|
||||
msg = &msgCheck;
|
||||
@ -10751,7 +10776,7 @@ void MappingNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd
|
||||
// run all statements under savepoint control
|
||||
AutoSavePoint savePoint(tdbb, transaction);
|
||||
|
||||
fb_assert(op == MAP_DROP || fromType);
|
||||
fb_assert(op == MAP_DROP || op == MAP_COMMENT || fromType);
|
||||
|
||||
short plugNull = plugin ? FALSE : TRUE;
|
||||
short dbNull = db ? FALSE : TRUE;
|
||||
@ -10807,6 +10832,17 @@ void MappingNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd
|
||||
END_MODIFY
|
||||
break;
|
||||
|
||||
case MAP_COMMENT:
|
||||
MODIFY M
|
||||
M.RDB$DESCRIPTION.NULL = !(comment && comment->hasData());
|
||||
if (!M.RDB$DESCRIPTION.NULL)
|
||||
{
|
||||
AutoBlb b(tdbb, blb::create(tdbb, transaction, &M.RDB$DESCRIPTION));
|
||||
b->BLB_put_data(tdbb, (const UCHAR*)(comment->c_str()), comment->length());
|
||||
}
|
||||
END_MODIFY
|
||||
break;
|
||||
|
||||
case MAP_DROP:
|
||||
ddlTriggerAction = DDL_TRIGGER_DROP_MAPPING;
|
||||
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE, ddlTriggerAction,
|
||||
@ -10870,15 +10906,17 @@ void MappingNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd
|
||||
|
||||
case MAP_MOD:
|
||||
case MAP_DROP:
|
||||
case MAP_COMMENT:
|
||||
if (!found)
|
||||
(Arg::Gds(isc_map_not_exists) << name).raise();
|
||||
break;
|
||||
}
|
||||
|
||||
fb_assert(ddlTriggerAction > 0);
|
||||
fb_assert(ddlTriggerAction > 0 || op == MAP_COMMENT);
|
||||
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
|
||||
}
|
||||
|
@ -2066,7 +2066,7 @@ private:
|
||||
class MappingNode : public DdlNode, private ExecInSecurityDb
|
||||
{
|
||||
public:
|
||||
enum OP {MAP_ADD, MAP_MOD, MAP_RPL, MAP_DROP};
|
||||
enum OP {MAP_ADD, MAP_MOD, MAP_RPL, MAP_DROP, MAP_COMMENT};
|
||||
|
||||
MappingNode(MemoryPool& p, OP o, const MetaName& nm)
|
||||
: DdlNode(p),
|
||||
@ -2077,6 +2077,7 @@ public:
|
||||
fromType(NULL),
|
||||
from(NULL),
|
||||
to(NULL),
|
||||
comment(NULL),
|
||||
op(o),
|
||||
mode('#'),
|
||||
global(false),
|
||||
@ -2096,7 +2097,8 @@ protected:
|
||||
{
|
||||
statusVector << Firebird::Arg::Gds(isc_dsql_mapping_failed) << name <<
|
||||
(op == MAP_ADD ? "CREATE" : op == MAP_MOD ?
|
||||
"ALTER" : op == MAP_RPL ? "CREATE OR ALTER" : "DROP");
|
||||
"ALTER" : op == MAP_RPL ? "CREATE OR ALTER" : op == MAP_DROP ?
|
||||
"DROP" : "COMMENT ON");
|
||||
}
|
||||
void runInSecurityDb(SecDbContext* secDbContext);
|
||||
|
||||
@ -2111,6 +2113,7 @@ public:
|
||||
MetaName* fromType;
|
||||
IntlString* from;
|
||||
MetaName* to;
|
||||
Firebird::string* comment;
|
||||
OP op;
|
||||
char mode; // * - any source, P - plugin, M - mapping, S - any serverwide plugin
|
||||
bool global;
|
||||
|
@ -5651,6 +5651,8 @@ comment
|
||||
{ $$ = newNode<CommentOnNode>($3, *$4, "", *$6); }
|
||||
| comment_on_user
|
||||
{ $$ = $1; }
|
||||
| comment_on_mapping
|
||||
{ $$ = $1; }
|
||||
;
|
||||
|
||||
%type <createAlterUserNode> comment_on_user
|
||||
@ -7307,6 +7309,28 @@ drop_map_clause($global)
|
||||
}
|
||||
;
|
||||
|
||||
%type <mappingNode> comment_on_mapping
|
||||
comment_on_mapping
|
||||
: COMMENT ON MAPPING map_comment(false)
|
||||
{
|
||||
$$ = $4;
|
||||
}
|
||||
| COMMENT ON GLOBAL MAPPING map_comment(true)
|
||||
{
|
||||
$$ = $5;
|
||||
}
|
||||
;
|
||||
|
||||
%type <mappingNode> map_comment(<boolVal>)
|
||||
map_comment($global)
|
||||
: map_name IS ddl_desc
|
||||
{
|
||||
$$ = newNode<MappingNode>(MappingNode::MAP_COMMENT, *$1);
|
||||
$$->global = $global;
|
||||
$$->comment = $3;
|
||||
}
|
||||
;
|
||||
|
||||
%type <mappingNode> map_clause(<mappingOp>)
|
||||
map_clause($op)
|
||||
: map_name
|
||||
|
@ -1725,10 +1725,11 @@ RecordBuffer* MappingList::getList(thread_db* tdbb, jrd_rel* relation)
|
||||
Field<Varying> from(mMap, 255);
|
||||
Field<SSHORT> role(mMap);
|
||||
Field<Varying> to(mMap, MAX_SQL_IDENTIFIER_SIZE);
|
||||
Field<ISC_QUAD> desc(mMap);
|
||||
|
||||
curs = att->openCursor(&st, tra, 0,
|
||||
"SELECT RDB$MAP_NAME, RDB$MAP_USING, RDB$MAP_PLUGIN, RDB$MAP_DB, "
|
||||
" RDB$MAP_FROM_TYPE, RDB$MAP_FROM, RDB$MAP_TO_TYPE, RDB$MAP_TO "
|
||||
" RDB$MAP_FROM_TYPE, RDB$MAP_FROM, RDB$MAP_TO_TYPE, RDB$MAP_TO, RDB$DESCRIPTION "
|
||||
"FROM RDB$AUTH_MAPPING",
|
||||
3, nullptr, nullptr, mMap.getMetadata(), nullptr, 0);
|
||||
if (st->getState() & IStatus::STATE_ERRORS)
|
||||
@ -1798,6 +1799,20 @@ RecordBuffer* MappingList::getList(thread_db* tdbb, jrd_rel* relation)
|
||||
DumpField(f_sec_map_to, VALUE_STRING, to->len, to->data));
|
||||
}
|
||||
|
||||
if (!desc.null)
|
||||
{
|
||||
RefPtr<IBlob> blb(REF_NO_INCR, att->openBlob(&st, tra, &desc, 0, nullptr));
|
||||
check("IAttachment::openBlob", &st);
|
||||
string buf;
|
||||
const FB_SIZE_T FLD_LIMIT = MAX_COLUMN_SIZE;
|
||||
unsigned length = 0;
|
||||
blb->getSegment(&st, FLD_LIMIT, buf.getBuffer(FLD_LIMIT), &length);
|
||||
check("IBlob::getSegment", &st);
|
||||
|
||||
putField(tdbb, record,
|
||||
DumpField(f_sec_map_comment, VALUE_STRING, length, buf.c_str()));
|
||||
}
|
||||
|
||||
buffer->store(record);
|
||||
}
|
||||
check("IResultSet::fetchNext", &st);
|
||||
|
@ -685,6 +685,7 @@ RELATION(nam_sec_global_auth_mapping, rel_global_auth_mapping, ODS_12_0, rel_vir
|
||||
FIELD(f_sec_map_from, nam_sec_map_from, fld_map_from, 0, ODS_12_0)
|
||||
FIELD(f_sec_map_to_type, nam_sec_map_to_type, fld_obj_type, 0, ODS_12_0)
|
||||
FIELD(f_sec_map_to, nam_sec_map_to, fld_map_to, 0, ODS_12_0)
|
||||
FIELD(f_sec_map_comment, nam_sec_description, fld_description, 0, ODS_13_1)
|
||||
END_RELATION
|
||||
|
||||
// Relation 47 (RDB$DB_CREATORS)
|
||||
|
Loading…
Reference in New Issue
Block a user