8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 00:03:02 +01:00

Improvement CORE-4484 - Description (COMMENT ON) for package procedures and functions, and its parameters.

This commit is contained in:
asfernandes 2014-07-27 03:05:44 +00:00
parent d285be3f96
commit 8bbd309e67
6 changed files with 176 additions and 111 deletions

View File

@ -136,7 +136,8 @@ Proposed syntax for testing:
COMMENT ON DATABASE IS {'txt'|NULL}; COMMENT ON DATABASE IS {'txt'|NULL};
COMMENT ON <basic_type> name IS {'txt'|NULL}; COMMENT ON <basic_type> name IS {'txt'|NULL};
COMMENT ON COLUMN table_or_view_name.field_name IS {'txt'|NULL}; COMMENT ON COLUMN table_or_view_name.field_name IS {'txt'|NULL};
COMMENT ON PARAMETER procedure_name.param_name IS {'txt'|NULL}; COMMENT ON {PROCEDURE | FUNCTION} [<package_name> .] name.param_name IS {'txt'|NULL};
COMMENT ON [PROCEDURE | FUNCTION] PARAMETER [<package_name> .] name.param_name IS {'txt'|NULL};
An empty literal string '' will act as NULL since the internal code (DYN in this case) An empty literal string '' will act as NULL since the internal code (DYN in this case)
works this way with blobs. works this way with blobs.

View File

@ -47,6 +47,12 @@ public:
{ {
} }
QualifiedName(MemoryPool& p, const MetaName& aIdentifier)
: identifier(p, aIdentifier),
package(p)
{
}
explicit QualifiedName(const MetaName& aIdentifier) explicit QualifiedName(const MetaName& aIdentifier)
: identifier(aIdentifier) : identifier(aIdentifier)
{ {

View File

@ -1054,7 +1054,7 @@ void CommentOnNode::print(string& text) const
" objType: %s\n" " objType: %s\n"
" objName: %s\n" " objName: %s\n"
" text: %s\n", " text: %s\n",
objType, objName.c_str(), this->text.c_str()); objType, objName.toString().c_str(), this->text.c_str());
} }
bool CommentOnNode::checkPermission(thread_db* tdbb, jrd_tra* transaction) bool CommentOnNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
@ -1078,54 +1078,52 @@ void CommentOnNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
const char* subColumnClause = NULL; const char* subColumnClause = NULL;
const char* addWhereClause = NULL; const char* addWhereClause = NULL;
Arg::StatusVector status; Arg::StatusVector status;
string objNameStr = objName.toString();
if (objType == obj_parameter) if (objType == obj_parameter)
{ {
fb_assert(subName.hasData()); fb_assert(subName.hasData());
PreparedStatement::Builder sql; AutoRequest requestHandle;
sql << "select 1 from rdb$procedures p join rdb$procedure_parameters pp using (rdb$procedure_name)" <<
"where p.rdb$procedure_name =" << objName <<
"and p.rdb$package_name is null and pp.rdb$package_name is null" <<
"and pp.rdb$parameter_name =" << subName <<
"union all" <<
"select 2 from rdb$functions f join rdb$function_arguments fa using (rdb$function_name)" <<
"where f.rdb$function_name =" << objName <<
"and f.rdb$package_name is null and fa.rdb$package_name is null" <<
"and fa.rdb$argument_name =" << subName;
AutoPreparedStatement ps(attachment->prepareStatement(tdbb, transaction, sql)); FOR (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction)
AutoResultSet rs(ps->executeQuery(tdbb, transaction)); FUN IN RDB$FUNCTIONS CROSS
ARG IN RDB$FUNCTION_ARGUMENTS
if (!rs->fetch(tdbb)) WITH FUN.RDB$FUNCTION_NAME EQ objName.identifier.c_str() AND
FUN.RDB$PACKAGE_NAME EQUIV NULLIF(objName.package.c_str(), '') AND
ARG.RDB$FUNCTION_NAME EQ FUN.RDB$FUNCTION_NAME AND
ARG.RDB$PACKAGE_NAME EQUIV FUN.RDB$PACKAGE_NAME AND
ARG.RDB$ARGUMENT_NAME EQ subName.c_str()
{ {
status_exception::raise(Arg::Gds(isc_dyn_routine_param_not_found) <<
Arg::Str(subName) << Arg::Str(objName));
}
fb_assert(!rs->isNull(1));
dsc& desc = rs->getDesc(1);
fb_assert(desc.dsc_dtype == dtype_long);
const SLONG result = *reinterpret_cast<SLONG*>(desc.dsc_address);
switch (result)
{
case 1:
objType = obj_procedure;
break;
case 2:
objType = obj_udf; objType = obj_udf;
break;
default:
fb_assert(false);
} }
END_FOR
if (rs->fetch(tdbb)) requestHandle.reset();
FOR (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction)
PRC IN RDB$PROCEDURES CROSS
PRM IN RDB$PROCEDURE_PARAMETERS
WITH PRC.RDB$PROCEDURE_NAME EQ objName.identifier.c_str() AND
PRC.RDB$PACKAGE_NAME EQUIV NULLIF(objName.package.c_str(), '') AND
PRM.RDB$PROCEDURE_NAME EQ PRC.RDB$PROCEDURE_NAME AND
PRM.RDB$PACKAGE_NAME EQUIV PRC.RDB$PACKAGE_NAME AND
PRM.RDB$PARAMETER_NAME EQ subName.c_str()
{
if (objType == obj_parameter)
objType = obj_procedure;
else
{ {
status_exception::raise(Arg::Gds(isc_dyn_routine_param_ambiguous) << status_exception::raise(Arg::Gds(isc_dyn_routine_param_ambiguous) <<
Arg::Str(subName) << Arg::Str(objName)); Arg::Str(subName) << Arg::Str(objNameStr));
}
}
END_FOR
if (objType == obj_parameter)
{
status_exception::raise(Arg::Gds(isc_dyn_routine_param_not_found) <<
Arg::Str(subName) << Arg::Str(objNameStr));
} }
} }
@ -1147,13 +1145,13 @@ void CommentOnNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
tableClause = "rdb$relation_fields"; tableClause = "rdb$relation_fields";
subColumnClause = "rdb$field_name"; subColumnClause = "rdb$field_name";
status << Arg::Gds(isc_dyn_column_does_not_exist) << status << Arg::Gds(isc_dyn_column_does_not_exist) <<
Arg::Str(subName) << Arg::Str(objName); Arg::Str(subName) << Arg::Str(objNameStr);
} }
else else
{ {
tableClause = "rdb$relations"; tableClause = "rdb$relations";
addWhereClause = "rdb$view_blr is null"; addWhereClause = "rdb$view_blr is null";
status << Arg::Gds(isc_dyn_table_not_found) << Arg::Str(objName); status << Arg::Gds(isc_dyn_table_not_found) << Arg::Str(objNameStr);
} }
columnClause = "rdb$relation_name"; columnClause = "rdb$relation_name";
break; break;
@ -1161,7 +1159,7 @@ void CommentOnNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
case obj_view: case obj_view:
tableClause = "rdb$relations"; tableClause = "rdb$relations";
columnClause = "rdb$relation_name"; columnClause = "rdb$relation_name";
status << Arg::Gds(isc_dyn_view_not_found) << Arg::Str(objName); status << Arg::Gds(isc_dyn_view_not_found) << Arg::Str(objNameStr);
addWhereClause = "rdb$view_blr is not null"; addWhereClause = "rdb$view_blr is not null";
break; break;
@ -1171,22 +1169,21 @@ void CommentOnNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
tableClause = "rdb$procedure_parameters"; tableClause = "rdb$procedure_parameters";
subColumnClause = "rdb$parameter_name"; subColumnClause = "rdb$parameter_name";
status << Arg::Gds(isc_dyn_proc_param_not_found) << status << Arg::Gds(isc_dyn_proc_param_not_found) <<
Arg::Str(subName) << Arg::Str(objName); Arg::Str(subName) << Arg::Str(objNameStr);
} }
else else
{ {
tableClause = "rdb$procedures"; tableClause = "rdb$procedures";
status << Arg::Gds(isc_dyn_proc_not_found) << Arg::Str(objName); status << Arg::Gds(isc_dyn_proc_not_found) << Arg::Str(objNameStr);
} }
addWhereClause = "rdb$package_name is null";
columnClause = "rdb$procedure_name"; columnClause = "rdb$procedure_name";
break; break;
case obj_trigger: case obj_trigger:
tableClause = "rdb$triggers"; tableClause = "rdb$triggers";
columnClause = "rdb$trigger_name"; columnClause = "rdb$trigger_name";
status << Arg::Gds(isc_dyn_trig_not_found) << Arg::Str(objName); status << Arg::Gds(isc_dyn_trig_not_found) << Arg::Str(objNameStr);
break; break;
case obj_udf: case obj_udf:
@ -1195,70 +1192,69 @@ void CommentOnNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
tableClause = "rdb$function_arguments"; tableClause = "rdb$function_arguments";
subColumnClause = "rdb$argument_name"; subColumnClause = "rdb$argument_name";
status << Arg::Gds(isc_dyn_func_param_not_found) << status << Arg::Gds(isc_dyn_func_param_not_found) <<
Arg::Str(subName) << Arg::Str(objName); Arg::Str(subName) << Arg::Str(objNameStr);
} }
else else
{ {
tableClause = "rdb$functions"; tableClause = "rdb$functions";
status << Arg::Gds(isc_dyn_func_not_found) << Arg::Str(objName); status << Arg::Gds(isc_dyn_func_not_found) << Arg::Str(objNameStr);
} }
addWhereClause = "rdb$package_name is null";
columnClause = "rdb$function_name"; columnClause = "rdb$function_name";
break; break;
case obj_blob_filter: case obj_blob_filter:
tableClause = "rdb$filters"; tableClause = "rdb$filters";
columnClause = "rdb$function_name"; columnClause = "rdb$function_name";
status << Arg::Gds(isc_dyn_filter_not_found) << Arg::Str(objName); status << Arg::Gds(isc_dyn_filter_not_found) << Arg::Str(objNameStr);
break; break;
case obj_exception: case obj_exception:
tableClause = "rdb$exceptions"; tableClause = "rdb$exceptions";
columnClause = "rdb$exception_name"; columnClause = "rdb$exception_name";
status << Arg::Gds(isc_dyn_exception_not_found) << Arg::Str(objName); status << Arg::Gds(isc_dyn_exception_not_found) << Arg::Str(objNameStr);
break; break;
case obj_generator: case obj_generator:
tableClause = "rdb$generators"; tableClause = "rdb$generators";
columnClause = "rdb$generator_name"; columnClause = "rdb$generator_name";
status << Arg::Gds(isc_dyn_gen_not_found) << Arg::Str(objName); status << Arg::Gds(isc_dyn_gen_not_found) << Arg::Str(objNameStr);
break; break;
case obj_index: case obj_index:
tableClause = "rdb$indices"; tableClause = "rdb$indices";
columnClause = "rdb$index_name"; columnClause = "rdb$index_name";
status << Arg::Gds(isc_dyn_index_not_found) << Arg::Str(objName); status << Arg::Gds(isc_dyn_index_not_found) << Arg::Str(objNameStr);
break; break;
case obj_sql_role: case obj_sql_role:
tableClause = "rdb$roles"; tableClause = "rdb$roles";
columnClause = "rdb$role_name"; columnClause = "rdb$role_name";
status << Arg::Gds(isc_dyn_role_not_found) << Arg::Str(objName); status << Arg::Gds(isc_dyn_role_not_found) << Arg::Str(objNameStr);
break; break;
case obj_charset: case obj_charset:
tableClause = "rdb$character_sets"; tableClause = "rdb$character_sets";
columnClause = "rdb$character_set_name"; columnClause = "rdb$character_set_name";
status << Arg::Gds(isc_dyn_charset_not_found) << Arg::Str(objName); status << Arg::Gds(isc_dyn_charset_not_found) << Arg::Str(objNameStr);
break; break;
case obj_collation: case obj_collation:
tableClause = "rdb$collations"; tableClause = "rdb$collations";
columnClause = "rdb$collation_name"; columnClause = "rdb$collation_name";
status << Arg::Gds(isc_dyn_collation_not_found) << Arg::Str(objName); status << Arg::Gds(isc_dyn_collation_not_found) << Arg::Str(objNameStr);
break; break;
case obj_package_header: case obj_package_header:
tableClause = "rdb$packages"; tableClause = "rdb$packages";
columnClause = "rdb$package_name"; columnClause = "rdb$package_name";
status << Arg::Gds(isc_dyn_package_not_found) << Arg::Str(objName); status << Arg::Gds(isc_dyn_package_not_found) << Arg::Str(objNameStr);
break; break;
case obj_schema: case obj_schema:
tableClause = "rdb$schemas"; tableClause = "rdb$schemas";
columnClause = "rdb$schema_name"; columnClause = "rdb$schema_name";
status << Arg::Gds(isc_dyn_schema_not_found) << Arg::Str(objName); status << Arg::Gds(isc_dyn_schema_not_found) << Arg::Str(objNameStr);
break; break;
default: default:
@ -1271,16 +1267,19 @@ void CommentOnNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
description = text; description = text;
PreparedStatement::Builder sql; PreparedStatement::Builder sql;
sql << "update" << tableClause << "set rdb$description =" << description; sql << "update" << tableClause << "set rdb$description =" << description << "where 1 = 1";
if (columnClause) if (columnClause)
{ {
sql << "where" << columnClause << "=" << objName; sql << "and" << columnClause << "=" << objName.identifier;
if (subColumnClause) if (subColumnClause)
sql << "and" << subColumnClause << "=" << subName; sql << "and" << subColumnClause << "=" << subName;
} }
if (objType == obj_procedure || objType == obj_udf)
sql << "and rdb$package_name is not distinct from nullif(" << objName.package << ", '')";
if (addWhereClause) if (addWhereClause)
sql << "and" << addWhereClause; sql << "and" << addWhereClause;

View File

@ -220,7 +220,7 @@ class CommentOnNode : public DdlNode
{ {
public: public:
CommentOnNode(MemoryPool& pool, int aObjType, CommentOnNode(MemoryPool& pool, int aObjType,
const Firebird::MetaName& aObjName, const Firebird::MetaName& aSubName, const Firebird::QualifiedName& aObjName, const Firebird::MetaName& aSubName,
const Firebird::string aText) const Firebird::string aText)
: DdlNode(pool), : DdlNode(pool),
objType(aObjType), objType(aObjType),
@ -238,18 +238,21 @@ public:
protected: protected:
virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector)
{ {
/*** ASF: FIXME: When returning, str is destroyed but its pointer is recorded. Firebird::string str(objName.toString());
Firebird::string str(objName.c_str());
if (subName.hasData()) if (subName.hasData())
str.append(".").append(subName.c_str()); str.append(".").append(subName.c_str());
statusVector << Firebird::Arg::Gds(isc_dsql_comment_on_failed) << str;
***/ //// ASF: What a hack, as StatusVector does not save the pointer content!
statusVector << Firebird::Arg::Gds(isc_dsql_comment_on_failed) << objName; const char* p = Firebird::MasterInterfacePtr()->circularAlloc(str.c_str(), str.length(),
(intptr_t) getThreadId());
statusVector << Firebird::Arg::Gds(isc_dsql_comment_on_failed) << p;
} }
private: private:
int objType; int objType;
Firebird::MetaName objName; Firebird::QualifiedName objName;
Firebird::MetaName subName; Firebird::MetaName subName;
Firebird::string text; Firebird::string text;
}; };

View File

@ -619,6 +619,7 @@ using namespace Firebird;
Firebird::MetaName* metaNamePtr; Firebird::MetaName* metaNamePtr;
Firebird::ObjectsArray<Firebird::MetaName>* metaNameArray; Firebird::ObjectsArray<Firebird::MetaName>* metaNameArray;
Firebird::PathName* pathNamePtr; Firebird::PathName* pathNamePtr;
Firebird::QualifiedName* qualifiedNamePtr;
Firebird::string* stringPtr; Firebird::string* stringPtr;
Jrd::IntlString* intlStringPtr; Jrd::IntlString* intlStringPtr;
Jrd::DbFileClause* dbFileClause; Jrd::DbFileClause* dbFileClause;
@ -4723,11 +4724,15 @@ set_statistics
%type <ddlNode> comment %type <ddlNode> comment
comment comment
: COMMENT ON ddl_type0 IS ddl_desc : COMMENT ON ddl_type0 IS ddl_desc
{ $$ = newNode<CommentOnNode>($3, "", "", *$5); } { $$ = newNode<CommentOnNode>($3, QualifiedName(""), "", *$5); }
| COMMENT ON ddl_type1 symbol_ddl_name IS ddl_desc | COMMENT ON ddl_type1 symbol_ddl_name IS ddl_desc
{ $$ = newNode<CommentOnNode>($3, *$4, "", *$6); } { $$ = newNode<CommentOnNode>($3, QualifiedName(*$4), "", *$6); }
| COMMENT ON ddl_type2 symbol_ddl_name ddl_subname IS ddl_desc | COMMENT ON ddl_type2 symbol_ddl_name ddl_subname IS ddl_desc
{ $$ = newNode<CommentOnNode>($3, QualifiedName(*$4), *$5, *$7); }
| COMMENT ON ddl_type3 ddl_qualified_name ddl_subname IS ddl_desc
{ $$ = newNode<CommentOnNode>($3, *$4, *$5, *$7); } { $$ = newNode<CommentOnNode>($3, *$4, *$5, *$7); }
| COMMENT ON ddl_type4 ddl_qualified_name IS ddl_desc
{ $$ = newNode<CommentOnNode>($3, *$4, "", *$6); }
| COMMENT ON USER symbol_user_name IS ddl_desc | COMMENT ON USER symbol_user_name IS ddl_desc
{ {
CreateAlterUserNode* node = CreateAlterUserNode* node =
@ -4748,10 +4753,7 @@ ddl_type1
: KW_DOMAIN { $$ = obj_field; } : KW_DOMAIN { $$ = obj_field; }
| TABLE { $$ = obj_relation; } | TABLE { $$ = obj_relation; }
| VIEW { $$ = obj_view; } | VIEW { $$ = obj_view; }
| PROCEDURE { $$ = obj_procedure; }
| TRIGGER { $$ = obj_trigger; } | TRIGGER { $$ = obj_trigger; }
| EXTERNAL FUNCTION { $$ = obj_udf; }
| FUNCTION { $$ = obj_udf; }
| FILTER { $$ = obj_blob_filter; } | FILTER { $$ = obj_blob_filter; }
| EXCEPTION { $$ = obj_exception; } | EXCEPTION { $$ = obj_exception; }
| GENERATOR { $$ = obj_generator; } | GENERATOR { $$ = obj_generator; }
@ -4769,13 +4771,19 @@ ddl_type1
%type <intVal> ddl_type2 %type <intVal> ddl_type2
ddl_type2 ddl_type2
: COLUMN { $$ = obj_relation; } : COLUMN { $$ = obj_relation; }
| ddl_param_opt PARAMETER { $$ = $1; }
; ;
%type <intVal> ddl_param_opt %type <intVal> ddl_type3
ddl_param_opt ddl_type3
: { $$ = obj_parameter; } : PARAMETER { $$ = obj_parameter; }
| PROCEDURE { $$ = obj_procedure; } | PROCEDURE PARAMETER { $$ = obj_procedure; }
| FUNCTION PARAMETER { $$ = obj_udf; }
;
%type <intVal> ddl_type4
ddl_type4
: PROCEDURE { $$ = obj_procedure; }
| EXTERNAL FUNCTION { $$ = obj_udf; }
| FUNCTION { $$ = obj_udf; } | FUNCTION { $$ = obj_udf; }
; ;
@ -4784,6 +4792,18 @@ ddl_subname
: '.' symbol_ddl_name { $$ = $2; } : '.' symbol_ddl_name { $$ = $2; }
; ;
%type <metaNamePtr> ddl_subname_opt
ddl_subname_opt
: /* nothing */ { $$ = NULL; }
| ddl_subname
;
%type <qualifiedNamePtr> ddl_qualified_name
ddl_qualified_name
: symbol_ddl_name { $$ = newNode<QualifiedName>(*$1); }
| symbol_ddl_name '.' symbol_ddl_name { $$ = newNode<QualifiedName>(*$3, *$1); }
;
%type <stringPtr> ddl_desc %type <stringPtr> ddl_desc
ddl_desc ddl_desc
: utf_string { $$ = $1; } : utf_string { $$ = $1; }

View File

@ -85,7 +85,7 @@ static processing_state show_all_tables(SSHORT);
static void show_charsets(const SCHAR*, const SCHAR*, const bool, bool, bool, bool); static void show_charsets(const SCHAR*, const SCHAR*, const bool, bool, bool, bool);
static processing_state show_check(const SCHAR*); static processing_state show_check(const SCHAR*);
static processing_state show_collations(const SCHAR*, SSHORT sys_flag, const char* msg = 0, bool compact = false); static processing_state show_collations(const SCHAR*, SSHORT sys_flag, const char* msg = 0, bool compact = false);
static void show_comment(const char* objtype, char* name1, char* name2, static void show_comment(const char* objtype, char* packageName, char* name1, char* name2,
ISC_QUAD* blobfld, const commentMode showextract, const char* banner); ISC_QUAD* blobfld, const commentMode showextract, const char* banner);
static processing_state show_comments(const commentMode showextract, const char* banner); static processing_state show_comments(const commentMode showextract, const char* banner);
static void show_db(); static void show_db();
@ -2668,7 +2668,7 @@ static processing_state show_collations(const SCHAR* object, SSHORT sys_flag, co
// Helper that displays in correct syntax the COMMENT ON command for each object. // Helper that displays in correct syntax the COMMENT ON command for each object.
// It escapes identifiers with embedded double quotes and escapes the comment // It escapes identifiers with embedded double quotes and escapes the comment
// itself if it contains single quotes when we are honoring script extraction. // itself if it contains single quotes when we are honoring script extraction.
static void show_comment(const char* objtype, char* name1, char* name2, static void show_comment(const char* objtype, char* packageName, char* name1, char* name2,
ISC_QUAD* blobfld, const commentMode showextract, const char* banner) ISC_QUAD* blobfld, const commentMode showextract, const char* banner)
{ {
const bool escape_quotes = showextract == cmmExtract; const bool escape_quotes = showextract == cmmExtract;
@ -2676,19 +2676,30 @@ static void show_comment(const char* objtype, char* name1, char* name2,
if (escape_quotes && banner) if (escape_quotes && banner)
isqlGlob.prints(banner); isqlGlob.prints(banner);
if (packageName)
fb_utils::exact_name(packageName);
if (name1) if (name1)
fb_utils::exact_name(name1); fb_utils::exact_name(name1);
if (name2) if (name2)
fb_utils::exact_name(name2); fb_utils::exact_name(name2);
char packageNameBuffer[BUFFER_LENGTH128];
char SQL_identifier2[BUFFER_LENGTH128]; char SQL_identifier2[BUFFER_LENGTH128];
if (escape_quotes && isqlGlob.db_SQL_dialect > SQL_DIALECT_V6_TRANSITION) if (escape_quotes && isqlGlob.db_SQL_dialect > SQL_DIALECT_V6_TRANSITION)
{ {
if (packageName)
{
IUTILS_copy_SQL_id (packageName, packageNameBuffer, DBL_QUOTE);
packageName = packageNameBuffer;
}
if (name1) if (name1)
{ {
IUTILS_copy_SQL_id (name1, SQL_identifier, DBL_QUOTE); IUTILS_copy_SQL_id (name1, SQL_identifier, DBL_QUOTE);
name1 = SQL_identifier; name1 = SQL_identifier;
} }
if (name2) if (name2)
{ {
IUTILS_copy_SQL_id (name2, SQL_identifier2, DBL_QUOTE); IUTILS_copy_SQL_id (name2, SQL_identifier2, DBL_QUOTE);
@ -2698,12 +2709,21 @@ static void show_comment(const char* objtype, char* name1, char* name2,
const char* quot = escape_quotes ? "'" : ""; const char* quot = escape_quotes ? "'" : "";
if (!name1) isqlGlob.printf("COMMENT ON %-12s", objtype);
isqlGlob.printf("COMMENT ON %-12s IS %s", objtype, quot);
else if (!name2) if (packageName || name1 || name2)
isqlGlob.printf("COMMENT ON %-12s %s IS %s", objtype, name1, quot); isqlGlob.printf(" ");
else
isqlGlob.printf("COMMENT ON %-12s %s.%s IS %s", objtype, name1, name2, quot); if (packageName)
isqlGlob.printf("%s.", packageName);
if (name1)
isqlGlob.printf("%s", name1);
if (name2)
isqlGlob.printf(".%s", name2);
isqlGlob.printf(" IS %s", quot);
SHOW_print_metadata_text_blob(isqlGlob.Out, blobfld, escape_quotes); SHOW_print_metadata_text_blob(isqlGlob.Out, blobfld, escape_quotes);
isqlGlob.printf("%s%s%s", quot, isqlGlob.global_Term, NEWLINE); isqlGlob.printf("%s%s%s", quot, isqlGlob.global_Term, NEWLINE);
@ -2740,7 +2760,7 @@ static processing_state show_comments(const commentMode showextract, const char*
FOR FIRST 1 DT IN RDB$DATABASE FOR FIRST 1 DT IN RDB$DATABASE
WITH DT.RDB$DESCRIPTION NOT MISSING WITH DT.RDB$DESCRIPTION NOT MISSING
show_comment("DATABASE", 0, 0, &DT.RDB$DESCRIPTION, showextract, first ? banner : 0); show_comment("DATABASE", NULL, NULL, NULL, &DT.RDB$DESCRIPTION, showextract, first ? banner : 0);
first = false; first = false;
END_FOR END_FOR
ON_ERROR ON_ERROR
@ -2754,7 +2774,7 @@ static processing_state show_comments(const commentMode showextract, const char*
AND DM.RDB$DESCRIPTION NOT MISSING AND DM.RDB$DESCRIPTION NOT MISSING
SORTED BY DM.RDB$FIELD_NAME SORTED BY DM.RDB$FIELD_NAME
show_comment("DOMAIN", DM.RDB$FIELD_NAME, 0, &DM.RDB$DESCRIPTION, show_comment("DOMAIN", NULL, DM.RDB$FIELD_NAME, NULL, &DM.RDB$DESCRIPTION,
showextract, first ? banner : 0); showextract, first ? banner : 0);
first = false; first = false;
END_FOR END_FOR
@ -2770,7 +2790,7 @@ static processing_state show_comments(const commentMode showextract, const char*
if (!RL.RDB$DESCRIPTION.NULL && !UserBlob::blobIsNull(RL.RDB$DESCRIPTION)) if (!RL.RDB$DESCRIPTION.NULL && !UserBlob::blobIsNull(RL.RDB$DESCRIPTION))
{ {
show_comment("TABLE", RL.RDB$RELATION_NAME, 0, &RL.RDB$DESCRIPTION, show_comment("TABLE", NULL, RL.RDB$RELATION_NAME, NULL, &RL.RDB$DESCRIPTION,
showextract, first ? banner : 0); showextract, first ? banner : 0);
first = false; first = false;
} }
@ -2780,7 +2800,7 @@ static processing_state show_comments(const commentMode showextract, const char*
AND RF.RDB$DESCRIPTION NOT MISSING AND RF.RDB$DESCRIPTION NOT MISSING
SORTED BY RF.RDB$FIELD_POSITION SORTED BY RF.RDB$FIELD_POSITION
show_comment(" COLUMN", RL.RDB$RELATION_NAME, RF.RDB$FIELD_NAME, show_comment(" COLUMN", NULL, RL.RDB$RELATION_NAME, RF.RDB$FIELD_NAME,
&RF.RDB$DESCRIPTION, showextract, first ? banner : 0); &RF.RDB$DESCRIPTION, showextract, first ? banner : 0);
first = false; first = false;
END_FOR END_FOR
@ -2802,7 +2822,7 @@ static processing_state show_comments(const commentMode showextract, const char*
if (!VW.RDB$DESCRIPTION.NULL && !UserBlob::blobIsNull(VW.RDB$DESCRIPTION)) if (!VW.RDB$DESCRIPTION.NULL && !UserBlob::blobIsNull(VW.RDB$DESCRIPTION))
{ {
show_comment("VIEW", VW.RDB$RELATION_NAME, 0 , &VW.RDB$DESCRIPTION, show_comment("VIEW", NULL, VW.RDB$RELATION_NAME, NULL, &VW.RDB$DESCRIPTION,
showextract, first ? banner : 0); showextract, first ? banner : 0);
first = false; first = false;
} }
@ -2812,7 +2832,7 @@ static processing_state show_comments(const commentMode showextract, const char*
AND RF.RDB$DESCRIPTION NOT MISSING AND RF.RDB$DESCRIPTION NOT MISSING
SORTED BY RF.RDB$FIELD_POSITION SORTED BY RF.RDB$FIELD_POSITION
show_comment(" COLUMN", VW.RDB$RELATION_NAME, RF.RDB$FIELD_NAME, show_comment(" COLUMN", NULL, VW.RDB$RELATION_NAME, RF.RDB$FIELD_NAME,
&RF.RDB$DESCRIPTION, showextract, first ? banner : 0); &RF.RDB$DESCRIPTION, showextract, first ? banner : 0);
first = false; first = false;
END_FOR END_FOR
@ -2829,24 +2849,24 @@ static processing_state show_comments(const commentMode showextract, const char*
FOR PR IN RDB$PROCEDURES FOR PR IN RDB$PROCEDURES
WITH (PR.RDB$SYSTEM_FLAG EQ 0 OR PR.RDB$SYSTEM_FLAG MISSING) WITH (PR.RDB$SYSTEM_FLAG EQ 0 OR PR.RDB$SYSTEM_FLAG MISSING)
AND PR.RDB$PACKAGE_NAME MISSING
SORTED BY PR.RDB$PROCEDURE_NAME SORTED BY PR.RDB$PROCEDURE_NAME
if (!PR.RDB$DESCRIPTION.NULL && !UserBlob::blobIsNull(PR.RDB$DESCRIPTION)) if (!PR.RDB$DESCRIPTION.NULL && !UserBlob::blobIsNull(PR.RDB$DESCRIPTION))
{ {
show_comment("PROCEDURE", PR.RDB$PROCEDURE_NAME, 0, &PR.RDB$DESCRIPTION, show_comment("PROCEDURE", (PR.RDB$PACKAGE_NAME.NULL ? NULL : PR.RDB$PACKAGE_NAME),
showextract, first ? banner : 0); PR.RDB$PROCEDURE_NAME, NULL, &PR.RDB$DESCRIPTION, showextract, first ? banner : 0);
first = false; first = false;
} }
FOR PA IN RDB$PROCEDURE_PARAMETERS FOR PA IN RDB$PROCEDURE_PARAMETERS
WITH PA.RDB$PROCEDURE_NAME = PR.RDB$PROCEDURE_NAME WITH PA.RDB$PROCEDURE_NAME = PR.RDB$PROCEDURE_NAME
AND PA.RDB$PACKAGE_NAME MISSING AND PA.RDB$PACKAGE_NAME EQUIV NULLIF(PR.RDB$PACKAGE_NAME, '')
AND PA.RDB$DESCRIPTION NOT MISSING AND PA.RDB$DESCRIPTION NOT MISSING
SORTED BY PA.RDB$PARAMETER_TYPE, PA.RDB$PARAMETER_NUMBER SORTED BY PA.RDB$PARAMETER_TYPE, PA.RDB$PARAMETER_NUMBER
show_comment(" PARAMETER", PR.RDB$PROCEDURE_NAME, PA.RDB$PARAMETER_NAME, show_comment(" PROCEDURE PARAMETER",
&PA.RDB$DESCRIPTION, showextract, first ? banner : 0); (PR.RDB$PACKAGE_NAME.NULL ? NULL : PR.RDB$PACKAGE_NAME), PR.RDB$PROCEDURE_NAME,
PA.RDB$PARAMETER_NAME, &PA.RDB$DESCRIPTION, showextract, first ? banner : 0);
first = false; first = false;
END_FOR END_FOR
ON_ERROR ON_ERROR
@ -2865,7 +2885,7 @@ static processing_state show_comments(const commentMode showextract, const char*
AND (TR.RDB$SYSTEM_FLAG EQ 0 OR TR.RDB$SYSTEM_FLAG MISSING) AND (TR.RDB$SYSTEM_FLAG EQ 0 OR TR.RDB$SYSTEM_FLAG MISSING)
SORTED BY TR.RDB$TRIGGER_NAME SORTED BY TR.RDB$TRIGGER_NAME
show_comment("TRIGGER", TR.RDB$TRIGGER_NAME, 0, &TR.RDB$DESCRIPTION, show_comment("TRIGGER", NULL, TR.RDB$TRIGGER_NAME, NULL, &TR.RDB$DESCRIPTION,
showextract, first ? banner : 0); showextract, first ? banner : 0);
first = false; first = false;
END_FOR END_FOR
@ -2877,7 +2897,6 @@ static processing_state show_comments(const commentMode showextract, const char*
FOR UD IN RDB$FUNCTIONS FOR UD IN RDB$FUNCTIONS
WITH UD.RDB$DESCRIPTION NOT MISSING WITH UD.RDB$DESCRIPTION NOT MISSING
AND (UD.RDB$SYSTEM_FLAG EQ 0 OR UD.RDB$SYSTEM_FLAG MISSING) AND (UD.RDB$SYSTEM_FLAG EQ 0 OR UD.RDB$SYSTEM_FLAG MISSING)
AND UD.RDB$PACKAGE_NAME MISSING
SORTED BY UD.RDB$FUNCTION_NAME SORTED BY UD.RDB$FUNCTION_NAME
// Avoid syntax error when extracting scripts due to an historical bug in gbak. // Avoid syntax error when extracting scripts due to an historical bug in gbak.
@ -2885,9 +2904,26 @@ static processing_state show_comments(const commentMode showextract, const char*
if (UserBlob::blobIsNull(UD.RDB$DESCRIPTION)) if (UserBlob::blobIsNull(UD.RDB$DESCRIPTION))
continue; continue;
show_comment("EXTERNAL FUNCTION", UD.RDB$FUNCTION_NAME, 0, show_comment("FUNCTION",
(UD.RDB$PACKAGE_NAME.NULL ? NULL : UD.RDB$PACKAGE_NAME), UD.RDB$FUNCTION_NAME, NULL,
&UD.RDB$DESCRIPTION, showextract, first ? banner : 0); &UD.RDB$DESCRIPTION, showextract, first ? banner : 0);
first = false; first = false;
FOR ARG IN RDB$FUNCTION_ARGUMENTS
WITH ARG.RDB$FUNCTION_NAME = UD.RDB$FUNCTION_NAME
AND ARG.RDB$PACKAGE_NAME EQUIV NULLIF(UD.RDB$PACKAGE_NAME, '')
AND ARG.RDB$DESCRIPTION NOT MISSING
SORTED BY ARG.RDB$ARGUMENT_POSITION
show_comment(" FUNCTION PARAMETER",
(ARG.RDB$PACKAGE_NAME.NULL ? NULL : ARG.RDB$PACKAGE_NAME), ARG.RDB$FUNCTION_NAME,
ARG.RDB$ARGUMENT_NAME, &ARG.RDB$DESCRIPTION, showextract, first ? banner : 0);
first = false;
END_FOR
ON_ERROR
ISQL_errmsg(fbStatus);
return ps_ERR;
END_ERROR
END_FOR END_FOR
ON_ERROR ON_ERROR
ISQL_errmsg(fbStatus); ISQL_errmsg(fbStatus);
@ -2899,7 +2935,7 @@ static processing_state show_comments(const commentMode showextract, const char*
AND (BF.RDB$SYSTEM_FLAG EQ 0 OR BF.RDB$SYSTEM_FLAG MISSING) AND (BF.RDB$SYSTEM_FLAG EQ 0 OR BF.RDB$SYSTEM_FLAG MISSING)
SORTED BY BF.RDB$FUNCTION_NAME SORTED BY BF.RDB$FUNCTION_NAME
show_comment("FILTER", BF.RDB$FUNCTION_NAME, 0, &BF.RDB$DESCRIPTION, show_comment("FILTER", NULL, BF.RDB$FUNCTION_NAME, NULL, &BF.RDB$DESCRIPTION,
showextract, first ? banner : 0); showextract, first ? banner : 0);
first = false; first = false;
END_FOR END_FOR
@ -2913,7 +2949,7 @@ static processing_state show_comments(const commentMode showextract, const char*
AND (XC.RDB$SYSTEM_FLAG EQ 0 OR XC.RDB$SYSTEM_FLAG MISSING) AND (XC.RDB$SYSTEM_FLAG EQ 0 OR XC.RDB$SYSTEM_FLAG MISSING)
SORTED BY XC.RDB$EXCEPTION_NAME SORTED BY XC.RDB$EXCEPTION_NAME
show_comment("EXCEPTION", XC.RDB$EXCEPTION_NAME, 0, &XC.RDB$DESCRIPTION, show_comment("EXCEPTION", NULL, XC.RDB$EXCEPTION_NAME, NULL, &XC.RDB$DESCRIPTION,
showextract, first ? banner : 0); showextract, first ? banner : 0);
first = false; first = false;
END_FOR END_FOR
@ -2929,7 +2965,7 @@ static processing_state show_comments(const commentMode showextract, const char*
AND (GR.RDB$SYSTEM_FLAG EQ 0 OR GR.RDB$SYSTEM_FLAG MISSING) AND (GR.RDB$SYSTEM_FLAG EQ 0 OR GR.RDB$SYSTEM_FLAG MISSING)
SORTED BY GR.RDB$GENERATOR_NAME SORTED BY GR.RDB$GENERATOR_NAME
show_comment("GENERATOR", GR.RDB$GENERATOR_NAME, 0, &GR.RDB$DESCRIPTION, show_comment("GENERATOR", NULL, GR.RDB$GENERATOR_NAME, NULL, &GR.RDB$DESCRIPTION,
showextract, first ? banner : 0); showextract, first ? banner : 0);
first = false; first = false;
END_FOR END_FOR
@ -2944,7 +2980,7 @@ static processing_state show_comments(const commentMode showextract, const char*
AND (IX.RDB$SYSTEM_FLAG EQ 0 OR IX.RDB$SYSTEM_FLAG MISSING) AND (IX.RDB$SYSTEM_FLAG EQ 0 OR IX.RDB$SYSTEM_FLAG MISSING)
SORTED BY IX.RDB$INDEX_NAME SORTED BY IX.RDB$INDEX_NAME
show_comment("INDEX", IX.RDB$INDEX_NAME, 0, &IX.RDB$DESCRIPTION, show_comment("INDEX", NULL, IX.RDB$INDEX_NAME, NULL, &IX.RDB$DESCRIPTION,
showextract, first ? banner : 0); showextract, first ? banner : 0);
first = false; first = false;
END_FOR END_FOR
@ -2960,7 +2996,7 @@ static processing_state show_comments(const commentMode showextract, const char*
AND (RO.RDB$SYSTEM_FLAG EQ 0 OR RO.RDB$SYSTEM_FLAG MISSING) AND (RO.RDB$SYSTEM_FLAG EQ 0 OR RO.RDB$SYSTEM_FLAG MISSING)
SORTED BY RO.RDB$ROLE_NAME SORTED BY RO.RDB$ROLE_NAME
show_comment("ROLE", RO.RDB$ROLE_NAME, 0, &RO.RDB$DESCRIPTION, show_comment("ROLE", NULL, RO.RDB$ROLE_NAME, NULL, &RO.RDB$DESCRIPTION,
showextract, first ? banner : 0); showextract, first ? banner : 0);
first = false; first = false;
END_FOR END_FOR
@ -2977,7 +3013,7 @@ static processing_state show_comments(const commentMode showextract, const char*
AND (PACK.RDB$SYSTEM_FLAG EQ 0 OR PACK.RDB$SYSTEM_FLAG MISSING) AND (PACK.RDB$SYSTEM_FLAG EQ 0 OR PACK.RDB$SYSTEM_FLAG MISSING)
SORTED BY PACK.RDB$PACKAGE_NAME SORTED BY PACK.RDB$PACKAGE_NAME
show_comment("PACKAGE", PACK.RDB$PACKAGE_NAME, 0, &PACK.RDB$DESCRIPTION, show_comment("PACKAGE", NULL, PACK.RDB$PACKAGE_NAME, NULL, &PACK.RDB$DESCRIPTION,
showextract, first ? banner : 0); showextract, first ? banner : 0);
first = false; first = false;
END_FOR END_FOR
@ -2992,7 +3028,7 @@ static processing_state show_comments(const commentMode showextract, const char*
AND (CH.RDB$SYSTEM_FLAG EQ 0 OR CH.RDB$SYSTEM_FLAG MISSING) AND (CH.RDB$SYSTEM_FLAG EQ 0 OR CH.RDB$SYSTEM_FLAG MISSING)
SORTED BY CH.RDB$CHARACTER_SET_NAME SORTED BY CH.RDB$CHARACTER_SET_NAME
show_comment("CHARACTER SET", CH.RDB$CHARACTER_SET_NAME, 0, show_comment("CHARACTER SET", NULL, CH.RDB$CHARACTER_SET_NAME, NULL,
&CH.RDB$DESCRIPTION, showextract, first ? banner : 0); &CH.RDB$DESCRIPTION, showextract, first ? banner : 0);
first = false; first = false;
END_FOR END_FOR
@ -3006,7 +3042,7 @@ static processing_state show_comments(const commentMode showextract, const char*
AND (CL.RDB$SYSTEM_FLAG EQ 0 OR CL.RDB$SYSTEM_FLAG MISSING) AND (CL.RDB$SYSTEM_FLAG EQ 0 OR CL.RDB$SYSTEM_FLAG MISSING)
SORTED BY CL.RDB$COLLATION_NAME SORTED BY CL.RDB$COLLATION_NAME
show_comment("COLLATION", CL.RDB$COLLATION_NAME, 0, &CL.RDB$DESCRIPTION, show_comment("COLLATION", NULL, CL.RDB$COLLATION_NAME, NULL, &CL.RDB$DESCRIPTION,
showextract, first ? banner : 0); showextract, first ? banner : 0);
first = false; first = false;
END_FOR END_FOR