2001-05-23 15:26:42 +02:00
|
|
|
/*
|
|
|
|
* PROGRAM: Interactive SQL utility
|
2003-09-29 14:43:14 +02:00
|
|
|
* MODULE: show.epp
|
2001-05-23 15:26:42 +02:00
|
|
|
* DESCRIPTION: Display routines
|
|
|
|
*
|
|
|
|
* The contents of this file are subject to the Interbase Public
|
|
|
|
* License Version 1.0 (the "License"); you may not use this file
|
|
|
|
* except in compliance with the License. You may obtain a copy
|
|
|
|
* of the License at http://www.Inprise.com/IPL.html
|
|
|
|
*
|
|
|
|
* Software distributed under the License is distributed on an
|
|
|
|
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
|
|
|
|
* or implied. See the License for the specific language governing
|
|
|
|
* rights and limitations under the License.
|
|
|
|
*
|
|
|
|
* The Original Code was created by Inprise Corporation
|
|
|
|
* and its predecessors. Portions created by Inprise Corporation are
|
|
|
|
* Copyright (C) Inprise Corporation.
|
|
|
|
*
|
|
|
|
* All Rights Reserved.
|
|
|
|
* Contributor(s): ______________________________________.
|
|
|
|
* Revision 1.2 2000/11/19 07:02:49 fsg
|
2004-11-30 07:08:56 +01:00
|
|
|
* Change in show.epp to use CHARACTER_LENGTH instead of FIELD_LENGTH in
|
2001-05-23 15:26:42 +02:00
|
|
|
* SHOW PROCEDURE
|
|
|
|
*
|
|
|
|
* 19-May-2001 Claudio Valderrama.
|
|
|
|
* Change to be in sync with extract.e: BLOB is not returned
|
|
|
|
* by value but by descriptor.
|
2002-06-29 15:39:11 +02:00
|
|
|
* 2001.09.21 Claudio Valderrama: Show correct mechanism for UDF parameters.
|
|
|
|
* 2001.10.01 Claudio Valderrama: SHOW GRANTS works without any argument, too.
|
|
|
|
* Metadata extraction is slightly faster if SHOW_grants() knows the obj_type.
|
|
|
|
* Keyword USER is written when the grantee is a user and since the engine
|
|
|
|
* now supports GRANT...to ROLE role_name, ROLE is written when the grantee is
|
|
|
|
* indeed a role. When the grantee is a group, it's shown, too.
|
2003-02-04 16:36:46 +01:00
|
|
|
* 2003.02.04 Dmitry Yemanov: support for universal triggers
|
2001-05-23 15:26:42 +02:00
|
|
|
*/
|
|
|
|
|
2001-07-30 01:43:24 +02:00
|
|
|
#include "firebird.h"
|
2004-04-29 00:36:29 +02:00
|
|
|
#include <stdio.h>
|
2002-06-29 15:39:11 +02:00
|
|
|
#include "../jrd/license.h"
|
2001-05-23 15:26:42 +02:00
|
|
|
#include <string.h>
|
|
|
|
|
2004-04-24 23:43:35 +02:00
|
|
|
#include "../jrd/gds_proto.h"
|
2001-05-23 15:26:42 +02:00
|
|
|
#include "../jrd/common.h"
|
2003-11-08 17:40:17 +01:00
|
|
|
#include "../jrd/ibase.h"
|
2001-05-23 15:26:42 +02:00
|
|
|
#include "../isql/isql.h"
|
|
|
|
#include "../jrd/intl.h"
|
|
|
|
#include "../isql/isql_proto.h"
|
|
|
|
#include "../isql/show_proto.h"
|
|
|
|
#include "../jrd/obj.h"
|
|
|
|
#include "../jrd/ods.h"
|
2002-06-29 15:39:11 +02:00
|
|
|
#include "../isql/extra_proto.h"
|
2003-12-31 06:36:12 +01:00
|
|
|
#include "../common/utils_proto.h"
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2001-07-12 08:32:05 +02:00
|
|
|
#ifdef HAVE_CTYPE_H
|
|
|
|
#include <ctype.h>
|
|
|
|
#endif
|
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
DATABASE DB = EXTERN COMPILETIME "yachts.lnk";
|
|
|
|
|
2005-05-20 10:34:19 +02:00
|
|
|
|
|
|
|
// This enumeration tell comment-related routines how to behave: for SHOW,
|
|
|
|
// we present names and text as they are. For EXTRACT, we need to make a valid
|
|
|
|
// script and escape double quotes in identifiers and single quotes in strings.
|
|
|
|
enum commentMode {cmmShow, cmmExtract};
|
|
|
|
|
|
|
|
|
2003-12-22 11:00:59 +01:00
|
|
|
static void local_fprintf(void*, const char*);
|
2003-09-29 14:43:14 +02:00
|
|
|
static void remove_delimited_double_quotes(TEXT*);
|
2003-11-30 07:41:29 +01:00
|
|
|
static void make_priv_string(USHORT, char*);
|
2003-12-03 09:19:24 +01:00
|
|
|
static processing_state show_all_tables(SSHORT);
|
2004-04-23 20:39:04 +02:00
|
|
|
static void show_charsets(const SCHAR*, const SCHAR*, const bool, bool, bool, bool);
|
2003-12-03 09:19:24 +01:00
|
|
|
static processing_state show_check(const SCHAR*);
|
2005-05-19 10:03:10 +02:00
|
|
|
static void show_comment(const char* objtype, char* name1, char* name2,
|
2005-05-20 10:34:19 +02:00
|
|
|
ISC_QUAD* blobfld, const commentMode showextract, const char* banner);
|
|
|
|
static processing_state show_comments(const commentMode showextract, const char* banner);
|
2003-11-30 07:41:29 +01:00
|
|
|
static void show_db();
|
2003-12-03 09:19:24 +01:00
|
|
|
static processing_state show_dialect();
|
|
|
|
static processing_state show_domains(const SCHAR*);
|
|
|
|
static processing_state show_exceptions(const SCHAR*);
|
|
|
|
static processing_state show_filters(const SCHAR*);
|
2005-01-04 06:42:26 +01:00
|
|
|
static processing_state show_functions(const SCHAR*, const SSHORT = 0);
|
2003-12-03 09:19:24 +01:00
|
|
|
static processing_state show_generators(const SCHAR*);
|
2003-09-29 14:43:14 +02:00
|
|
|
static void show_index(SCHAR*, SCHAR*, const SSHORT, const SSHORT, const SSHORT);
|
2003-12-03 09:19:24 +01:00
|
|
|
static processing_state show_indices(const SCHAR* const*);
|
|
|
|
static processing_state show_proc(const SCHAR*);
|
|
|
|
static processing_state show_role(const SCHAR*);
|
2004-04-23 20:39:04 +02:00
|
|
|
static processing_state show_table(const SCHAR*, bool);
|
|
|
|
static processing_state show_trigger(const SCHAR*, bool, bool);
|
|
|
|
const char* spaces = " ";
|
2001-05-23 15:26:42 +02:00
|
|
|
static TEXT Print_buffer[512];
|
|
|
|
static TEXT SQL_identifier[BUFFER_LENGTH128];
|
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
// Initialize types
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-09-29 14:43:14 +02:00
|
|
|
static const SCHAR* Object_types[] = {
|
2001-05-23 15:26:42 +02:00
|
|
|
"Table",
|
|
|
|
"View",
|
|
|
|
"Trigger",
|
|
|
|
"Computed column",
|
|
|
|
"Validation",
|
|
|
|
"Procedure",
|
|
|
|
"Expression index",
|
|
|
|
"Exception",
|
|
|
|
"User",
|
|
|
|
"Domain",
|
2002-06-29 15:39:11 +02:00
|
|
|
"Index",
|
2003-11-30 07:41:29 +01:00
|
|
|
"Count [error if used]",
|
|
|
|
"User group",
|
|
|
|
"SQL role",
|
|
|
|
"Generator",
|
|
|
|
"User Defined Function"
|
2001-05-23 15:26:42 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
2003-09-29 14:43:14 +02:00
|
|
|
const SCHAR* Trigger_prefix_types[] = {
|
2003-11-30 07:41:29 +01:00
|
|
|
"BEFORE", // NTX: keyword
|
|
|
|
"AFTER" // NTX: keyword
|
2003-02-04 16:36:46 +01:00
|
|
|
};
|
|
|
|
|
2003-09-29 14:43:14 +02:00
|
|
|
const SCHAR* Trigger_suffix_types[] = {
|
2001-05-23 15:26:42 +02:00
|
|
|
"",
|
2003-11-30 07:41:29 +01:00
|
|
|
"INSERT", // NTX: keyword
|
|
|
|
"UPDATE", // NTX: keyword
|
|
|
|
"DELETE" // NTX: keyword
|
2001-05-23 15:26:42 +02:00
|
|
|
};
|
|
|
|
|
2002-06-29 15:39:11 +02:00
|
|
|
|
2004-04-26 09:54:22 +02:00
|
|
|
enum priv_flag {
|
|
|
|
priv_UNKNOWN = 1,
|
|
|
|
priv_SELECT = 2,
|
|
|
|
priv_INSERT = 4,
|
|
|
|
priv_UPDATE = 8,
|
|
|
|
priv_DELETE = 16,
|
|
|
|
priv_EXECUTE = 32,
|
|
|
|
priv_REFERENCES = 64
|
|
|
|
};
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
|
2003-02-13 10:42:18 +01:00
|
|
|
static const struct {
|
2001-05-23 15:26:42 +02:00
|
|
|
USHORT priv_flag;
|
2003-11-30 07:41:29 +01:00
|
|
|
const char* priv_string;
|
2001-05-23 15:26:42 +02:00
|
|
|
} privs[] = {
|
2003-11-30 07:41:29 +01:00
|
|
|
{ priv_DELETE, "DELETE"}, // NTX: keyword
|
|
|
|
{ priv_EXECUTE, "EXECUTE"}, // NTX: keyword
|
|
|
|
{ priv_INSERT, "INSERT"}, // NTX: keyword
|
|
|
|
{ priv_SELECT, "SELECT"}, // NTX: keyword
|
|
|
|
{ priv_UPDATE, "UPDATE"}, // NTX: keyword
|
|
|
|
{ priv_REFERENCES, "REFERENCES"}, // NTX: keyword
|
2001-05-23 15:26:42 +02:00
|
|
|
{ 0, NULL}
|
|
|
|
};
|
|
|
|
|
|
|
|
/* strlen of each element above, + strlen(", ") for separators */
|
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
const int MAX_PRIV_LIST = (6 + 2 + 7 + 2 + 6 + 2 + 6 + 2 + 6 + 2 + 10 + 1);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
|
2003-02-13 10:42:18 +01:00
|
|
|
static const SCHAR db_dialect_info[] = {
|
2001-05-23 15:26:42 +02:00
|
|
|
isc_info_db_sql_dialect,
|
|
|
|
isc_info_end
|
|
|
|
};
|
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
// Added support to display FORCED WRITES status. - PR 27-NOV-2001
|
|
|
|
// Added support to display transaction info when next_transaction id is fixed.
|
2004-08-27 07:03:13 +02:00
|
|
|
// Added support to display ODS version. CVC 26-Aug-2004.
|
2003-02-13 10:42:18 +01:00
|
|
|
static const SCHAR db_items[] = {
|
2001-05-23 15:26:42 +02:00
|
|
|
isc_info_page_size,
|
|
|
|
isc_info_db_size_in_pages,
|
|
|
|
isc_info_sweep_interval,
|
|
|
|
isc_info_limbo,
|
2002-06-29 15:39:11 +02:00
|
|
|
isc_info_forced_writes,
|
|
|
|
isc_info_oldest_transaction,
|
|
|
|
isc_info_oldest_active,
|
|
|
|
isc_info_oldest_snapshot,
|
|
|
|
isc_info_next_transaction,
|
2004-08-27 07:03:13 +02:00
|
|
|
isc_info_ods_version,
|
|
|
|
isc_info_ods_minor_version,
|
2001-05-23 15:26:42 +02:00
|
|
|
isc_info_end
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/* BPB to force transliteration of any shown system blobs from
|
|
|
|
* Database character set (CS_METADATA) to process character set
|
|
|
|
* (CS_dynamic).
|
|
|
|
* This same BPB is safe to use for both V3 & V4 db's - as
|
|
|
|
* a V3 db will ignore the source_ & target_interp values.
|
|
|
|
*/
|
2003-02-13 10:42:18 +01:00
|
|
|
static const UCHAR metadata_text_bpb[] = {
|
2001-05-23 15:26:42 +02:00
|
|
|
isc_bpb_version1,
|
2004-04-29 19:48:39 +02:00
|
|
|
isc_bpb_source_type, 1, isc_blob_text,
|
|
|
|
isc_bpb_target_type, 1, isc_blob_text,
|
2001-05-23 15:26:42 +02:00
|
|
|
isc_bpb_source_interp, 1, CS_METADATA,
|
|
|
|
isc_bpb_target_interp, 1, CS_dynamic
|
|
|
|
};
|
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
// trigger action helpers
|
2003-02-04 16:36:46 +01:00
|
|
|
|
2004-05-29 06:55:23 +02:00
|
|
|
inline int TRIGGER_ACTION_PREFIX(int value) {
|
2004-05-24 19:16:02 +02:00
|
|
|
return (value + 1) & 1;
|
|
|
|
}
|
2003-02-04 16:36:46 +01:00
|
|
|
|
2004-05-29 06:55:23 +02:00
|
|
|
inline int TRIGGER_ACTION_SUFFIX(int value, int slot) {
|
2004-05-24 19:16:02 +02:00
|
|
|
return ((value + 1) >> (slot * 2 - 1)) & 3;
|
|
|
|
}
|
2003-02-04 16:36:46 +01:00
|
|
|
|
|
|
|
const char* trigger_action(int type)
|
|
|
|
{
|
|
|
|
static char buffer[256];
|
|
|
|
int prefix = TRIGGER_ACTION_PREFIX(type);
|
|
|
|
strcpy(buffer, Trigger_prefix_types[prefix]);
|
|
|
|
int suffix = TRIGGER_ACTION_SUFFIX(type, 1);
|
|
|
|
strcat(buffer, " ");
|
|
|
|
strcat(buffer, Trigger_suffix_types[suffix]);
|
|
|
|
if ( (suffix = TRIGGER_ACTION_SUFFIX(type, 2)) ) {
|
|
|
|
strcat(buffer, " OR ");
|
|
|
|
strcat(buffer, Trigger_suffix_types[suffix]);
|
|
|
|
}
|
|
|
|
if ( (suffix = TRIGGER_ACTION_SUFFIX(type, 3)) ) {
|
|
|
|
strcat(buffer, " OR ");
|
|
|
|
strcat(buffer, Trigger_suffix_types[suffix]);
|
|
|
|
}
|
|
|
|
return buffer;
|
|
|
|
}
|
|
|
|
|
2005-05-19 10:03:10 +02:00
|
|
|
inline bool blobIsNull(const ISC_QUAD* blobid)
|
|
|
|
{
|
|
|
|
return blobid->gds_quad_high == 0 && blobid->gds_quad_low == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// There was too much string comparison inside SHOW_metadata.
|
|
|
|
// Handle all cases except VERSION and SQL DIALECT inside this class.
|
|
|
|
class ShowOptions
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
enum show_commands
|
|
|
|
{
|
|
|
|
role, table, view, system, index, domain, exception,
|
|
|
|
filter, function, generator, grant, procedure, trigger,
|
|
|
|
check, database, comment, wrong
|
|
|
|
};
|
|
|
|
static show_commands getCommand(const char* cmd);
|
|
|
|
|
|
|
|
private:
|
|
|
|
struct map
|
|
|
|
{
|
|
|
|
show_commands kw;
|
|
|
|
const char* text;
|
|
|
|
};
|
|
|
|
static const map options[];
|
|
|
|
};
|
|
|
|
|
|
|
|
const ShowOptions::map ShowOptions::options[] =
|
|
|
|
{
|
|
|
|
{role, "ROLE"},
|
|
|
|
{role, "ROLES"},
|
|
|
|
{table, "TABLE"},
|
|
|
|
{table, "TABLES"},
|
|
|
|
{view, "VIEW"},
|
|
|
|
{view, "VIEWS"},
|
|
|
|
{system, "SYSTEM"},
|
|
|
|
{system, "SYS"},
|
|
|
|
{index, "IND"},
|
|
|
|
{index, "INDEX"},
|
|
|
|
{index, "INDICES"},
|
|
|
|
{domain, "DOMAIN"},
|
|
|
|
{domain, "DOMAINS"},
|
|
|
|
{exception, "EXCEPTION"},
|
|
|
|
{exception, "EXCEPTIONS"},
|
|
|
|
{filter, "FILTER"},
|
|
|
|
{filter, "FILTERS"},
|
|
|
|
{function, "FUNCTION"},
|
|
|
|
{function, "FUNCTIONS"},
|
|
|
|
{generator, "GEN"},
|
|
|
|
{generator, "GENERATOR"},
|
|
|
|
{generator, "GENERATORS"},
|
|
|
|
{generator, "SEQ"},
|
|
|
|
{generator, "SEQUENCE"},
|
|
|
|
{generator, "SEQUENCES"},
|
|
|
|
{grant, "GRANT"},
|
|
|
|
{grant, "GRANTS"},
|
|
|
|
{procedure, "PROC"},
|
|
|
|
{procedure, "PROCEDURE"},
|
|
|
|
{procedure, "PROCEDURES"},
|
|
|
|
{trigger, "TRIG"},
|
|
|
|
{trigger, "TRIGGER"},
|
|
|
|
{trigger, "TRIGGERS"},
|
|
|
|
{check, "CHECK"},
|
|
|
|
{check, "CHECKS"},
|
|
|
|
{database, "DB"},
|
|
|
|
{database, "DATABASE"},
|
|
|
|
{comment, "COMMENT"},
|
|
|
|
{comment, "COMMENTS"}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Return the keyword associated with the string. There may be several strings
|
|
|
|
// for the same keyword (see table above). Return last (unused) keyword on error.
|
|
|
|
// Assume the command string is uppercased already.
|
|
|
|
ShowOptions::show_commands ShowOptions::getCommand(const char* cmd)
|
|
|
|
{
|
|
|
|
for (int i = 0; i < FB_NELEM(options); ++i)
|
|
|
|
{
|
|
|
|
if (!strcmp(cmd, options[i].text))
|
|
|
|
return options[i].kw;
|
|
|
|
}
|
|
|
|
return wrong;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-05-20 10:34:19 +02:00
|
|
|
|
2005-05-19 10:03:10 +02:00
|
|
|
// *************************
|
|
|
|
// S H O W _ c o m m e n t s
|
|
|
|
// *************************
|
2005-05-20 10:34:19 +02:00
|
|
|
// Extract database comments. Since it's called by the script extraction
|
2005-05-19 10:03:10 +02:00
|
|
|
// routine, it does nothing for ODS < 11, unless the force option is true.
|
|
|
|
void SHOW_comments(bool force)
|
|
|
|
{
|
|
|
|
if (isqlGlob.major_ods >= ODS_VERSION11 || force)
|
|
|
|
{
|
|
|
|
char banner[BUFFER_LENGTH128];
|
|
|
|
sprintf(banner, "%s/* Comments for database objects. */%s",
|
|
|
|
NEWLINE, NEWLINE);
|
2005-05-20 10:34:19 +02:00
|
|
|
show_comments(cmmExtract, banner);
|
2005-05-19 10:03:10 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-03 01:06:37 +02:00
|
|
|
bool SHOW_dbb_parameters(FB_API_HANDLE db_handle,
|
2003-09-29 14:43:14 +02:00
|
|
|
SCHAR* info_buf,
|
2004-05-12 21:39:17 +02:00
|
|
|
const SCHAR* db_itemsL,
|
2003-09-05 13:25:53 +02:00
|
|
|
USHORT item_length,
|
|
|
|
bool translate)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
2003-11-30 07:41:29 +01:00
|
|
|
* S H O W _ d b b _ p a r a m e t e r s
|
2001-05-23 15:26:42 +02:00
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Show db_info on this database
|
|
|
|
*
|
2003-11-30 07:41:29 +01:00
|
|
|
* Arguments:
|
2001-05-23 15:26:42 +02:00
|
|
|
* db_handle -- database handle
|
|
|
|
* info_buf -- info_bufput file pointer
|
2004-05-12 21:39:17 +02:00
|
|
|
* db_itemsL -- list of db_info items to process
|
2001-05-23 15:26:42 +02:00
|
|
|
*
|
|
|
|
**************************************/
|
2005-03-26 06:33:55 +01:00
|
|
|
SCHAR buffer[BUFFER_LENGTH128];
|
|
|
|
TEXT msg[MSG_LENGTH];
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-09-29 14:43:14 +02:00
|
|
|
ISC_STATUS_ARRAY status_vector;
|
2002-12-16 17:06:15 +01:00
|
|
|
if (isc_database_info(status_vector, &db_handle, item_length,
|
2004-05-12 21:39:17 +02:00
|
|
|
db_itemsL, BUFFER_LENGTH128, buffer))
|
2003-11-10 10:47:28 +01:00
|
|
|
{
|
2003-11-30 07:41:29 +01:00
|
|
|
ISQL_errmsg(status_vector);
|
|
|
|
return false;
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
*info_buf = '\0';
|
2003-09-29 14:43:14 +02:00
|
|
|
SCHAR* info = info_buf;
|
|
|
|
for (const SCHAR* d = buffer; *d != isc_info_end;) {
|
|
|
|
SLONG value_out = 0;
|
|
|
|
const SCHAR item = *d++;
|
|
|
|
const int length = isc_vax_integer(d, 2);
|
2001-05-23 15:26:42 +02:00
|
|
|
d += 2;
|
|
|
|
/*
|
|
|
|
* This is not the best solution but it fixes the lack of <LF> characters
|
|
|
|
* in Windows ISQL. This will need to remain until we modify the messages
|
|
|
|
* to remove the '\n' (on the PC its '\n\r').
|
2004-09-22 03:55:37 +02:00
|
|
|
* CVC: WISQL is dead. I've restored the the missing newlines for isql.
|
2001-05-23 15:26:42 +02:00
|
|
|
*/
|
|
|
|
switch (item) {
|
|
|
|
case isc_info_end:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case isc_info_page_size:
|
|
|
|
value_out = isc_vax_integer(d, length);
|
|
|
|
sprintf(info, "PAGE_SIZE %ld %s", value_out, NEWLINE);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case isc_info_db_size_in_pages:
|
|
|
|
value_out = isc_vax_integer(d, length);
|
|
|
|
if (translate) {
|
2005-03-31 09:50:32 +02:00
|
|
|
ISQL_msg_get(NUMBER_PAGES, msg, (TEXT*) (IPTR)value_out);
|
2004-09-22 03:55:37 +02:00
|
|
|
sprintf(info, "%s%s", msg, NEWLINE);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
sprintf(info, "Number of DB pages allocated = %ld %s",
|
|
|
|
value_out, NEWLINE);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case isc_info_sweep_interval:
|
|
|
|
value_out = isc_vax_integer(d, length);
|
|
|
|
if (translate) {
|
2005-03-31 09:50:32 +02:00
|
|
|
ISQL_msg_get(SWEEP_INTERV, msg, (TEXT*)(IPTR) value_out);
|
2004-09-22 03:55:37 +02:00
|
|
|
sprintf(info, "%s%s", msg, NEWLINE);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
sprintf(info, "Sweep interval = %ld %s", value_out, NEWLINE);
|
|
|
|
break;
|
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
case isc_info_forced_writes:
|
|
|
|
value_out = isc_vax_integer (d, length);
|
2004-11-30 07:08:56 +01:00
|
|
|
sprintf (info, "Forced Writes are %s %s", (value_out == 1 ? "ON" : "OFF"), NEWLINE);
|
2003-11-30 07:41:29 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case isc_info_oldest_transaction :
|
|
|
|
value_out = isc_vax_integer (d, length);
|
2004-08-27 07:03:13 +02:00
|
|
|
sprintf(info, "Transaction - oldest = %ld %s", value_out, NEWLINE);
|
2003-11-30 07:41:29 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case isc_info_oldest_active :
|
|
|
|
value_out = isc_vax_integer (d, length);
|
2004-08-27 07:03:13 +02:00
|
|
|
sprintf(info, "Transaction - oldest active = %ld %s", value_out, NEWLINE);
|
2003-11-30 07:41:29 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case isc_info_oldest_snapshot :
|
|
|
|
value_out = isc_vax_integer (d, length);
|
2004-08-27 07:03:13 +02:00
|
|
|
sprintf(info, "Transaction - oldest snapshot = %ld %s", value_out, NEWLINE);
|
2003-11-30 07:41:29 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case isc_info_next_transaction :
|
|
|
|
value_out = isc_vax_integer (d, length);
|
|
|
|
sprintf (info, "Transaction - Next = %ld %s", value_out, NEWLINE);
|
|
|
|
break;
|
2002-06-29 15:39:11 +02:00
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
case isc_info_base_level:
|
|
|
|
value_out = isc_vax_integer(d, length);
|
|
|
|
if (translate) {
|
2005-03-31 09:50:32 +02:00
|
|
|
ISQL_msg_get(BASE_LEVEL, msg, (TEXT*)(IPTR)value_out);
|
2004-09-22 03:55:37 +02:00
|
|
|
sprintf(info, "%s%s", msg, NEWLINE);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
sprintf(info, "Base level = %ld %s", value_out, NEWLINE);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case isc_info_limbo:
|
|
|
|
value_out = isc_vax_integer(d, length);
|
|
|
|
if (translate) {
|
2005-03-31 09:50:32 +02:00
|
|
|
ISQL_msg_get(LIMBO, msg, (TEXT*)(IPTR)value_out);
|
2004-09-22 03:55:37 +02:00
|
|
|
sprintf(info, "%s%s", msg, NEWLINE);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
sprintf(info, "Transaction in limbo = %ld %s",
|
|
|
|
value_out, NEWLINE);
|
|
|
|
break;
|
|
|
|
|
2004-08-27 07:03:13 +02:00
|
|
|
case isc_info_ods_version:
|
|
|
|
isqlGlob.major_ods = isc_vax_integer(d, length);
|
|
|
|
break;
|
|
|
|
case isc_info_ods_minor_version:
|
|
|
|
value_out = isc_vax_integer(d, length);
|
|
|
|
sprintf(info, "ODS = %ld.%ld%s", (SLONG) isqlGlob.major_ods, value_out, NEWLINE);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
d += length;
|
|
|
|
info += strlen(info);
|
|
|
|
}
|
2002-06-29 15:39:11 +02:00
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
return true;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-11-23 12:03:48 +01:00
|
|
|
processing_state SHOW_grants(const SCHAR* object,
|
2003-09-09 13:03:37 +02:00
|
|
|
const SCHAR* terminator,
|
2003-09-05 13:25:53 +02:00
|
|
|
USHORT obj_type)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* S H O W _ g r a n t s
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
2002-06-29 15:39:11 +02:00
|
|
|
* Placeholder for SHOW_grants2 without additional message.
|
|
|
|
*
|
|
|
|
**************************************/
|
2003-11-30 07:41:29 +01:00
|
|
|
return SHOW_grants2 (object, terminator, obj_type, NULL);
|
2002-06-29 15:39:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-11-23 12:03:48 +01:00
|
|
|
processing_state SHOW_grants2 (const SCHAR* object,
|
2003-09-09 13:03:37 +02:00
|
|
|
const SCHAR* terminator,
|
2003-09-05 13:25:53 +02:00
|
|
|
USHORT obj_type,
|
2003-11-30 07:41:29 +01:00
|
|
|
const TEXT* optional_msg)
|
2002-06-29 15:39:11 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* S H O W _ g r a n t s 2
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
2001-05-23 15:26:42 +02:00
|
|
|
* Show grants for given object name
|
|
|
|
* This function is also called by extract for privileges.
|
|
|
|
* It must extract granted privileges on tables/views to users,
|
|
|
|
* - these may be compound, so put them on the same line.
|
|
|
|
* Grant execute privilege on procedures to users
|
|
|
|
* Grant various privilegs to procedures.
|
|
|
|
* All privileges may have the with_grant option set.
|
2002-06-29 15:39:11 +02:00
|
|
|
* The optional msg is to display a customized message. When the
|
|
|
|
* new feature of all grants is used, there's no way to print the
|
|
|
|
* header message after this routine, so it should be printed here.
|
2001-05-23 15:26:42 +02:00
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
BASED_ON RDB$USER_PRIVILEGES.RDB$USER prev_user;
|
|
|
|
BASED_ON RDB$USER_PRIVILEGES.RDB$GRANT_OPTION prev_option;
|
|
|
|
BASED_ON RDB$USER_PRIVILEGES.RDB$FIELD_NAME prev_field;
|
2005-05-26 09:35:45 +02:00
|
|
|
BASED_ON RDB$USER_PRIVILEGES.RDB$USER_TYPE prev_user_type;
|
2001-05-23 15:26:42 +02:00
|
|
|
SCHAR user_string[44];
|
2003-09-05 13:25:53 +02:00
|
|
|
bool first = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (!*object)
|
2005-05-14 16:50:41 +02:00
|
|
|
return ps_ERR;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2005-05-26 09:35:45 +02:00
|
|
|
// Query against user_privileges instead of looking at rdb$security_classes
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
prev_option = -1;
|
|
|
|
prev_user[0] = '\0';
|
|
|
|
prev_field[0] = '\0';
|
2005-05-26 09:35:45 +02:00
|
|
|
prev_user_type = -1;
|
2003-11-30 07:41:29 +01:00
|
|
|
char priv_string[MAX_PRIV_LIST] = "";
|
|
|
|
char col_string[BUFFER_LENGTH128] = "";
|
|
|
|
char with_option[18] = "";
|
|
|
|
USHORT priv_flags = 0;
|
|
|
|
SSHORT prev_field_null = -1;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2005-05-26 09:35:45 +02:00
|
|
|
if (obj_type == obj_relation || obj_type == 255)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
// Find the user specified relation and show its privileges
|
|
|
|
|
|
|
|
FOR FIRST 1 R IN RDB$RELATIONS WITH R.RDB$RELATION_NAME EQ object;
|
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
// This query only finds tables, eliminating owner privileges
|
2002-06-29 15:39:11 +02:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
FOR PRV IN RDB$USER_PRIVILEGES CROSS
|
2003-11-30 07:41:29 +01:00
|
|
|
REL IN RDB$RELATIONS WITH
|
|
|
|
PRV.RDB$RELATION_NAME EQ object AND
|
|
|
|
REL.RDB$RELATION_NAME EQ object AND
|
|
|
|
PRV.RDB$PRIVILEGE NE 'M' AND
|
|
|
|
REL.RDB$OWNER_NAME NE PRV.RDB$USER
|
|
|
|
SORTED BY PRV.RDB$USER, PRV.RDB$FIELD_NAME, PRV.RDB$GRANT_OPTION;
|
|
|
|
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(PRV.RDB$USER);
|
2003-11-30 07:41:29 +01:00
|
|
|
|
|
|
|
// Sometimes grant options are null, sometimes 0. Both same
|
|
|
|
|
|
|
|
if (PRV.RDB$GRANT_OPTION.NULL)
|
|
|
|
PRV.RDB$GRANT_OPTION = 0;
|
|
|
|
|
|
|
|
if (PRV.RDB$FIELD_NAME.NULL)
|
|
|
|
PRV.RDB$FIELD_NAME[0] = '\0';
|
|
|
|
|
|
|
|
// Print a new grant statement for each new user or change of option
|
|
|
|
|
|
|
|
if ((prev_user[0] && strcmp (prev_user, PRV.RDB$USER)) ||
|
|
|
|
(prev_field_null != -1 &&
|
|
|
|
prev_field_null != PRV.RDB$FIELD_NAME.NULL) ||
|
|
|
|
(!prev_field_null && strcmp (prev_field, PRV.RDB$FIELD_NAME)) ||
|
2005-05-26 09:35:45 +02:00
|
|
|
(prev_option != -1 && prev_option != PRV.RDB$GRANT_OPTION) ||
|
|
|
|
(prev_user_type != -1 && prev_user_type != PRV.RDB$USER_TYPE))
|
2003-11-30 07:41:29 +01:00
|
|
|
{
|
|
|
|
|
|
|
|
make_priv_string (priv_flags, priv_string);
|
|
|
|
|
|
|
|
if (first && optional_msg)
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.prints(optional_msg);
|
2003-11-30 07:41:29 +01:00
|
|
|
|
|
|
|
first = false;
|
|
|
|
|
2004-05-24 19:16:02 +02:00
|
|
|
if (isqlGlob.db_SQL_dialect > SQL_DIALECT_V6_TRANSITION)
|
2003-11-30 07:41:29 +01:00
|
|
|
ISQL_copy_SQL_id (object, SQL_identifier, DBL_QUOTE);
|
|
|
|
else
|
|
|
|
strcpy (SQL_identifier, object);
|
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("GRANT %s%s ON %s TO %s%s%s%s", priv_string,
|
2003-11-30 07:41:29 +01:00
|
|
|
col_string, SQL_identifier, user_string,
|
|
|
|
with_option, terminator, NEWLINE);
|
|
|
|
|
|
|
|
// re-initialize strings
|
|
|
|
|
|
|
|
priv_string[0] = '\0';
|
|
|
|
with_option[0] = '\0';
|
|
|
|
col_string[0] = '\0';
|
|
|
|
priv_flags = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// At each row, store this value for the next compare of contol break
|
|
|
|
|
|
|
|
strcpy (prev_user, PRV.RDB$USER);
|
|
|
|
prev_option = PRV.RDB$GRANT_OPTION;
|
|
|
|
prev_field_null = PRV.RDB$FIELD_NAME.NULL;
|
|
|
|
strcpy (prev_field, PRV.RDB$FIELD_NAME);
|
2005-05-26 09:35:45 +02:00
|
|
|
prev_user_type = PRV.RDB$USER_TYPE;
|
2003-11-30 07:41:29 +01:00
|
|
|
|
|
|
|
switch (PRV.RDB$USER_TYPE) {
|
|
|
|
case obj_relation:
|
|
|
|
case obj_view:
|
|
|
|
case obj_trigger:
|
|
|
|
case obj_procedure:
|
|
|
|
case obj_sql_role:
|
2004-05-24 19:16:02 +02:00
|
|
|
if (isqlGlob.db_SQL_dialect > SQL_DIALECT_V6_TRANSITION) {
|
2003-11-30 07:41:29 +01:00
|
|
|
ISQL_copy_SQL_id (PRV.RDB$USER, SQL_identifier, DBL_QUOTE);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
strcpy (SQL_identifier, PRV.RDB$USER);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
strcpy (SQL_identifier, PRV.RDB$USER);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (PRV.RDB$USER_TYPE) {
|
|
|
|
case obj_view:
|
|
|
|
sprintf (user_string, "VIEW %s", SQL_identifier);
|
|
|
|
break;
|
|
|
|
case obj_trigger:
|
|
|
|
sprintf (user_string, "TRIGGER %s", SQL_identifier);
|
|
|
|
break;
|
|
|
|
case obj_procedure:
|
|
|
|
sprintf (user_string, "PROCEDURE %s", SQL_identifier);
|
|
|
|
break;
|
|
|
|
case obj_user:
|
|
|
|
if (strcmp(SQL_identifier, "PUBLIC"))
|
|
|
|
sprintf (user_string, "USER %s", SQL_identifier);
|
|
|
|
else
|
|
|
|
strcpy (user_string, SQL_identifier);
|
|
|
|
break;
|
|
|
|
case obj_user_group:
|
|
|
|
sprintf (user_string, "GROUP %s", SQL_identifier);
|
|
|
|
break;
|
|
|
|
case obj_sql_role:
|
|
|
|
sprintf (user_string, "ROLE %s", SQL_identifier);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
strcpy (user_string, SQL_identifier);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Only the first character is used for permissions
|
|
|
|
|
|
|
|
const char c = PRV.RDB$PRIVILEGE[0];
|
|
|
|
|
|
|
|
switch (c) {
|
|
|
|
case 'S':
|
|
|
|
priv_flags |= priv_SELECT;
|
|
|
|
break;
|
|
|
|
case 'I':
|
|
|
|
priv_flags |= priv_INSERT;
|
|
|
|
break;
|
|
|
|
case 'U':
|
|
|
|
priv_flags |= priv_UPDATE;
|
|
|
|
break;
|
|
|
|
case 'D':
|
|
|
|
priv_flags |= priv_DELETE;
|
|
|
|
break;
|
|
|
|
case 'R':
|
|
|
|
priv_flags |= priv_REFERENCES;
|
|
|
|
break;
|
|
|
|
case 'X':
|
|
|
|
// Execute should not be here -- special handling below
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
priv_flags |= priv_UNKNOWN;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Column level privileges for update and references only
|
|
|
|
if (PRV.RDB$FIELD_NAME.NULL) {
|
|
|
|
*col_string = '\0';
|
|
|
|
}
|
|
|
|
else {
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(PRV.RDB$FIELD_NAME);
|
2004-05-24 19:16:02 +02:00
|
|
|
if (isqlGlob.db_SQL_dialect > SQL_DIALECT_V6_TRANSITION) {
|
2003-11-30 07:41:29 +01:00
|
|
|
ISQL_copy_SQL_id (PRV.RDB$FIELD_NAME, SQL_identifier, DBL_QUOTE);
|
|
|
|
sprintf(col_string, " (%s)", SQL_identifier);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
sprintf(col_string, " (%s)", PRV.RDB$FIELD_NAME);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (PRV.RDB$GRANT_OPTION)
|
|
|
|
strcpy (with_option, " WITH GRANT OPTION");
|
|
|
|
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg (isc_status);
|
2005-05-14 16:50:41 +02:00
|
|
|
return ps_ERR;
|
2003-11-30 07:41:29 +01:00
|
|
|
END_ERROR;
|
|
|
|
|
|
|
|
// Print last case if there was anything to print
|
|
|
|
|
|
|
|
if (prev_option != -1) {
|
|
|
|
make_priv_string (priv_flags, priv_string);
|
|
|
|
if (first && optional_msg)
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.prints(optional_msg);
|
2003-11-30 07:41:29 +01:00
|
|
|
first = false;
|
|
|
|
|
2004-05-24 19:16:02 +02:00
|
|
|
if (isqlGlob.db_SQL_dialect > SQL_DIALECT_V6_TRANSITION)
|
2003-11-30 07:41:29 +01:00
|
|
|
ISQL_copy_SQL_id (object, SQL_identifier, DBL_QUOTE);
|
|
|
|
else
|
|
|
|
strcpy (SQL_identifier, object);
|
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("GRANT %s%s ON %s TO %s%s%s%s",
|
2003-11-30 07:41:29 +01:00
|
|
|
priv_string, col_string,
|
|
|
|
SQL_identifier, user_string, with_option, terminator, NEWLINE);
|
|
|
|
}
|
|
|
|
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
2005-05-14 16:50:41 +02:00
|
|
|
return ps_ERR;
|
2004-04-23 20:39:04 +02:00
|
|
|
END_ERROR;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
if (!first)
|
|
|
|
return (SKIP);
|
|
|
|
}
|
|
|
|
|
|
|
|
// No relation called "object" was found, try procedure "object"
|
2005-05-26 09:35:45 +02:00
|
|
|
if (obj_type == obj_procedure || obj_type == 255)
|
|
|
|
{
|
2003-11-30 07:41:29 +01:00
|
|
|
|
|
|
|
FOR FIRST 1 P IN RDB$PROCEDURES WITH P.RDB$PROCEDURE_NAME EQ object
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
// Part two is for stored procedures only
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
FOR PRV IN RDB$USER_PRIVILEGES CROSS
|
2003-11-30 07:41:29 +01:00
|
|
|
PRC IN RDB$PROCEDURES WITH
|
|
|
|
PRV.RDB$OBJECT_TYPE = obj_procedure AND
|
|
|
|
PRV.RDB$RELATION_NAME EQ object AND
|
|
|
|
PRC.RDB$PROCEDURE_NAME EQ object AND
|
|
|
|
PRV.RDB$PRIVILEGE EQ 'X' AND
|
|
|
|
PRC.RDB$OWNER_NAME NE PRV.RDB$USER
|
|
|
|
SORTED BY PRV.RDB$USER, PRV.RDB$FIELD_NAME, PRV.RDB$GRANT_OPTION;
|
|
|
|
|
|
|
|
if (first && optional_msg)
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.prints(optional_msg);
|
2003-11-30 07:41:29 +01:00
|
|
|
|
|
|
|
first = false;
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(PRV.RDB$USER);
|
2003-11-30 07:41:29 +01:00
|
|
|
|
|
|
|
switch (PRV.RDB$USER_TYPE) {
|
|
|
|
case obj_relation:
|
|
|
|
case obj_view:
|
|
|
|
case obj_trigger:
|
|
|
|
case obj_procedure:
|
|
|
|
case obj_sql_role:
|
2004-05-24 19:16:02 +02:00
|
|
|
if (isqlGlob.db_SQL_dialect > SQL_DIALECT_V6_TRANSITION) {
|
2003-11-30 07:41:29 +01:00
|
|
|
ISQL_copy_SQL_id (PRV.RDB$USER, SQL_identifier, DBL_QUOTE);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
strcpy (SQL_identifier, PRV.RDB$USER);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
strcpy (SQL_identifier, PRV.RDB$USER);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (PRV.RDB$USER_TYPE) {
|
|
|
|
case obj_view:
|
|
|
|
sprintf (user_string, "VIEW %s", SQL_identifier);
|
|
|
|
break;
|
|
|
|
case obj_trigger:
|
|
|
|
sprintf (user_string, "TRIGGER %s", SQL_identifier);
|
|
|
|
break;
|
|
|
|
case obj_procedure:
|
|
|
|
sprintf (user_string, "PROCEDURE %s", SQL_identifier);
|
|
|
|
break;
|
|
|
|
case obj_user:
|
|
|
|
if (strcmp(SQL_identifier, "PUBLIC"))
|
|
|
|
sprintf (user_string, "USER %s", SQL_identifier);
|
|
|
|
else
|
|
|
|
strcpy (user_string, SQL_identifier);
|
|
|
|
break;
|
|
|
|
case obj_user_group:
|
|
|
|
sprintf (user_string, "GROUP %s", SQL_identifier);
|
|
|
|
break;
|
|
|
|
case obj_sql_role:
|
|
|
|
sprintf (user_string, "ROLE %s", SQL_identifier);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
strcpy (user_string, SQL_identifier);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (PRV.RDB$GRANT_OPTION)
|
|
|
|
strcpy (with_option, " WITH GRANT OPTION");
|
|
|
|
else
|
|
|
|
with_option[0] = '\0';
|
|
|
|
|
2004-05-24 19:16:02 +02:00
|
|
|
if (isqlGlob.db_SQL_dialect > SQL_DIALECT_V6_TRANSITION) {
|
2003-11-30 07:41:29 +01:00
|
|
|
ISQL_copy_SQL_id (object, SQL_identifier, DBL_QUOTE);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
strcpy (SQL_identifier, object);
|
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("GRANT EXECUTE ON PROCEDURE %s TO %s%s%s%s",
|
2003-11-30 07:41:29 +01:00
|
|
|
SQL_identifier, user_string, with_option, terminator, NEWLINE);
|
|
|
|
first = false;
|
|
|
|
|
|
|
|
END_FOR
|
2004-04-23 20:39:04 +02:00
|
|
|
ON_ERROR
|
2003-11-30 07:41:29 +01:00
|
|
|
ISQL_errmsg (isc_status);
|
2005-05-19 10:03:10 +02:00
|
|
|
return ps_ERR;
|
2004-04-23 20:39:04 +02:00
|
|
|
END_ERROR
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
2003-11-30 07:41:29 +01:00
|
|
|
ISQL_errmsg(isc_status);
|
2005-05-19 10:03:10 +02:00
|
|
|
return ps_ERR;
|
2004-04-23 20:39:04 +02:00
|
|
|
END_ERROR;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
if (!first)
|
|
|
|
return (SKIP);
|
|
|
|
}
|
|
|
|
|
|
|
|
// No procedure called "object" was found, try role "object"
|
|
|
|
SCHAR role_name[BUFFER_LENGTH128];
|
|
|
|
|
|
|
|
if (obj_type == obj_sql_role || obj_type == 255) {
|
|
|
|
// No procedure called "object" was found, try role "object"
|
|
|
|
/* CVC: This code could be superseded by SHOW_grant_roles() below
|
|
|
|
with the sole difference of the sort fields. */
|
|
|
|
|
|
|
|
FOR FIRST 1 R IN RDB$ROLES WITH R.RDB$ROLE_NAME EQ object
|
|
|
|
|
|
|
|
FOR PRV IN RDB$USER_PRIVILEGES WITH
|
|
|
|
PRV.RDB$OBJECT_TYPE EQ obj_sql_role AND
|
|
|
|
PRV.RDB$USER_TYPE EQ obj_user AND
|
|
|
|
PRV.RDB$RELATION_NAME EQ object AND
|
|
|
|
PRV.RDB$PRIVILEGE EQ 'M'
|
|
|
|
SORTED BY PRV.RDB$USER
|
|
|
|
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(PRV.RDB$RELATION_NAME);
|
2003-11-30 07:41:29 +01:00
|
|
|
strcpy (role_name, PRV.RDB$RELATION_NAME);
|
2004-05-24 19:16:02 +02:00
|
|
|
if (isqlGlob.db_SQL_dialect > SQL_DIALECT_V6_TRANSITION)
|
2003-11-30 07:41:29 +01:00
|
|
|
ISQL_copy_SQL_id (role_name, SQL_identifier, DBL_QUOTE);
|
|
|
|
else
|
|
|
|
strcpy (SQL_identifier, role_name);
|
|
|
|
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(PRV.RDB$USER);
|
2003-11-30 07:41:29 +01:00
|
|
|
strcpy (user_string, PRV.RDB$USER);
|
|
|
|
|
|
|
|
if (PRV.RDB$GRANT_OPTION)
|
|
|
|
strcpy (with_option, " WITH ADMIN OPTION");
|
|
|
|
else
|
|
|
|
with_option[0] = '\0';
|
|
|
|
|
|
|
|
sprintf (Print_buffer, "GRANT %s TO %s%s%s%s", SQL_identifier,
|
|
|
|
user_string, with_option, terminator, NEWLINE);
|
|
|
|
|
|
|
|
if (first && optional_msg)
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.prints(optional_msg);
|
2003-11-30 07:41:29 +01:00
|
|
|
|
|
|
|
first = false;
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.prints(Print_buffer);
|
2003-11-30 07:41:29 +01:00
|
|
|
|
|
|
|
END_FOR
|
2004-04-23 20:39:04 +02:00
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg (isc_status);
|
2005-05-19 10:03:10 +02:00
|
|
|
return ps_ERR;
|
2004-04-23 20:39:04 +02:00
|
|
|
END_ERROR;
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
2003-11-30 07:41:29 +01:00
|
|
|
ISQL_errmsg(isc_status);
|
2005-05-19 10:03:10 +02:00
|
|
|
return ps_ERR;
|
2004-04-23 20:39:04 +02:00
|
|
|
END_ERROR;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
if (!first)
|
|
|
|
return (SKIP);
|
|
|
|
}
|
2002-06-29 15:39:11 +02:00
|
|
|
|
2003-12-03 09:19:24 +01:00
|
|
|
return OBJECT_NOT_FOUND;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-09-09 13:03:37 +02:00
|
|
|
void SHOW_grant_roles(const SCHAR* terminator,
|
|
|
|
bool* first)
|
2002-06-29 15:39:11 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* S H O W _ g r a n t _ r o l e s
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Placeholder for SHOW_grant_roles2 without additional message.
|
|
|
|
*
|
|
|
|
**************************************/
|
2003-11-30 07:41:29 +01:00
|
|
|
SHOW_grant_roles2 (terminator, first, 0);
|
2002-06-29 15:39:11 +02:00
|
|
|
}
|
|
|
|
|
2003-09-09 13:03:37 +02:00
|
|
|
void SHOW_grant_roles2 (const SCHAR* terminator,
|
|
|
|
bool* first,
|
2003-11-30 07:41:29 +01:00
|
|
|
const TEXT* optional_msg)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* S H O W _ g r a n t _ r o l e s
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
2005-04-04 10:33:43 +02:00
|
|
|
* Show grants for each role name
|
2001-05-23 15:26:42 +02:00
|
|
|
* This function is also called by extract for privileges.
|
|
|
|
* All membership privilege may have the with_admin option set.
|
|
|
|
*
|
|
|
|
**************************************/
|
2001-12-24 03:51:06 +01:00
|
|
|
char with_option[18];
|
|
|
|
char user_string[44];
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
// process role "object"
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
FOR PRV IN RDB$USER_PRIVILEGES WITH
|
2004-04-23 20:39:04 +02:00
|
|
|
PRV.RDB$OBJECT_TYPE EQ obj_sql_role AND
|
|
|
|
PRV.RDB$USER_TYPE EQ obj_user AND
|
|
|
|
PRV.RDB$PRIVILEGE EQ 'M'
|
2005-04-04 10:33:43 +02:00
|
|
|
SORTED BY PRV.RDB$RELATION_NAME, PRV.RDB$USER
|
2002-06-29 15:39:11 +02:00
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
if (first) {
|
|
|
|
if (*first && optional_msg) {
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.prints(optional_msg);
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
|
|
|
*first = false;
|
|
|
|
}
|
|
|
|
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(PRV.RDB$USER);
|
2004-04-23 20:39:04 +02:00
|
|
|
strcpy (user_string, PRV.RDB$USER);
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
if (PRV.RDB$GRANT_OPTION)
|
|
|
|
strcpy (with_option, " WITH ADMIN OPTION");
|
|
|
|
else
|
|
|
|
with_option[0] = '\0';
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2005-04-04 10:33:43 +02:00
|
|
|
const char* role = fb_utils::exact_name(PRV.RDB$RELATION_NAME);
|
|
|
|
if (isqlGlob.db_SQL_dialect > SQL_DIALECT_V6_TRANSITION)
|
|
|
|
{
|
2003-11-30 07:41:29 +01:00
|
|
|
ISQL_copy_SQL_id (PRV.RDB$RELATION_NAME, SQL_identifier, DBL_QUOTE);
|
2005-04-04 10:33:43 +02:00
|
|
|
role = SQL_identifier;
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("GRANT %s TO %s%s%s%s", role,
|
2003-11-30 07:41:29 +01:00
|
|
|
user_string, with_option, terminator, NEWLINE);
|
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
END_FOR
|
2003-11-30 07:41:29 +01:00
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-04-29 00:36:29 +02:00
|
|
|
void SHOW_print_metadata_text_blob(FILE* fp,
|
2005-05-19 10:03:10 +02:00
|
|
|
ISC_QUAD* blobid,
|
|
|
|
bool escape_squote)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* S H O W _ p r i n t _ m e t a d a t a _ t e x t _ b l o b
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Print a Blob that is known to be metadata text.
|
2005-05-19 10:03:10 +02:00
|
|
|
* The last param says whether single quotes should be escaped (duplicating them).
|
2001-05-23 15:26:42 +02:00
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
|
2005-05-19 10:03:10 +02:00
|
|
|
// Don't bother with null blobs
|
|
|
|
if (blobIsNull(blobid))
|
2001-05-23 15:26:42 +02:00
|
|
|
return;
|
|
|
|
|
2004-05-03 01:06:37 +02:00
|
|
|
isc_blob_handle blob_handle = 0;
|
2001-07-12 08:32:05 +02:00
|
|
|
if (isc_open_blob2(isc_status, &DB, &gds_trans, &blob_handle, blobid,
|
2003-10-29 11:53:47 +01:00
|
|
|
sizeof(metadata_text_bpb), metadata_text_bpb))
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
ISQL_errmsg(isc_status);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2005-03-26 06:33:55 +01:00
|
|
|
SCHAR buffer[BUFFER_LENGTH512];
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-09-29 14:43:14 +02:00
|
|
|
USHORT length = 0;
|
2001-05-23 15:26:42 +02:00
|
|
|
while (!isc_get_segment(isc_status, &blob_handle, &length,
|
2003-04-08 12:38:59 +02:00
|
|
|
(USHORT) (BUFFER_LENGTH512 - 1), buffer) ||
|
2004-04-11 06:04:18 +02:00
|
|
|
isc_status[1] == isc_segment)
|
|
|
|
{
|
2005-05-19 10:03:10 +02:00
|
|
|
// Need to step through the buffer until we hit a '\n' and then print the
|
|
|
|
// line. This is because '\n' are included in blob text.
|
|
|
|
// CVC: The above comment and the code do not match.
|
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
buffer[length] = 0;
|
2005-05-19 10:03:10 +02:00
|
|
|
if (escape_squote)
|
|
|
|
{
|
|
|
|
for (const UCHAR* p = (UCHAR*) buffer; *p; ++p)
|
|
|
|
{
|
|
|
|
if (*p == '\'')
|
|
|
|
fputc(*p, fp);
|
|
|
|
fputc(*p, fp);
|
|
|
|
}
|
|
|
|
fflush(fp);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ISQL_printf(fp, buffer);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (isc_status[1] && isc_status[1] != isc_segstr_eof)
|
|
|
|
ISQL_errmsg(isc_status);
|
|
|
|
|
|
|
|
isc_close_blob(isc_status, &blob_handle);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-12-03 09:19:24 +01:00
|
|
|
processing_state SHOW_metadata(const SCHAR* const* cmd,
|
2003-09-29 14:43:14 +02:00
|
|
|
SCHAR** lcmd)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* S H O W _ m e t a d a t a
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* If somebody presses the show ..., come here to
|
|
|
|
* interpret the desired command.
|
|
|
|
* Paramters:
|
|
|
|
* cmd -- Array of words for the command
|
|
|
|
*
|
|
|
|
**************************************/
|
2003-12-03 09:19:24 +01:00
|
|
|
processing_state ret = SKIP;
|
2001-05-23 15:26:42 +02:00
|
|
|
int key = 0;
|
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
// Can't show nothing, return an error
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (!cmd[1])
|
2005-05-19 10:03:10 +02:00
|
|
|
return ps_ERR;
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2005-05-26 08:45:25 +02:00
|
|
|
// Only show version and show sql dialect work if there is no db attached
|
|
|
|
bool handled = true;
|
|
|
|
if ((!strcmp(cmd[1], "VERSION")) || (!strcmp(cmd[1], "VER")))
|
|
|
|
{
|
2003-11-30 07:41:29 +01:00
|
|
|
TEXT msg_string[MSG_LENGTH];
|
2005-03-31 09:50:32 +02:00
|
|
|
ISQL_msg_get(VERSION, msg_string, FB_VERSION);
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%s%s", msg_string, NEWLINE);
|
2003-12-22 11:00:59 +01:00
|
|
|
isc_version(&DB, local_fprintf, NULL);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
2005-05-26 08:45:25 +02:00
|
|
|
else if (!strcmp(cmd[1], "SQL"))
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
if (!strcmp(cmd[2], "DIALECT"))
|
|
|
|
ret = show_dialect();
|
|
|
|
else
|
2005-05-14 16:50:41 +02:00
|
|
|
ret = ps_ERR;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
2005-05-26 08:45:25 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
handled = false;
|
|
|
|
if (!ISQL_dbcheck())
|
|
|
|
ret = ps_ERR;
|
|
|
|
}
|
2005-05-19 10:03:10 +02:00
|
|
|
|
2005-05-26 08:45:25 +02:00
|
|
|
if (ret == ps_ERR || handled)
|
2005-05-19 10:03:10 +02:00
|
|
|
return ret;
|
|
|
|
|
|
|
|
TEXT SQL_id_for_grant[BUFFER_LENGTH128];
|
|
|
|
|
|
|
|
switch (ShowOptions::getCommand(cmd[1]))
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2005-05-19 10:03:10 +02:00
|
|
|
case ShowOptions::role:
|
|
|
|
if (isqlGlob.major_ods >= ODS_VERSION9)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
if (*cmd[2])
|
|
|
|
{
|
|
|
|
if (*cmd[2] == '"')
|
|
|
|
{
|
|
|
|
remove_delimited_double_quotes(lcmd[2]);
|
|
|
|
ret = show_role(lcmd[2]);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ret = show_role(cmd[2]);
|
|
|
|
}
|
|
|
|
|
2005-05-19 10:03:10 +02:00
|
|
|
if (ret == OBJECT_NOT_FOUND)
|
2001-05-23 15:26:42 +02:00
|
|
|
key = NO_ROLE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ret = show_role(NULL);
|
2005-05-19 10:03:10 +02:00
|
|
|
if (ret == OBJECT_NOT_FOUND)
|
2001-05-23 15:26:42 +02:00
|
|
|
key = NO_ROLES;
|
|
|
|
}
|
|
|
|
}
|
2005-05-19 10:03:10 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
ret = OBJECT_NOT_FOUND;
|
|
|
|
key = NO_ROLES;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ShowOptions::table:
|
2001-05-23 15:26:42 +02:00
|
|
|
if (*cmd[2])
|
|
|
|
{
|
|
|
|
if (*cmd[2] == '"')
|
|
|
|
{
|
|
|
|
remove_delimited_double_quotes(lcmd[2]);
|
2004-04-23 20:39:04 +02:00
|
|
|
ret = show_table(lcmd[2], false);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-04-23 20:39:04 +02:00
|
|
|
ret = show_table(cmd[2], false);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2005-05-19 10:03:10 +02:00
|
|
|
if (ret == OBJECT_NOT_FOUND)
|
2001-05-23 15:26:42 +02:00
|
|
|
key = NO_TABLE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ret = show_all_tables(0);
|
2005-05-19 10:03:10 +02:00
|
|
|
if (ret == OBJECT_NOT_FOUND)
|
2001-05-23 15:26:42 +02:00
|
|
|
key = NO_TABLES;
|
|
|
|
}
|
2005-05-19 10:03:10 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case ShowOptions::view:
|
2001-05-23 15:26:42 +02:00
|
|
|
if (*cmd[2])
|
|
|
|
{
|
|
|
|
if (*cmd[2] == '"')
|
|
|
|
{
|
|
|
|
remove_delimited_double_quotes(lcmd[2]);
|
2004-04-23 20:39:04 +02:00
|
|
|
ret = show_table(lcmd[2], true);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-04-23 20:39:04 +02:00
|
|
|
ret = show_table(cmd[2], true);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2005-05-19 10:03:10 +02:00
|
|
|
if (ret == OBJECT_NOT_FOUND)
|
2001-05-23 15:26:42 +02:00
|
|
|
key = NO_VIEW;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ret = show_all_tables(-1);
|
2005-05-19 10:03:10 +02:00
|
|
|
if (ret == OBJECT_NOT_FOUND)
|
2001-05-23 15:26:42 +02:00
|
|
|
key = NO_VIEWS;
|
|
|
|
}
|
2005-05-19 10:03:10 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case ShowOptions::system:
|
2005-05-26 08:45:25 +02:00
|
|
|
{
|
|
|
|
TEXT msg[MSG_LENGTH];
|
|
|
|
ISQL_msg_get(MSG_TABLES, msg, NULL);
|
|
|
|
isqlGlob.printf("%s%s", msg, NEWLINE);
|
|
|
|
show_all_tables(1);
|
|
|
|
ISQL_msg_get(MSG_FUNCTIONS, msg, NULL);
|
|
|
|
isqlGlob.printf("%s%s", msg, NEWLINE);
|
|
|
|
show_functions("", 1);
|
|
|
|
}
|
2005-05-19 10:03:10 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case ShowOptions::index:
|
2001-05-23 15:26:42 +02:00
|
|
|
if (*cmd[2] == '"')
|
|
|
|
{
|
|
|
|
remove_delimited_double_quotes(lcmd[2]);
|
|
|
|
ret = show_indices(lcmd);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ret = show_indices(cmd);
|
|
|
|
}
|
|
|
|
|
2005-05-19 10:03:10 +02:00
|
|
|
if (ret == OBJECT_NOT_FOUND)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
if (*cmd[2])
|
|
|
|
{
|
2003-11-30 07:41:29 +01:00
|
|
|
FOR FIRST 1 R IN RDB$RELATIONS WITH R.RDB$RELATION_NAME EQ cmd[2];
|
|
|
|
key = NO_INDICES_ON_REL;
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
// Ignore any error
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
|
|
|
if (!key)
|
|
|
|
key = NO_REL_OR_INDEX;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
key = NO_INDICES;
|
|
|
|
}
|
|
|
|
}
|
2005-05-19 10:03:10 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case ShowOptions::domain:
|
2001-05-23 15:26:42 +02:00
|
|
|
if (*cmd[2] == '"')
|
|
|
|
{
|
|
|
|
remove_delimited_double_quotes(lcmd[2]);
|
|
|
|
ret = show_domains(lcmd[2]);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ret = show_domains(cmd[2]);
|
|
|
|
|
2005-05-19 10:03:10 +02:00
|
|
|
if (ret == OBJECT_NOT_FOUND) {
|
2001-05-23 15:26:42 +02:00
|
|
|
if (*cmd[2])
|
|
|
|
key = NO_DOMAIN;
|
|
|
|
else
|
|
|
|
key = NO_DOMAINS;
|
|
|
|
}
|
2005-05-19 10:03:10 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case ShowOptions::exception:
|
2001-05-23 15:26:42 +02:00
|
|
|
if (*cmd[2] == '"') {
|
|
|
|
remove_delimited_double_quotes(lcmd[2]);
|
|
|
|
ret = show_exceptions(lcmd[2]);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ret = show_exceptions(cmd[2]);
|
|
|
|
|
2005-05-19 10:03:10 +02:00
|
|
|
if (ret == OBJECT_NOT_FOUND) {
|
2001-05-23 15:26:42 +02:00
|
|
|
if (*cmd[2])
|
|
|
|
key = NO_EXCEPTION;
|
|
|
|
else
|
|
|
|
key = NO_EXCEPTIONS;
|
|
|
|
}
|
2005-05-19 10:03:10 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case ShowOptions::filter:
|
2001-05-23 15:26:42 +02:00
|
|
|
if (*cmd[2] == '"') {
|
|
|
|
remove_delimited_double_quotes(lcmd[2]);
|
|
|
|
ret = show_filters(lcmd[2]);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ret = show_filters(cmd[2]);
|
|
|
|
|
2005-05-19 10:03:10 +02:00
|
|
|
if (ret == OBJECT_NOT_FOUND) {
|
2001-05-23 15:26:42 +02:00
|
|
|
if (*cmd[2])
|
|
|
|
key = NO_FILTER;
|
|
|
|
else
|
|
|
|
key = NO_FILTERS;
|
|
|
|
}
|
2005-05-19 10:03:10 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case ShowOptions::function:
|
2001-05-23 15:26:42 +02:00
|
|
|
if (*cmd[2] == '"') {
|
|
|
|
remove_delimited_double_quotes(lcmd[2]);
|
|
|
|
ret = show_functions(lcmd[2]);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ret = show_functions(cmd[2]);
|
|
|
|
|
2005-05-19 10:03:10 +02:00
|
|
|
if (ret == OBJECT_NOT_FOUND) {
|
2001-05-23 15:26:42 +02:00
|
|
|
if (*cmd[2])
|
|
|
|
key = NO_FUNCTION;
|
|
|
|
else
|
|
|
|
key = NO_FUNCTIONS;
|
|
|
|
}
|
2005-05-19 10:03:10 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case ShowOptions::generator:
|
2001-05-23 15:26:42 +02:00
|
|
|
if (*cmd[2] == '"') {
|
|
|
|
remove_delimited_double_quotes(lcmd[2]);
|
|
|
|
ret = show_generators(lcmd[2]);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ret = show_generators(cmd[2]);
|
|
|
|
|
2005-05-19 10:03:10 +02:00
|
|
|
if (ret == OBJECT_NOT_FOUND) {
|
2001-05-23 15:26:42 +02:00
|
|
|
if (*cmd[2])
|
|
|
|
key = NO_GEN;
|
|
|
|
else
|
|
|
|
key = NO_GENS;
|
|
|
|
}
|
2005-05-19 10:03:10 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case ShowOptions::grant:
|
2001-05-23 15:26:42 +02:00
|
|
|
if (*cmd[2]) {
|
|
|
|
if (*cmd[2] == '"') {
|
|
|
|
remove_delimited_double_quotes(lcmd[2]);
|
|
|
|
strcpy(SQL_id_for_grant, lcmd[2]);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
strcpy(SQL_id_for_grant, cmd[2]);
|
2003-11-30 07:41:29 +01:00
|
|
|
ret = SHOW_grants (SQL_id_for_grant, "", 255);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
2002-06-29 15:39:11 +02:00
|
|
|
else {
|
2001-05-23 15:26:42 +02:00
|
|
|
strcpy(SQL_id_for_grant, cmd[2]);
|
2003-11-30 07:41:29 +01:00
|
|
|
ret = EXTRACT_list_grants ("");
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2005-05-19 10:03:10 +02:00
|
|
|
if (ret == OBJECT_NOT_FOUND) {
|
2003-11-30 07:41:29 +01:00
|
|
|
if (*cmd[2]) {
|
|
|
|
FOR FIRST 1 R IN RDB$RELATIONS
|
|
|
|
WITH R.RDB$RELATION_NAME EQ SQL_id_for_grant;
|
2002-06-29 15:39:11 +02:00
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
key = NO_GRANT_ON_REL;
|
|
|
|
END_FOR
|
2004-04-23 20:39:04 +02:00
|
|
|
ON_ERROR
|
2003-11-30 07:41:29 +01:00
|
|
|
// Ignore any error
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
2003-11-30 07:41:29 +01:00
|
|
|
if (!key) {
|
|
|
|
FOR FIRST 1 P IN RDB$PROCEDURES
|
|
|
|
WITH P.RDB$PROCEDURE_NAME EQ SQL_id_for_grant;
|
|
|
|
|
|
|
|
key = NO_GRANT_ON_PROC;
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
// Ignore any error
|
2004-04-23 20:39:04 +02:00
|
|
|
END_ERROR;
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
|
|
|
if (!key) {
|
|
|
|
FOR FIRST 1 R IN RDB$ROLES WITH R.RDB$ROLE_NAME EQ SQL_id_for_grant;
|
|
|
|
key = NO_GRANT_ON_ROL;
|
|
|
|
END_FOR
|
2004-04-23 20:39:04 +02:00
|
|
|
ON_ERROR
|
2003-11-30 07:41:29 +01:00
|
|
|
// Ignore any error
|
2004-04-23 20:39:04 +02:00
|
|
|
END_ERROR;
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
|
|
|
if (!key)
|
|
|
|
key = NO_REL_OR_PROC_OR_ROLE;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
key = NO_GRANT_ON_ANY;
|
|
|
|
}
|
|
|
|
}
|
2005-05-19 10:03:10 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case ShowOptions::procedure:
|
2001-05-23 15:26:42 +02:00
|
|
|
if (*cmd[2] == '"') {
|
|
|
|
remove_delimited_double_quotes(lcmd[2]);
|
|
|
|
ret = show_proc(lcmd[2]);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ret = show_proc(cmd[2]);
|
|
|
|
|
2005-05-19 10:03:10 +02:00
|
|
|
if (ret == OBJECT_NOT_FOUND) {
|
2001-05-23 15:26:42 +02:00
|
|
|
if (*cmd[2])
|
|
|
|
key = NO_PROC;
|
|
|
|
else
|
|
|
|
key = NO_PROCS;
|
|
|
|
}
|
2005-05-19 10:03:10 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case ShowOptions::trigger:
|
2001-05-23 15:26:42 +02:00
|
|
|
if (*cmd[2] == '"') {
|
|
|
|
remove_delimited_double_quotes(lcmd[2]);
|
2004-04-23 20:39:04 +02:00
|
|
|
ret = show_trigger(lcmd[2], true, true);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
else
|
2004-04-23 20:39:04 +02:00
|
|
|
ret = show_trigger(cmd[2], true, true);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2005-05-19 10:03:10 +02:00
|
|
|
if (ret == OBJECT_NOT_FOUND)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
if (*cmd[2]) {
|
2003-11-30 07:41:29 +01:00
|
|
|
FOR FIRST 1 R IN RDB$RELATIONS WITH R.RDB$RELATION_NAME EQ cmd[2];
|
|
|
|
key = NO_TRIGGERS_ON_REL;
|
|
|
|
END_FOR
|
2001-05-23 15:26:42 +02:00
|
|
|
ON_ERROR
|
2003-11-30 07:41:29 +01:00
|
|
|
// Ignore any error
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
|
|
|
if (!key)
|
|
|
|
key = NO_REL_OR_TRIGGER;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
key = NO_TRIGGERS;
|
2005-05-19 10:03:10 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ShowOptions::check:
|
2001-05-23 15:26:42 +02:00
|
|
|
if (*cmd[2] == '"') {
|
|
|
|
remove_delimited_double_quotes(lcmd[2]);
|
|
|
|
ret = show_check(lcmd[2]);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ret = show_check(cmd[2]);
|
|
|
|
|
2005-05-19 10:03:10 +02:00
|
|
|
if (ret == OBJECT_NOT_FOUND) {
|
2001-05-23 15:26:42 +02:00
|
|
|
if (*cmd[2]) {
|
2003-11-30 07:41:29 +01:00
|
|
|
FOR FIRST 1 R IN RDB$RELATIONS WITH R.RDB$RELATION_NAME EQ cmd[2];
|
|
|
|
key = NO_CHECKS_ON_REL;
|
|
|
|
END_FOR
|
2001-05-23 15:26:42 +02:00
|
|
|
ON_ERROR
|
2003-11-30 07:41:29 +01:00
|
|
|
// Ignore any error
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
|
|
|
}
|
|
|
|
if (!key)
|
|
|
|
key = NO_TABLE;
|
|
|
|
}
|
2005-05-19 10:03:10 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case ShowOptions::database:
|
2001-05-23 15:26:42 +02:00
|
|
|
show_db();
|
2005-05-19 10:03:10 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case ShowOptions::comment:
|
2005-05-20 10:34:19 +02:00
|
|
|
ret = show_comments(cmmShow, 0);
|
2005-05-19 10:03:10 +02:00
|
|
|
if (ret == OBJECT_NOT_FOUND)
|
|
|
|
key = NO_COMMENTS;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return ps_ERR;
|
|
|
|
} // switch
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2005-05-19 10:03:10 +02:00
|
|
|
if (ret == OBJECT_NOT_FOUND) {
|
2003-11-30 07:41:29 +01:00
|
|
|
TEXT key_string[MSG_LENGTH];
|
2001-05-23 15:26:42 +02:00
|
|
|
if (*cmd[2] == '"')
|
2005-03-31 09:50:32 +02:00
|
|
|
ISQL_msg_get(key, key_string, lcmd[2]);
|
2001-05-23 15:26:42 +02:00
|
|
|
else
|
2005-03-31 09:50:32 +02:00
|
|
|
ISQL_msg_get(key, key_string, cmd[2]);
|
2005-03-26 06:33:55 +01:00
|
|
|
STDERROUT(key_string);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2005-05-19 10:03:10 +02:00
|
|
|
return ret;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-12-22 11:00:59 +01:00
|
|
|
static void local_fprintf(void* format_ignored,
|
2003-09-05 13:25:53 +02:00
|
|
|
const char* string)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* l o c a l _ p r i n t f
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
2004-05-24 19:16:02 +02:00
|
|
|
* Used to make sure that local calls to print stuff go to isqlGlob.Out
|
2005-01-04 06:42:26 +01:00
|
|
|
* and not to stdout if isc_version gets called.
|
2001-05-23 15:26:42 +02:00
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf("%s%s", string, NEWLINE);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-12-24 03:51:06 +01:00
|
|
|
static void remove_delimited_double_quotes(TEXT* string)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* r e m o v e _ d e l i m i t e d _ d o u b l e _ q u o t e s
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
2003-11-30 07:41:29 +01:00
|
|
|
* Remove the delimited double quotes. Blanks could be part of
|
|
|
|
* delimited SQL identifier. Unescape embedded double quotes.
|
2001-05-23 15:26:42 +02:00
|
|
|
*
|
|
|
|
**************************************/
|
2003-11-30 07:41:29 +01:00
|
|
|
ISQL_remove_and_unescape_quotes(string, DBL_QUOTE);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-09-05 13:25:53 +02:00
|
|
|
static void make_priv_string(USHORT flags,
|
2003-11-30 07:41:29 +01:00
|
|
|
char* string)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* m a k e _ p r i v _ s t r i n g
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
2003-11-30 07:41:29 +01:00
|
|
|
* Given a bit-vector of privileges, turn it into a
|
2001-05-23 15:26:42 +02:00
|
|
|
* string list.
|
|
|
|
*
|
|
|
|
**************************************/
|
2003-11-30 07:41:29 +01:00
|
|
|
for (int i = 0; privs[i].priv_string; i++) {
|
2001-05-23 15:26:42 +02:00
|
|
|
if (flags & privs[i].priv_flag) {
|
|
|
|
if (*string)
|
2003-11-30 07:41:29 +01:00
|
|
|
strcat(string, ", ");
|
|
|
|
strcat(string, privs[i].priv_string);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-01-04 06:42:26 +01:00
|
|
|
static processing_state show_all_tables(SSHORT sys_flag)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* s h o w _ a l l _ t a b l e s
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Print the names of all user tables from
|
2003-11-30 07:41:29 +01:00
|
|
|
* rdb$relations. We use a dynamic query
|
2001-05-23 15:26:42 +02:00
|
|
|
*
|
2005-01-04 06:42:26 +01:00
|
|
|
* Parameters: sys_flag -- 0, show user tables
|
2003-09-09 13:03:37 +02:00
|
|
|
* 1, show system tables only; -1, show views only
|
2001-05-23 15:26:42 +02:00
|
|
|
*
|
|
|
|
**************************************/
|
2003-09-09 13:03:37 +02:00
|
|
|
bool odd = true;
|
2003-09-05 13:25:53 +02:00
|
|
|
bool first = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2005-01-04 06:42:26 +01:00
|
|
|
if (sys_flag == -1) {
|
2003-11-30 07:41:29 +01:00
|
|
|
// Views
|
2004-04-23 20:39:04 +02:00
|
|
|
FOR REL IN RDB$RELATIONS WITH
|
2003-11-30 07:41:29 +01:00
|
|
|
REL.RDB$VIEW_BLR NOT MISSING
|
|
|
|
SORTED BY REL.RDB$RELATION_NAME
|
|
|
|
|
|
|
|
first = false;
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%38s%s", REL.RDB$RELATION_NAME, (odd ? " " : NEWLINE));
|
2004-04-23 20:39:04 +02:00
|
|
|
odd = !odd;
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
END_FOR
|
2003-11-30 07:41:29 +01:00
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
2005-05-14 16:50:41 +02:00
|
|
|
return ps_ERR;
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
|
|
|
}
|
2004-04-23 20:39:04 +02:00
|
|
|
// 23-Apr-2004 (only tables)
|
2001-05-23 15:26:42 +02:00
|
|
|
else {
|
2005-01-04 06:42:26 +01:00
|
|
|
// The rdb$system_flag is not always set for non-system objects... this
|
2004-04-23 20:39:04 +02:00
|
|
|
// query may potentially fail.
|
2003-11-30 07:41:29 +01:00
|
|
|
FOR REL IN RDB$RELATIONS WITH
|
2005-01-04 06:42:26 +01:00
|
|
|
(REL.RDB$SYSTEM_FLAG EQ sys_flag
|
|
|
|
/*OR (sys_flag == 0 AND REL.RDB$SYSTEM_FLAG MISSING)*/)
|
2004-04-23 20:39:04 +02:00
|
|
|
AND REL.RDB$VIEW_BLR MISSING
|
2003-11-30 07:41:29 +01:00
|
|
|
SORTED BY REL.RDB$RELATION_NAME
|
|
|
|
|
|
|
|
first = false;
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%38s%s", REL.RDB$RELATION_NAME, (odd ? " " : NEWLINE));
|
2004-04-23 20:39:04 +02:00
|
|
|
odd = !odd;
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
END_FOR
|
2003-11-30 07:41:29 +01:00
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
2005-05-14 16:50:41 +02:00
|
|
|
return ps_ERR;
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!first) {
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf(NEWLINE);
|
2001-05-23 15:26:42 +02:00
|
|
|
return SKIP;
|
|
|
|
}
|
|
|
|
else
|
2003-12-03 09:19:24 +01:00
|
|
|
return OBJECT_NOT_FOUND;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2005-05-19 10:03:10 +02:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
static void show_charsets(
|
|
|
|
const SCHAR* relation_name,
|
|
|
|
const SCHAR* field_name,
|
|
|
|
bool show_charset,
|
|
|
|
bool show_collation,
|
|
|
|
bool doIndent,
|
|
|
|
bool doReturn)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-11-30 07:41:29 +01:00
|
|
|
/*************************************
|
2001-05-23 15:26:42 +02:00
|
|
|
*
|
|
|
|
* s h o w _ c h a r s e t s
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
2004-04-23 20:39:04 +02:00
|
|
|
* Show character set and collations
|
2001-05-23 15:26:42 +02:00
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
SSHORT collation, char_set_id;
|
2003-09-29 14:43:14 +02:00
|
|
|
const SSHORT default_char_set_id = ISQL_get_default_char_set_id();
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
// If there is a relation_name, this is a real column, look up collation
|
2004-03-07 08:58:55 +01:00
|
|
|
// in rdb$relation_fields
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
if (relation_name) {
|
|
|
|
FOR RRF IN RDB$RELATION_FIELDS CROSS
|
2003-11-30 07:41:29 +01:00
|
|
|
FLD IN RDB$FIELDS
|
|
|
|
WITH RRF.RDB$FIELD_NAME EQ field_name AND
|
|
|
|
RRF.RDB$RELATION_NAME EQ relation_name AND
|
|
|
|
RRF.RDB$FIELD_SOURCE EQ FLD.RDB$FIELD_NAME
|
|
|
|
|
|
|
|
char_set_id = 0;
|
|
|
|
if (!FLD.RDB$CHARACTER_SET_ID.NULL)
|
|
|
|
char_set_id = FLD.RDB$CHARACTER_SET_ID;
|
|
|
|
collation = 0;
|
2004-04-23 20:39:04 +02:00
|
|
|
if (!RRF.RDB$COLLATION_ID.NULL)
|
2003-11-30 07:41:29 +01:00
|
|
|
collation = RRF.RDB$COLLATION_ID;
|
2004-04-23 20:39:04 +02:00
|
|
|
else if (!FLD.RDB$COLLATION_ID.NULL)
|
2003-11-30 07:41:29 +01:00
|
|
|
collation = FLD.RDB$COLLATION_ID;
|
|
|
|
END_FOR
|
2001-05-23 15:26:42 +02:00
|
|
|
ON_ERROR
|
|
|
|
#ifdef DEV_BUILD
|
2004-04-29 00:36:29 +02:00
|
|
|
fprintf(stderr, "show_charsets(%s %s) failed\n",
|
2001-05-23 15:26:42 +02:00
|
|
|
relation_name, field_name);
|
|
|
|
#endif
|
|
|
|
END_ERROR;
|
|
|
|
}
|
2004-04-23 20:39:04 +02:00
|
|
|
else {
|
|
|
|
FOR FLD IN RDB$FIELDS WITH
|
|
|
|
FLD.RDB$FIELD_NAME EQ field_name
|
|
|
|
|
|
|
|
char_set_id = 0;
|
|
|
|
collation = 0;
|
|
|
|
if (!FLD.RDB$CHARACTER_SET_ID.NULL)
|
|
|
|
char_set_id = FLD.RDB$CHARACTER_SET_ID;
|
|
|
|
if (!FLD.RDB$COLLATION_ID.NULL)
|
|
|
|
collation = FLD.RDB$COLLATION_ID;
|
|
|
|
END_FOR
|
2001-05-23 15:26:42 +02:00
|
|
|
ON_ERROR
|
|
|
|
#ifdef DEV_BUILD
|
2004-04-29 00:36:29 +02:00
|
|
|
fprintf(stderr, "show_charsets(NULL %s) failed\n",
|
2001-05-23 15:26:42 +02:00
|
|
|
field_name);
|
|
|
|
#endif
|
|
|
|
END_ERROR;
|
|
|
|
}
|
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
TEXT char_sets[86]; /* CHARACTER SET <name31> COLLATE <name31> */
|
2001-05-23 15:26:42 +02:00
|
|
|
char_sets[0] = 0;
|
2004-05-09 07:48:33 +02:00
|
|
|
if ((char_set_id != default_char_set_id) || collation) {
|
2004-04-23 20:39:04 +02:00
|
|
|
if (show_charset && !show_collation)
|
2004-04-24 16:38:27 +02:00
|
|
|
ISQL_get_character_sets(char_set_id, 0, false, char_sets);
|
2004-04-23 20:39:04 +02:00
|
|
|
else if (!show_charset && show_collation)
|
|
|
|
ISQL_get_character_sets(char_set_id, collation, true, char_sets);
|
|
|
|
else
|
|
|
|
ISQL_get_character_sets(char_set_id, collation, false, char_sets);
|
|
|
|
}
|
2004-05-09 07:48:33 +02:00
|
|
|
if (char_sets[0]) {
|
2004-04-23 20:39:04 +02:00
|
|
|
if (doIndent)
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf(spaces);
|
|
|
|
isqlGlob.prints(char_sets);
|
2004-04-23 20:39:04 +02:00
|
|
|
if (doReturn)
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf(NEWLINE);
|
2004-04-23 20:39:04 +02:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-12-03 09:19:24 +01:00
|
|
|
static processing_state show_check(const SCHAR* object)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* s h o w _ c h e c k
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Show check constraints for the named object
|
|
|
|
*
|
|
|
|
**************************************/
|
2003-09-05 13:25:53 +02:00
|
|
|
bool first = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (!*object)
|
2005-05-19 10:03:10 +02:00
|
|
|
return ps_ERR;
|
2003-11-30 07:41:29 +01:00
|
|
|
// Query gets the check clauses for triggers stored for check constraints
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
FOR TRG IN RDB$TRIGGERS CROSS
|
2004-04-23 20:39:04 +02:00
|
|
|
CHK IN RDB$CHECK_CONSTRAINTS WITH
|
|
|
|
TRG.RDB$TRIGGER_TYPE EQ 1 AND
|
|
|
|
TRG.RDB$TRIGGER_NAME EQ CHK.RDB$TRIGGER_NAME AND
|
|
|
|
CHK.RDB$TRIGGER_NAME STARTING WITH "CHECK" AND
|
|
|
|
TRG.RDB$RELATION_NAME EQ object
|
|
|
|
SORTED BY CHK.RDB$CONSTRAINT_NAME
|
|
|
|
|
|
|
|
// Use print_blob to print the blob
|
|
|
|
first = false;
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("CONSTRAINT %s:%s ",
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(CHK.RDB$CONSTRAINT_NAME), NEWLINE);
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
if (!TRG.RDB$TRIGGER_SOURCE.NULL)
|
2004-05-24 19:16:02 +02:00
|
|
|
SHOW_print_metadata_text_blob (isqlGlob.Out, &TRG.RDB$TRIGGER_SOURCE);
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf(NEWLINE);
|
2003-11-30 07:41:29 +01:00
|
|
|
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
2005-05-19 10:03:10 +02:00
|
|
|
return ps_ERR;
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
|
|
|
if (first)
|
2003-12-03 09:19:24 +01:00
|
|
|
return (OBJECT_NOT_FOUND);
|
2001-05-23 15:26:42 +02:00
|
|
|
return (SKIP);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-05-19 10:03:10 +02:00
|
|
|
// ***********************
|
|
|
|
// s h o w _ c o m m e n t
|
|
|
|
// ***********************
|
|
|
|
// Helper that displays in correct syntax the COMMENT ON command for each object.
|
|
|
|
// It escapes identifiers with embedded double quotes and escapes the comment
|
2005-05-20 10:34:19 +02:00
|
|
|
// itself if it contains single quotes when we are honoring script extraction.
|
2005-05-19 10:03:10 +02:00
|
|
|
static void show_comment(const char* objtype, char* name1, char* name2,
|
2005-05-20 10:34:19 +02:00
|
|
|
ISC_QUAD* blobfld, const commentMode showextract, const char* banner)
|
2005-05-19 10:03:10 +02:00
|
|
|
{
|
2005-05-20 10:34:19 +02:00
|
|
|
const bool escape_quotes = showextract == cmmExtract;
|
|
|
|
|
|
|
|
if (escape_quotes && banner)
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.prints(banner);
|
2005-05-19 10:03:10 +02:00
|
|
|
|
|
|
|
if (name1)
|
|
|
|
fb_utils::exact_name(name1);
|
2005-05-20 10:34:19 +02:00
|
|
|
if (name2)
|
|
|
|
fb_utils::exact_name(name2);
|
|
|
|
|
|
|
|
char SQL_identifier2[BUFFER_LENGTH128];
|
|
|
|
if (escape_quotes && isqlGlob.db_SQL_dialect > SQL_DIALECT_V6_TRANSITION)
|
|
|
|
{
|
|
|
|
if (name1)
|
2005-05-19 10:03:10 +02:00
|
|
|
{
|
|
|
|
ISQL_copy_SQL_id (name1, SQL_identifier, DBL_QUOTE);
|
|
|
|
name1 = SQL_identifier;
|
|
|
|
}
|
2005-05-20 10:34:19 +02:00
|
|
|
if (name2)
|
2005-05-19 10:03:10 +02:00
|
|
|
{
|
|
|
|
ISQL_copy_SQL_id (name2, SQL_identifier2, DBL_QUOTE);
|
|
|
|
name2 = SQL_identifier2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-05-20 10:34:19 +02:00
|
|
|
const char* quot = escape_quotes ? "'" : "";
|
|
|
|
|
2005-05-19 10:03:10 +02:00
|
|
|
if (!name1)
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf("COMMENT ON %-12s IS %s", objtype, quot);
|
2005-05-19 10:03:10 +02:00
|
|
|
else if (!name2)
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf("COMMENT ON %-12s %s IS %s", objtype, name1, quot);
|
2005-05-19 10:03:10 +02:00
|
|
|
else
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf("COMMENT ON %-12s %s.%s IS %s", objtype, name1, name2, quot);
|
2005-05-19 10:03:10 +02:00
|
|
|
|
2005-05-20 10:34:19 +02:00
|
|
|
SHOW_print_metadata_text_blob(isqlGlob.Out, blobfld, escape_quotes);
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf("%s%s%s", quot, isqlGlob.global_Term, NEWLINE);
|
2005-05-19 10:03:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// *************************
|
|
|
|
// s h o w _ c o m m e n t s
|
|
|
|
// *************************
|
|
|
|
// Will extract and show descriptions (comments) for all supported db objects.
|
|
|
|
// This function does its task even if the server version doesn't support
|
|
|
|
// the COMMENT ON command. It will however skip generators and roles that
|
|
|
|
// didn't have description fields before ODS11.
|
|
|
|
// It will extract the main objects by category and inside each category,
|
|
|
|
// in alphabetical order. For tables and views, their fields are printed
|
|
|
|
// immediately after the table/field in rdb$field_position order, that's
|
|
|
|
// the order the users sees when doing a select * from tbl/view. For procedures,
|
|
|
|
// their parameters are printed immediately after the procedure, first the input
|
|
|
|
// params by position, the the output params by position. All system objects
|
|
|
|
// as well as implicit domains and implicit triggers are skipped. For ODS < 11,
|
|
|
|
// we skip generators and roles because those system tables didn't have a
|
|
|
|
// rdb$description field.
|
2005-05-20 10:34:19 +02:00
|
|
|
// When showing comments, we don't escape quotes in neither names nor strings.
|
|
|
|
// When extracting comments, we do the usual escaping to make the script valid.
|
|
|
|
static processing_state show_comments(const commentMode showextract, const char* banner)
|
2005-05-19 10:03:10 +02:00
|
|
|
{
|
|
|
|
// From dsql.h:
|
|
|
|
// ddl_database, ddl_domain, ddl_relation, ddl_view, ddl_procedure, ddl_trigger,
|
|
|
|
// ddl_udf, ddl_blob_filter, ddl_exception, ddl_generator, ddl_index, ddl_role,
|
|
|
|
// ddl_charset, ddl_collation//, ddl_sec_class
|
|
|
|
|
|
|
|
bool first = true;
|
|
|
|
|
|
|
|
FOR FIRST 1 DT IN RDB$DATABASE
|
|
|
|
WITH DT.RDB$DESCRIPTION NOT MISSING
|
|
|
|
|
2005-05-20 10:34:19 +02:00
|
|
|
show_comment("DATABASE", 0, 0, &DT.RDB$DESCRIPTION, showextract, first ? banner : 0);
|
2005-05-19 10:03:10 +02:00
|
|
|
first = false;
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
|
|
|
return ps_ERR;
|
|
|
|
END_ERROR
|
|
|
|
|
|
|
|
FOR DM IN RDB$FIELDS
|
|
|
|
WITH DM.RDB$FIELD_NAME NOT MATCHING "RDB$+" USING "+=[0-9][0-9]* *"
|
|
|
|
AND (DM.RDB$SYSTEM_FLAG EQ 0 OR DM.RDB$SYSTEM_FLAG MISSING)
|
|
|
|
AND DM.RDB$DESCRIPTION NOT MISSING
|
|
|
|
SORTED BY DM.RDB$FIELD_NAME
|
|
|
|
|
|
|
|
show_comment("DOMAIN", DM.RDB$FIELD_NAME, 0, &DM.RDB$DESCRIPTION,
|
2005-05-20 10:34:19 +02:00
|
|
|
showextract, first ? banner : 0);
|
2005-05-19 10:03:10 +02:00
|
|
|
first = false;
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
|
|
|
return ps_ERR;
|
|
|
|
END_ERROR
|
|
|
|
|
|
|
|
FOR RL IN RDB$RELATIONS
|
|
|
|
WITH RL.RDB$VIEW_BLR MISSING
|
|
|
|
AND (RL.RDB$SYSTEM_FLAG EQ 0 OR RL.RDB$SYSTEM_FLAG MISSING)
|
|
|
|
SORTED BY RL.RDB$RELATION_NAME
|
|
|
|
|
|
|
|
if (!RL.RDB$DESCRIPTION.NULL && !blobIsNull(&RL.RDB$DESCRIPTION))
|
|
|
|
{
|
|
|
|
show_comment("TABLE", RL.RDB$RELATION_NAME, 0, &RL.RDB$DESCRIPTION,
|
2005-05-20 10:34:19 +02:00
|
|
|
showextract, first ? banner : 0);
|
2005-05-19 10:03:10 +02:00
|
|
|
first = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
FOR RF IN RDB$RELATION_FIELDS
|
|
|
|
WITH RF.RDB$RELATION_NAME = RL.RDB$RELATION_NAME
|
|
|
|
AND RF.RDB$DESCRIPTION NOT MISSING
|
|
|
|
SORTED BY RF.RDB$FIELD_POSITION
|
|
|
|
|
2005-05-20 10:34:19 +02:00
|
|
|
show_comment(" COLUMN", RL.RDB$RELATION_NAME, RF.RDB$FIELD_NAME,
|
|
|
|
&RF.RDB$DESCRIPTION, showextract, first ? banner : 0);
|
2005-05-19 10:03:10 +02:00
|
|
|
first = false;
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
|
|
|
return ps_ERR;
|
|
|
|
END_ERROR
|
|
|
|
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
|
|
|
return ps_ERR;
|
|
|
|
END_ERROR
|
|
|
|
|
|
|
|
FOR VW IN RDB$RELATIONS
|
|
|
|
WITH VW.RDB$VIEW_BLR NOT MISSING
|
|
|
|
AND (VW.RDB$SYSTEM_FLAG EQ 0 OR VW.RDB$SYSTEM_FLAG MISSING)
|
|
|
|
SORTED BY VW.RDB$RELATION_NAME
|
|
|
|
|
|
|
|
if (!VW.RDB$DESCRIPTION.NULL && !blobIsNull(&VW.RDB$DESCRIPTION))
|
|
|
|
{
|
|
|
|
show_comment("VIEW", VW.RDB$RELATION_NAME, 0 , &VW.RDB$DESCRIPTION,
|
2005-05-20 10:34:19 +02:00
|
|
|
showextract, first ? banner : 0);
|
2005-05-19 10:03:10 +02:00
|
|
|
first = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
FOR RF IN RDB$RELATION_FIELDS
|
|
|
|
WITH RF.RDB$RELATION_NAME = VW.RDB$RELATION_NAME
|
|
|
|
AND RF.RDB$DESCRIPTION NOT MISSING
|
|
|
|
SORTED BY RF.RDB$FIELD_POSITION
|
|
|
|
|
2005-05-20 10:34:19 +02:00
|
|
|
show_comment(" COLUMN", VW.RDB$RELATION_NAME, RF.RDB$FIELD_NAME,
|
|
|
|
&RF.RDB$DESCRIPTION, showextract, first ? banner : 0);
|
2005-05-19 10:03:10 +02:00
|
|
|
first = false;
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
|
|
|
return ps_ERR;
|
|
|
|
END_ERROR
|
|
|
|
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
|
|
|
return ps_ERR;
|
|
|
|
END_ERROR
|
|
|
|
|
|
|
|
FOR PR IN RDB$PROCEDURES
|
|
|
|
WITH (PR.RDB$SYSTEM_FLAG EQ 0 OR PR.RDB$SYSTEM_FLAG MISSING)
|
|
|
|
SORTED BY PR.RDB$PROCEDURE_NAME
|
|
|
|
|
|
|
|
if (!PR.RDB$DESCRIPTION.NULL && !blobIsNull(&PR.RDB$DESCRIPTION))
|
|
|
|
{
|
|
|
|
show_comment("PROCEDURE", PR.RDB$PROCEDURE_NAME, 0, &PR.RDB$DESCRIPTION,
|
2005-05-20 10:34:19 +02:00
|
|
|
showextract, first ? banner : 0);
|
2005-05-19 10:03:10 +02:00
|
|
|
first = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
FOR PA IN RDB$PROCEDURE_PARAMETERS
|
|
|
|
WITH PA.RDB$PROCEDURE_NAME = PR.RDB$PROCEDURE_NAME
|
|
|
|
AND PA.RDB$DESCRIPTION NOT MISSING
|
|
|
|
SORTED BY PA.RDB$PARAMETER_TYPE, PA.RDB$PARAMETER_NUMBER
|
|
|
|
|
2005-05-20 10:34:19 +02:00
|
|
|
show_comment(" PARAMETER", PR.RDB$PROCEDURE_NAME, PA.RDB$PARAMETER_NAME,
|
|
|
|
&PA.RDB$DESCRIPTION, showextract, first ? banner : 0);
|
2005-05-19 10:03:10 +02:00
|
|
|
first = false;
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
|
|
|
return ps_ERR;
|
|
|
|
END_ERROR
|
|
|
|
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
|
|
|
return ps_ERR;
|
|
|
|
END_ERROR
|
|
|
|
|
|
|
|
FOR TR IN RDB$TRIGGERS
|
|
|
|
WITH TR.RDB$DESCRIPTION NOT MISSING
|
|
|
|
AND (TR.RDB$SYSTEM_FLAG EQ 0 OR TR.RDB$SYSTEM_FLAG MISSING)
|
|
|
|
SORTED BY TR.RDB$TRIGGER_NAME
|
|
|
|
|
|
|
|
show_comment("TRIGGER", TR.RDB$TRIGGER_NAME, 0, &TR.RDB$DESCRIPTION,
|
2005-05-20 10:34:19 +02:00
|
|
|
showextract, first ? banner : 0);
|
2005-05-19 10:03:10 +02:00
|
|
|
first = false;
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
|
|
|
return ps_ERR;
|
|
|
|
END_ERROR
|
|
|
|
|
|
|
|
FOR UD IN RDB$FUNCTIONS
|
|
|
|
WITH UD.RDB$DESCRIPTION NOT MISSING
|
|
|
|
AND (UD.RDB$SYSTEM_FLAG EQ 0 OR UD.RDB$SYSTEM_FLAG MISSING)
|
|
|
|
SORTED BY UD.RDB$FUNCTION_NAME
|
|
|
|
|
|
|
|
show_comment("EXTERNAL FUNCTION", UD.RDB$FUNCTION_NAME, 0,
|
2005-05-20 10:34:19 +02:00
|
|
|
&UD.RDB$DESCRIPTION, showextract, first ? banner : 0);
|
2005-05-19 10:03:10 +02:00
|
|
|
first = false;
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
|
|
|
return ps_ERR;
|
|
|
|
END_ERROR
|
|
|
|
|
|
|
|
FOR BF IN RDB$FILTERS
|
|
|
|
WITH BF.RDB$DESCRIPTION NOT MISSING
|
|
|
|
AND (BF.RDB$SYSTEM_FLAG EQ 0 OR BF.RDB$SYSTEM_FLAG MISSING)
|
|
|
|
SORTED BY BF.RDB$FUNCTION_NAME
|
|
|
|
|
|
|
|
show_comment("FILTER", BF.RDB$FUNCTION_NAME, 0, &BF.RDB$DESCRIPTION,
|
2005-05-20 10:34:19 +02:00
|
|
|
showextract, first ? banner : 0);
|
2005-05-19 10:03:10 +02:00
|
|
|
first = false;
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
|
|
|
return ps_ERR;
|
|
|
|
END_ERROR
|
|
|
|
|
|
|
|
FOR XC IN RDB$EXCEPTIONS
|
|
|
|
WITH XC.RDB$DESCRIPTION NOT MISSING
|
|
|
|
AND (XC.RDB$SYSTEM_FLAG EQ 0 OR XC.RDB$SYSTEM_FLAG MISSING)
|
|
|
|
SORTED BY XC.RDB$EXCEPTION_NAME
|
|
|
|
|
|
|
|
show_comment("EXCEPTION", XC.RDB$EXCEPTION_NAME, 0, &XC.RDB$DESCRIPTION,
|
2005-05-20 10:34:19 +02:00
|
|
|
showextract, first ? banner : 0);
|
2005-05-19 10:03:10 +02:00
|
|
|
first = false;
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
|
|
|
return ps_ERR;
|
|
|
|
END_ERROR
|
|
|
|
|
|
|
|
if (isqlGlob.major_ods >= ODS_VERSION11)
|
|
|
|
{
|
|
|
|
FOR GR IN RDB$GENERATORS
|
|
|
|
WITH GR.RDB$DESCRIPTION NOT MISSING
|
|
|
|
AND (GR.RDB$SYSTEM_FLAG EQ 0 OR GR.RDB$SYSTEM_FLAG MISSING)
|
|
|
|
SORTED BY GR.RDB$GENERATOR_NAME
|
|
|
|
|
|
|
|
show_comment("GENERATOR", GR.RDB$GENERATOR_NAME, 0, &GR.RDB$DESCRIPTION,
|
2005-05-20 10:34:19 +02:00
|
|
|
showextract, first ? banner : 0);
|
2005-05-19 10:03:10 +02:00
|
|
|
first = false;
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
|
|
|
return ps_ERR;
|
|
|
|
END_ERROR
|
|
|
|
}
|
|
|
|
|
|
|
|
FOR IX IN RDB$INDICES
|
|
|
|
WITH IX.RDB$DESCRIPTION NOT MISSING
|
|
|
|
AND (IX.RDB$SYSTEM_FLAG EQ 0 OR IX.RDB$SYSTEM_FLAG MISSING)
|
|
|
|
SORTED BY IX.RDB$INDEX_NAME
|
|
|
|
|
|
|
|
show_comment("INDEX", IX.RDB$INDEX_NAME, 0, &IX.RDB$DESCRIPTION,
|
2005-05-20 10:34:19 +02:00
|
|
|
showextract, first ? banner : 0);
|
2005-05-19 10:03:10 +02:00
|
|
|
first = false;
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
|
|
|
return ps_ERR;
|
|
|
|
END_ERROR
|
|
|
|
|
|
|
|
if (isqlGlob.major_ods >= ODS_VERSION11)
|
|
|
|
{
|
|
|
|
FOR RO IN RDB$ROLES
|
|
|
|
WITH RO.RDB$DESCRIPTION NOT MISSING
|
|
|
|
AND (RO.RDB$SYSTEM_FLAG EQ 0 OR RO.RDB$SYSTEM_FLAG MISSING)
|
|
|
|
SORTED BY RO.RDB$ROLE_NAME
|
|
|
|
|
|
|
|
show_comment("ROLE", RO.RDB$ROLE_NAME, 0, &RO.RDB$DESCRIPTION,
|
2005-05-20 10:34:19 +02:00
|
|
|
showextract, first ? banner : 0);
|
2005-05-19 10:03:10 +02:00
|
|
|
first = false;
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
|
|
|
return ps_ERR;
|
|
|
|
END_ERROR
|
|
|
|
}
|
|
|
|
|
|
|
|
FOR CH IN RDB$CHARACTER_SETS
|
|
|
|
WITH CH.RDB$DESCRIPTION NOT MISSING
|
|
|
|
AND (CH.RDB$SYSTEM_FLAG EQ 0 OR CH.RDB$SYSTEM_FLAG MISSING)
|
|
|
|
SORTED BY CH.RDB$CHARACTER_SET_NAME
|
|
|
|
|
|
|
|
show_comment("CHARACTER SET", CH.RDB$CHARACTER_SET_NAME, 0,
|
2005-05-20 10:34:19 +02:00
|
|
|
&CH.RDB$DESCRIPTION, showextract, first ? banner : 0);
|
2005-05-19 10:03:10 +02:00
|
|
|
first = false;
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
|
|
|
return ps_ERR;
|
|
|
|
END_ERROR
|
|
|
|
|
|
|
|
FOR CL IN RDB$COLLATIONS
|
|
|
|
WITH CL.RDB$DESCRIPTION NOT MISSING
|
|
|
|
AND (CL.RDB$SYSTEM_FLAG EQ 0 OR CL.RDB$SYSTEM_FLAG MISSING)
|
|
|
|
SORTED BY CL.RDB$COLLATION_NAME
|
|
|
|
|
|
|
|
show_comment("COLLATION", CL.RDB$COLLATION_NAME, 0, &CL.RDB$DESCRIPTION,
|
2005-05-20 10:34:19 +02:00
|
|
|
showextract, first ? banner : 0);
|
2005-05-19 10:03:10 +02:00
|
|
|
first = false;
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
|
|
|
return ps_ERR;
|
|
|
|
END_ERROR
|
|
|
|
|
|
|
|
return first ? OBJECT_NOT_FOUND : SKIP;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
static void show_db()
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* s h o w _ d b
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Show info on this database. cache, logfiles, etc
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
// First print the name of the database
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("Database: %s%s", isqlGlob.global_Db_name, NEWLINE);
|
2003-11-30 07:41:29 +01:00
|
|
|
// Get the owner name
|
2001-05-23 15:26:42 +02:00
|
|
|
FOR REL IN RDB$RELATIONS WITH
|
2004-04-23 20:39:04 +02:00
|
|
|
REL.RDB$RELATION_NAME = "RDB$DATABASE"
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
if (!REL.RDB$OWNER_NAME.NULL) {
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%sOwner: %s%s", TAB_AS_SPACES, REL.RDB$OWNER_NAME, NEWLINE);
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
END_FOR
|
2003-11-30 07:41:29 +01:00
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
2004-04-23 20:39:04 +02:00
|
|
|
return;
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
// Query for files
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
FOR FIL IN RDB$FILES SORTED BY FIL.RDB$SHADOW_NUMBER, FIL.RDB$FILE_SEQUENCE,
|
2003-11-30 07:41:29 +01:00
|
|
|
FIL.RDB$FILE_SEQUENCE
|
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
// reset nulls to zero
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
if (FIL.RDB$FILE_FLAGS.NULL)
|
2003-11-30 07:41:29 +01:00
|
|
|
FIL.RDB$FILE_FLAGS = 0;
|
|
|
|
if (FIL.RDB$FILE_LENGTH.NULL)
|
|
|
|
FIL.RDB$FILE_LENGTH = 0;
|
2004-04-23 20:39:04 +02:00
|
|
|
if (FIL.RDB$FILE_SEQUENCE.NULL)
|
2003-11-30 07:41:29 +01:00
|
|
|
FIL.RDB$FILE_SEQUENCE = 0;
|
2004-04-23 20:39:04 +02:00
|
|
|
if (FIL.RDB$FILE_START.NULL)
|
2003-11-30 07:41:29 +01:00
|
|
|
FIL.RDB$FILE_START = 0;
|
|
|
|
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(FIL.RDB$FILE_NAME);
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
if (FIL.RDB$FILE_FLAGS == 0) {
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(" File %d: \"%s\", length %ld, start %ld%s",
|
2003-11-30 07:41:29 +01:00
|
|
|
FIL.RDB$FILE_SEQUENCE, FIL.RDB$FILE_NAME,
|
|
|
|
FIL.RDB$FILE_LENGTH, FIL.RDB$FILE_START, NEWLINE);
|
|
|
|
}
|
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
if (FIL.RDB$FILE_FLAGS & FILE_shadow) {
|
2003-11-30 07:41:29 +01:00
|
|
|
if (FIL.RDB$FILE_SEQUENCE) {
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%sfile %s ", TAB_AS_SPACES, FIL.RDB$FILE_NAME);
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
|
|
|
else {
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(" Shadow %d: \"%s\" ",
|
2003-11-30 07:41:29 +01:00
|
|
|
FIL.RDB$SHADOW_NUMBER, FIL.RDB$FILE_NAME);
|
|
|
|
if (FIL.RDB$FILE_FLAGS & FILE_inactive) {
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("inactive ");
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
|
|
|
if (FIL.RDB$FILE_FLAGS & FILE_manual) {
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("manual ");
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
|
|
|
else {
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("auto ");
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
|
|
|
if (FIL.RDB$FILE_FLAGS & FILE_conditional) {
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("conditional ");
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (FIL.RDB$FILE_LENGTH) {
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("length %ld ", FIL.RDB$FILE_LENGTH);
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
|
|
|
if (FIL.RDB$FILE_START) {
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("starting %ld", FIL.RDB$FILE_START);
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf(NEWLINE);
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
END_FOR
|
2003-11-30 07:41:29 +01:00
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
2004-04-23 20:39:04 +02:00
|
|
|
return;
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
|
|
|
|
2005-03-26 06:33:55 +01:00
|
|
|
SCHAR info_buf[BUFFER_LENGTH400];
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2005-05-26 08:45:25 +02:00
|
|
|
// First general database parameters
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-09-29 14:43:14 +02:00
|
|
|
bool translate = true;
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2003-10-29 11:53:47 +01:00
|
|
|
if (SHOW_dbb_parameters(DB, info_buf, db_items, sizeof(db_items), translate)) {
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.prints(info_buf);
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
FOR DBB IN RDB$DATABASE
|
|
|
|
WITH DBB.RDB$CHARACTER_SET_NAME NOT MISSING
|
|
|
|
AND DBB.RDB$CHARACTER_SET_NAME NE " "
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("Default Character set: %s%s",
|
2004-04-23 20:39:04 +02:00
|
|
|
DBB.RDB$CHARACTER_SET_NAME,
|
|
|
|
NEWLINE);
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
|
|
|
return;
|
|
|
|
END_ERROR;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-12-03 09:19:24 +01:00
|
|
|
static processing_state show_dialect()
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* s h o w _ d i a l e c t
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
2003-11-30 07:41:29 +01:00
|
|
|
* Print out the SQL dialect information
|
2001-05-23 15:26:42 +02:00
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
|
2004-05-24 19:16:02 +02:00
|
|
|
if (isqlGlob.db_SQL_dialect > 0) {
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%38s%d%s%d",
|
2004-05-24 19:16:02 +02:00
|
|
|
"Client SQL dialect is set to: ", isqlGlob.SQL_dialect,
|
|
|
|
" and database SQL dialect is: ", isqlGlob.db_SQL_dialect);
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
2004-05-24 19:16:02 +02:00
|
|
|
else if (isqlGlob.SQL_dialect == 0) {
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%38s%s",
|
2001-05-23 15:26:42 +02:00
|
|
|
"Client SQL dialect has not been set",
|
|
|
|
" and no database has been connected yet.");
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
|
|
|
else {
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%38s%d%s",
|
2004-05-24 19:16:02 +02:00
|
|
|
"Client SQL dialect is set to: ", isqlGlob.SQL_dialect,
|
2001-05-23 15:26:42 +02:00
|
|
|
". No database has been connected.");
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf(NEWLINE);
|
2001-05-23 15:26:42 +02:00
|
|
|
return SKIP;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-12-03 09:19:24 +01:00
|
|
|
static processing_state show_domains(const SCHAR* domain_name)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-11-30 07:41:29 +01:00
|
|
|
/*************************************
|
2001-05-23 15:26:42 +02:00
|
|
|
*
|
|
|
|
* s h o w _ d o m a i n s
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Show all domains or the named domain
|
|
|
|
************************************/
|
2003-09-05 13:25:53 +02:00
|
|
|
bool first = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (!*domain_name) {
|
2004-12-04 09:30:43 +01:00
|
|
|
bool odd = true;
|
2003-11-30 07:41:29 +01:00
|
|
|
// List all domain names in columns
|
2004-04-23 20:39:04 +02:00
|
|
|
FOR FLD IN RDB$FIELDS WITH
|
|
|
|
FLD.RDB$FIELD_NAME NOT MATCHING "RDB$+" USING "+=[0-9][0-9]* *"
|
|
|
|
AND FLD.RDB$SYSTEM_FLAG NE 1
|
|
|
|
SORTED BY FLD.RDB$FIELD_NAME
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
first = false;
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%38s%s", FLD.RDB$FIELD_NAME, (odd ? " " : NEWLINE));
|
2004-04-23 20:39:04 +02:00
|
|
|
odd = !odd;
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
2005-05-14 16:50:41 +02:00
|
|
|
return ps_ERR;
|
2004-04-23 20:39:04 +02:00
|
|
|
END_ERROR;
|
2001-05-23 15:26:42 +02:00
|
|
|
if (!first)
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf(NEWLINE);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
2003-11-30 07:41:29 +01:00
|
|
|
else { // List named domain
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
FOR FLD IN RDB$FIELDS WITH
|
2003-11-30 07:41:29 +01:00
|
|
|
FLD.RDB$FIELD_NAME EQ domain_name;
|
|
|
|
|
|
|
|
first = false;
|
|
|
|
// Print the name of the domain
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(FLD.RDB$FIELD_NAME);
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%-32s", FLD.RDB$FIELD_NAME);
|
2003-11-30 07:41:29 +01:00
|
|
|
|
|
|
|
// Array dimensions
|
|
|
|
if (!FLD.RDB$DIMENSIONS.NULL) {
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("ARRAY OF ");
|
2003-11-30 07:41:29 +01:00
|
|
|
ISQL_array_dimensions (FLD.RDB$FIELD_NAME);
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%s ",
|
2003-11-30 07:41:29 +01:00
|
|
|
NEWLINE);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Look through types array
|
|
|
|
|
|
|
|
for (int i = 0; Column_types[i].type; i++)
|
2004-04-23 20:39:04 +02:00
|
|
|
if (FLD.RDB$FIELD_TYPE == Column_types[i].type) {
|
2003-11-30 07:41:29 +01:00
|
|
|
bool precision_known = false;
|
|
|
|
|
2004-05-24 19:16:02 +02:00
|
|
|
if (isqlGlob.major_ods >= ODS_VERSION10) {
|
2003-11-30 07:41:29 +01:00
|
|
|
// Handle Integral subtypes NUMERIC and DECIMAL
|
|
|
|
if ((FLD.RDB$FIELD_TYPE == SMALLINT) ||
|
|
|
|
(FLD.RDB$FIELD_TYPE == INTEGER) ||
|
2004-09-22 03:55:37 +02:00
|
|
|
(FLD.RDB$FIELD_TYPE == BIGINT))
|
2003-11-30 07:41:29 +01:00
|
|
|
{
|
|
|
|
FOR FLD1 IN RDB$FIELDS WITH
|
|
|
|
FLD1.RDB$FIELD_NAME EQ domain_name;
|
|
|
|
/* We are ODS >= 10 and could be any Dialect */
|
|
|
|
if (!FLD1.RDB$FIELD_PRECISION.NULL) {
|
|
|
|
/* We are Dialect >=3 since FIELD_PRECISION
|
|
|
|
is non-NULL */
|
|
|
|
if (FLD1.RDB$FIELD_SUB_TYPE > 0 &&
|
|
|
|
FLD1.RDB$FIELD_SUB_TYPE <= MAX_INTSUBTYPES)
|
|
|
|
{
|
|
|
|
sprintf (Print_buffer, "%s(%d, %d)",
|
|
|
|
Integral_subtypes[FLD1.RDB$FIELD_SUB_TYPE],
|
|
|
|
FLD1.RDB$FIELD_PRECISION,
|
|
|
|
-FLD1.RDB$FIELD_SCALE);
|
|
|
|
precision_known = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg (isc_status);
|
2005-05-14 16:50:41 +02:00
|
|
|
return ps_ERR;
|
2003-11-30 07:41:29 +01:00
|
|
|
END_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!precision_known) {
|
|
|
|
// Take a stab at numerics and decimals
|
|
|
|
if ((FLD.RDB$FIELD_TYPE == SMALLINT) &&
|
|
|
|
(FLD.RDB$FIELD_SCALE < 0))
|
|
|
|
{
|
|
|
|
sprintf (Print_buffer,
|
|
|
|
"NUMERIC(4, %d)",
|
|
|
|
-FLD.RDB$FIELD_SCALE);
|
2004-04-23 20:39:04 +02:00
|
|
|
}
|
2003-11-30 07:41:29 +01:00
|
|
|
else if ((FLD.RDB$FIELD_TYPE == INTEGER) &&
|
|
|
|
(FLD.RDB$FIELD_SCALE < 0))
|
|
|
|
{
|
|
|
|
sprintf (Print_buffer,
|
|
|
|
"NUMERIC(9, %d)",
|
|
|
|
-FLD.RDB$FIELD_SCALE);
|
|
|
|
}
|
|
|
|
else if ((FLD.RDB$FIELD_TYPE == DOUBLE_PRECISION) &&
|
|
|
|
(FLD.RDB$FIELD_SCALE < 0))
|
|
|
|
{
|
|
|
|
sprintf (Print_buffer,
|
|
|
|
"NUMERIC(15, %d)",
|
|
|
|
-FLD.RDB$FIELD_SCALE);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
sprintf (Print_buffer, "%s", Column_types[i].type_name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.prints(Print_buffer);
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
break;
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Length for CHARs
|
2004-04-24 16:38:27 +02:00
|
|
|
if ((FLD.RDB$FIELD_TYPE == T_CHAR) || (FLD.RDB$FIELD_TYPE == VARCHAR)) {
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("(%d)", ISQL_get_field_length(FLD.RDB$FIELD_NAME));
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Blob domains
|
|
|
|
if (FLD.RDB$FIELD_TYPE == BLOB) {
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(" segment %u, subtype ", (USHORT) FLD.RDB$SEGMENT_LENGTH);
|
2004-12-07 01:33:16 +01:00
|
|
|
const int subtype = FLD.RDB$FIELD_SUB_TYPE;
|
2004-05-09 07:48:33 +02:00
|
|
|
if (subtype >= 0 && subtype <= MAX_BLOBSUBTYPES) {
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.prints(Sub_types[subtype]);
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
|
|
|
else {
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%d", subtype);
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
// Show international character sets
|
2004-04-24 16:38:27 +02:00
|
|
|
if (FLD.RDB$FIELD_TYPE == T_CHAR ||
|
2003-11-30 07:41:29 +01:00
|
|
|
FLD.RDB$FIELD_TYPE == VARCHAR ||
|
2004-04-23 20:39:04 +02:00
|
|
|
FLD.RDB$FIELD_TYPE == BLOB)
|
2003-11-30 07:41:29 +01:00
|
|
|
{
|
2004-04-23 20:39:04 +02:00
|
|
|
show_charsets(NULL, FLD.RDB$FIELD_NAME, true, false, false, false);
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
if (FLD.RDB$NULL_FLAG != 1) {
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(" Nullable");
|
2004-04-23 20:39:04 +02:00
|
|
|
}
|
|
|
|
else {
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(" Not Null");
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf(NEWLINE);
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
ISC_QUAD default_source;
|
|
|
|
ISQL_get_default_source (NULL, FLD.RDB$FIELD_NAME,
|
|
|
|
&default_source);
|
|
|
|
if (default_source.gds_quad_high) {
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(" ");
|
2004-05-24 19:16:02 +02:00
|
|
|
SHOW_print_metadata_text_blob (isqlGlob.Out, &default_source);
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf(NEWLINE);
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!FLD.RDB$VALIDATION_SOURCE.NULL) {
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(" ");
|
2004-05-24 19:16:02 +02:00
|
|
|
SHOW_print_metadata_text_blob (isqlGlob.Out, &FLD.RDB$VALIDATION_SOURCE);
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf(NEWLINE);
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
// Show collations
|
2004-04-24 16:38:27 +02:00
|
|
|
if (FLD.RDB$FIELD_TYPE == T_CHAR ||
|
2004-04-23 20:39:04 +02:00
|
|
|
FLD.RDB$FIELD_TYPE == VARCHAR ||
|
|
|
|
FLD.RDB$FIELD_TYPE == BLOB)
|
|
|
|
{
|
|
|
|
show_charsets(NULL, FLD.RDB$FIELD_NAME, false, true, true, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
END_FOR
|
2003-11-30 07:41:29 +01:00
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
2005-05-19 10:03:10 +02:00
|
|
|
return ps_ERR;
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
|
|
|
}
|
|
|
|
if (first)
|
2003-12-03 09:19:24 +01:00
|
|
|
return (OBJECT_NOT_FOUND);
|
2001-05-23 15:26:42 +02:00
|
|
|
return (SKIP);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-12-03 09:19:24 +01:00
|
|
|
static processing_state show_exceptions(const SCHAR* object)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* s h o w _ e x c e p t i o n s
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Show exceptions and their dependencies
|
|
|
|
* This version fetches all the exceptions, and only prints the
|
|
|
|
* one you asked for if you ask for one. It could be optimized
|
|
|
|
* like other such functions.
|
|
|
|
*
|
|
|
|
**************************************/
|
2003-09-05 13:25:53 +02:00
|
|
|
bool first = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
SCHAR type[20];
|
|
|
|
|
2004-09-26 03:49:52 +02:00
|
|
|
//fb_utils::exact_name(object); It already comes trimmed.
|
2003-11-30 07:41:29 +01:00
|
|
|
|
|
|
|
FOR EXC IN RDB$EXCEPTIONS
|
2004-04-23 20:39:04 +02:00
|
|
|
SORTED BY EXC.RDB$EXCEPTION_NAME
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(EXC.RDB$EXCEPTION_NAME);
|
2004-04-23 20:39:04 +02:00
|
|
|
// List all objects if none specified, or just the named exception
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2005-05-26 08:45:25 +02:00
|
|
|
if (!*object || !strcmp (EXC.RDB$EXCEPTION_NAME, object))
|
|
|
|
{
|
2003-11-30 07:41:29 +01:00
|
|
|
if (first) {
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf("Exception Name Used by, Type%s%s%s",
|
|
|
|
NEWLINE,
|
|
|
|
"=============================== =============================================",
|
|
|
|
NEWLINE);
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
|
|
|
first = false;
|
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%-31s ", EXC.RDB$EXCEPTION_NAME);
|
2003-11-30 07:41:29 +01:00
|
|
|
|
|
|
|
// Look up dependent objects --procedures and triggers
|
|
|
|
bool first_dep = true;
|
|
|
|
FOR DEP IN RDB$DEPENDENCIES WITH
|
2005-05-26 08:45:25 +02:00
|
|
|
DEP.RDB$DEPENDED_ON_TYPE = obj_exception AND
|
2003-11-30 07:41:29 +01:00
|
|
|
DEP.RDB$DEPENDED_ON_NAME EQ EXC.RDB$EXCEPTION_NAME
|
|
|
|
SORTED BY DEP.RDB$DEPENDENT_TYPE, DEP.RDB$DEPENDENT_NAME
|
|
|
|
|
|
|
|
if (!first_dep) {
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf("%31s ", "");
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
|
|
|
first_dep = false;
|
|
|
|
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(DEP.RDB$DEPENDENT_NAME);
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2005-05-26 08:45:25 +02:00
|
|
|
switch (DEP.RDB$DEPENDENT_TYPE)
|
|
|
|
{
|
|
|
|
case obj_trigger:
|
|
|
|
strcpy (type, "Trigger");
|
|
|
|
break;
|
|
|
|
case obj_procedure:
|
|
|
|
strcpy (type, "Stored procedure");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
strcpy (type, "Unknown");
|
|
|
|
break;
|
|
|
|
}
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%s, %s%s",
|
2003-11-30 07:41:29 +01:00
|
|
|
DEP.RDB$DEPENDENT_NAME,
|
|
|
|
type,
|
|
|
|
NEWLINE);
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg (isc_status);
|
2005-05-14 16:50:41 +02:00
|
|
|
return ps_ERR;
|
2003-11-30 07:41:29 +01:00
|
|
|
END_ERROR;
|
|
|
|
|
2005-05-26 08:45:25 +02:00
|
|
|
if (first_dep)
|
|
|
|
printf(NEWLINE);
|
|
|
|
|
|
|
|
if (!EXC.RDB$MESSAGE.NULL && strlen(EXC.RDB$MESSAGE))
|
|
|
|
isqlGlob.printf("Msg: %s%s", EXC.RDB$MESSAGE, NEWLINE);
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
2004-04-23 20:39:04 +02:00
|
|
|
if (!first)
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf(NEWLINE);
|
2003-11-30 07:41:29 +01:00
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
2004-04-23 20:39:04 +02:00
|
|
|
ISQL_errmsg(isc_status);
|
2005-05-14 16:50:41 +02:00
|
|
|
return ps_ERR;
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
|
|
|
if (first)
|
2003-12-03 09:19:24 +01:00
|
|
|
return (OBJECT_NOT_FOUND);
|
2001-05-23 15:26:42 +02:00
|
|
|
return (SKIP);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-12-03 09:19:24 +01:00
|
|
|
static processing_state show_filters(const SCHAR* object)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* s h o w _ f i l t e r s
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Show blob filters in general or for the named filters
|
|
|
|
*
|
|
|
|
**************************************/
|
2003-09-05 13:25:53 +02:00
|
|
|
bool first = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
// Show all functions
|
2001-05-23 15:26:42 +02:00
|
|
|
if (!*object) {
|
2004-12-04 09:30:43 +01:00
|
|
|
bool odd = true;
|
2003-09-09 13:03:37 +02:00
|
|
|
FOR FIL IN RDB$FILTERS
|
|
|
|
SORTED BY FIL.RDB$FUNCTION_NAME
|
2003-11-30 07:41:29 +01:00
|
|
|
|
|
|
|
first = false;
|
2005-04-03 08:58:40 +02:00
|
|
|
//fb_utils::exact_name(FIL.RDB$FUNCTION_NAME);
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%38s%s", FIL.RDB$FUNCTION_NAME, (odd ? " " : NEWLINE));
|
2003-11-30 07:41:29 +01:00
|
|
|
odd = !odd;
|
2003-09-09 13:03:37 +02:00
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
2005-05-14 16:50:41 +02:00
|
|
|
return ps_ERR;
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
|
|
|
if (!first) {
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf(NEWLINE);
|
2001-05-23 15:26:42 +02:00
|
|
|
return (SKIP);
|
|
|
|
}
|
|
|
|
else
|
2003-12-03 09:19:24 +01:00
|
|
|
return OBJECT_NOT_FOUND;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
// We have a filter name, so expand on it
|
2001-05-23 15:26:42 +02:00
|
|
|
FOR FIL IN RDB$FILTERS WITH
|
|
|
|
FIL.RDB$FUNCTION_NAME EQ object
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2003-09-05 13:25:53 +02:00
|
|
|
first = false;
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(FIL.RDB$FUNCTION_NAME);
|
|
|
|
fb_utils::exact_name(FIL.RDB$MODULE_NAME);
|
|
|
|
fb_utils::exact_name(FIL.RDB$ENTRYPOINT);
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("BLOB Filter: %s %s%sInput subtype: %d Output subtype: %d%s",
|
2003-11-30 07:41:29 +01:00
|
|
|
FIL.RDB$FUNCTION_NAME, NEWLINE,
|
|
|
|
TAB_AS_SPACES, FIL.RDB$INPUT_SUB_TYPE, FIL.RDB$OUTPUT_SUB_TYPE, NEWLINE);
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%sFilter library is %s%s%sEntry point is %s%s%s",
|
2003-11-30 07:41:29 +01:00
|
|
|
TAB_AS_SPACES, FIL.RDB$MODULE_NAME, NEWLINE,
|
|
|
|
TAB_AS_SPACES, FIL.RDB$ENTRYPOINT, NEWLINE,
|
|
|
|
NEWLINE);
|
|
|
|
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
2005-05-14 16:50:41 +02:00
|
|
|
return ps_ERR;
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
|
|
|
|
|
|
|
if (first)
|
2003-12-03 09:19:24 +01:00
|
|
|
return (OBJECT_NOT_FOUND);
|
2001-05-23 15:26:42 +02:00
|
|
|
return (SKIP);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-01-04 06:42:26 +01:00
|
|
|
static processing_state show_functions(const SCHAR* object, const SSHORT sys_flag)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* s h o w _ f u n c t i o n s
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Show external functions in general or for the named function
|
|
|
|
*
|
|
|
|
**************************************/
|
2003-09-05 13:25:53 +02:00
|
|
|
bool first = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
// Show all functions
|
2001-05-23 15:26:42 +02:00
|
|
|
if (!*object)
|
|
|
|
{
|
2004-12-04 09:30:43 +01:00
|
|
|
bool odd = true;
|
2005-03-31 09:50:32 +02:00
|
|
|
if (!sys_flag)
|
|
|
|
{
|
|
|
|
FOR FUN IN RDB$FUNCTIONS
|
|
|
|
WITH FUN.RDB$SYSTEM_FLAG EQ 0
|
|
|
|
OR FUN.RDB$SYSTEM_FLAG MISSING
|
|
|
|
SORTED BY FUN.RDB$FUNCTION_NAME
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2005-03-31 09:50:32 +02:00
|
|
|
first = false;
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%38s%s", FUN.RDB$FUNCTION_NAME, (odd ? " " : NEWLINE));
|
2005-03-31 09:50:32 +02:00
|
|
|
odd = !odd;
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
2005-05-14 16:50:41 +02:00
|
|
|
return ps_ERR;
|
2005-03-31 09:50:32 +02:00
|
|
|
END_ERROR;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
FOR FUN IN RDB$FUNCTIONS
|
|
|
|
WITH FUN.RDB$SYSTEM_FLAG EQ sys_flag
|
|
|
|
SORTED BY FUN.RDB$FUNCTION_NAME
|
|
|
|
|
|
|
|
first = false;
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%38s%s", FUN.RDB$FUNCTION_NAME, (odd ? " " : NEWLINE));
|
2005-03-31 09:50:32 +02:00
|
|
|
odd = !odd;
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
2005-05-14 16:50:41 +02:00
|
|
|
return ps_ERR;
|
2005-03-31 09:50:32 +02:00
|
|
|
END_ERROR;
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
if (!first)
|
|
|
|
{
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf(NEWLINE);
|
2001-05-23 15:26:42 +02:00
|
|
|
return (SKIP);
|
|
|
|
}
|
|
|
|
else
|
2003-12-03 09:19:24 +01:00
|
|
|
return OBJECT_NOT_FOUND;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
2004-12-04 09:30:43 +01:00
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
FOR FUN IN RDB$FUNCTIONS CROSS
|
2003-11-30 07:41:29 +01:00
|
|
|
FNA IN RDB$FUNCTION_ARGUMENTS WITH
|
|
|
|
FUN.RDB$FUNCTION_NAME EQ FNA.RDB$FUNCTION_NAME AND
|
|
|
|
FUN.RDB$FUNCTION_NAME EQ object
|
|
|
|
SORTED BY FNA.RDB$ARGUMENT_POSITION
|
|
|
|
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(FUN.RDB$FUNCTION_NAME);
|
|
|
|
fb_utils::exact_name(FUN.RDB$MODULE_NAME);
|
|
|
|
fb_utils::exact_name(FUN.RDB$ENTRYPOINT);
|
2003-11-30 07:41:29 +01:00
|
|
|
if (first) {
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%sFunction %s:%s",
|
2003-11-30 07:41:29 +01:00
|
|
|
NEWLINE,
|
|
|
|
FUN.RDB$FUNCTION_NAME,
|
|
|
|
NEWLINE);
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("Function library is %s%s",
|
2004-04-23 20:39:04 +02:00
|
|
|
FUN.RDB$MODULE_NAME,
|
2003-11-30 07:41:29 +01:00
|
|
|
NEWLINE);
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("Entry point is %s%s",
|
2003-11-30 07:41:29 +01:00
|
|
|
FUN.RDB$ENTRYPOINT,
|
|
|
|
NEWLINE);
|
|
|
|
}
|
|
|
|
|
|
|
|
SSHORT ptype = (SSHORT) abs (FNA.RDB$MECHANISM);
|
2004-09-22 03:55:37 +02:00
|
|
|
if (ptype > MAX_UDFPARAM_TYPES) {
|
|
|
|
ptype = MAX_UDFPARAM_TYPES;
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
first = false;
|
|
|
|
if (FUN.RDB$RETURN_ARGUMENT == FNA.RDB$ARGUMENT_POSITION) {
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("Returns %s%s",
|
2003-11-30 07:41:29 +01:00
|
|
|
UDF_param_types[ptype],
|
2004-09-22 03:55:37 +02:00
|
|
|
(FNA.RDB$MECHANISM < 0 ? " FREE_IT " : " "));
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
|
|
|
else {
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("Argument %d:%s ", FNA.RDB$ARGUMENT_POSITION,
|
2003-11-30 07:41:29 +01:00
|
|
|
UDF_param_types[ptype]);
|
|
|
|
}
|
|
|
|
for (int i = 0; Column_types[i].type; i++)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-11-30 07:41:29 +01:00
|
|
|
if (FNA.RDB$FIELD_TYPE == Column_types[i].type)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-11-30 07:41:29 +01:00
|
|
|
bool precision_known = false;
|
|
|
|
|
|
|
|
// Handle Integral subtypes NUMERIC and DECIMAL
|
2004-05-24 19:16:02 +02:00
|
|
|
if ( (isqlGlob.major_ods >= ODS_VERSION10) &&
|
2003-11-30 07:41:29 +01:00
|
|
|
((FNA.RDB$FIELD_TYPE == SMALLINT) ||
|
|
|
|
(FNA.RDB$FIELD_TYPE == INTEGER) ||
|
2004-09-22 03:55:37 +02:00
|
|
|
(FNA.RDB$FIELD_TYPE == BIGINT)) )
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-11-30 07:41:29 +01:00
|
|
|
FOR FNA1 IN RDB$FUNCTION_ARGUMENTS WITH
|
|
|
|
FNA1.RDB$FUNCTION_NAME = FNA.RDB$FUNCTION_NAME AND
|
|
|
|
FNA1.RDB$ARGUMENT_POSITION = FNA.RDB$ARGUMENT_POSITION
|
|
|
|
|
|
|
|
/* We are ODS >= 10 */
|
|
|
|
if (!FNA1.RDB$FIELD_PRECISION.NULL)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-11-30 07:41:29 +01:00
|
|
|
/* We are Dialect >=3 since FIELD_PRECISION is
|
|
|
|
non-NULL */
|
|
|
|
if (FNA1.RDB$FIELD_SUB_TYPE > 0 &&
|
|
|
|
FNA1.RDB$FIELD_SUB_TYPE <= MAX_INTSUBTYPES)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-11-30 07:41:29 +01:00
|
|
|
sprintf (Print_buffer, "%s(%d, %d)",
|
|
|
|
Integral_subtypes[FNA1.RDB$FIELD_SUB_TYPE],
|
|
|
|
FNA1.RDB$FIELD_PRECISION,
|
|
|
|
-FNA1.RDB$FIELD_SCALE);
|
|
|
|
precision_known = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
END_FOR
|
2004-04-23 20:39:04 +02:00
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg (isc_status);
|
2005-05-14 16:50:41 +02:00
|
|
|
return ps_ERR;
|
2004-04-23 20:39:04 +02:00
|
|
|
END_ERROR;
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!precision_known)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-11-30 07:41:29 +01:00
|
|
|
// Take a stab at numerics and decimals
|
|
|
|
if ((FNA.RDB$FIELD_TYPE == SMALLINT) && (FNA.RDB$FIELD_SCALE < 0))
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-11-30 07:41:29 +01:00
|
|
|
sprintf (Print_buffer, "NUMERIC(4, %d)", -FNA.RDB$FIELD_SCALE);
|
|
|
|
}
|
|
|
|
else if ((FNA.RDB$FIELD_TYPE == INTEGER) && (FNA.RDB$FIELD_SCALE < 0))
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-11-30 07:41:29 +01:00
|
|
|
sprintf (Print_buffer, "NUMERIC(9, %d)", -FNA.RDB$FIELD_SCALE);
|
|
|
|
}
|
|
|
|
else if ((FNA.RDB$FIELD_TYPE == DOUBLE_PRECISION) &&
|
|
|
|
(FNA.RDB$FIELD_SCALE < 0))
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-11-30 07:41:29 +01:00
|
|
|
sprintf (Print_buffer, "NUMERIC(15, %d)", -FNA.RDB$FIELD_SCALE);
|
|
|
|
}
|
|
|
|
else
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-11-30 07:41:29 +01:00
|
|
|
sprintf (Print_buffer, "%s", Column_types[i].type_name);
|
|
|
|
}
|
|
|
|
}
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.prints(Print_buffer);
|
2003-11-30 07:41:29 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
// Print length where appropriate
|
2004-04-24 16:38:27 +02:00
|
|
|
if ((FNA.RDB$FIELD_TYPE == T_CHAR) || (FNA.RDB$FIELD_TYPE == VARCHAR)
|
2003-11-30 07:41:29 +01:00
|
|
|
|| (FNA.RDB$FIELD_TYPE == CSTRING))
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2004-04-23 20:39:04 +02:00
|
|
|
FOR V4FNA IN RDB$FUNCTION_ARGUMENTS CROSS
|
|
|
|
CHARSET IN RDB$CHARACTER_SETS OVER RDB$CHARACTER_SET_ID
|
|
|
|
WITH V4FNA.RDB$FUNCTION_NAME EQ FNA.RDB$FUNCTION_NAME AND
|
|
|
|
V4FNA.RDB$ARGUMENT_POSITION EQ FNA.RDB$ARGUMENT_POSITION
|
|
|
|
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(CHARSET.RDB$CHARACTER_SET_NAME);
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("(%d) CHARACTER SET %s",
|
2004-04-23 20:39:04 +02:00
|
|
|
(FNA.RDB$FIELD_LENGTH / MAX (1, CHARSET.RDB$BYTES_PER_CHARACTER)),
|
|
|
|
CHARSET.RDB$CHARACTER_SET_NAME);
|
|
|
|
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg (isc_status);
|
2005-05-14 16:50:41 +02:00
|
|
|
return ps_ERR;
|
2004-04-23 20:39:04 +02:00
|
|
|
END_ERROR;
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
|
|
|
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf(NEWLINE);
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
END_FOR
|
2003-11-30 07:41:29 +01:00
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
2005-05-14 16:50:41 +02:00
|
|
|
return ps_ERR;
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
|
|
|
if (first)
|
2003-12-03 09:19:24 +01:00
|
|
|
return (OBJECT_NOT_FOUND);
|
2001-05-23 15:26:42 +02:00
|
|
|
return (SKIP);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-12-03 09:19:24 +01:00
|
|
|
static processing_state show_generators(const SCHAR* object)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* s h o w _ g e n e r a t o r s
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Show generators including the next number they return
|
|
|
|
* We do this by selecting the GEN_ID of each one,
|
|
|
|
* incrementing by 0 to not change the current value.
|
|
|
|
*
|
|
|
|
**************************************/
|
2003-09-05 13:25:53 +02:00
|
|
|
SSHORT indicator;
|
2003-09-29 14:43:14 +02:00
|
|
|
bool found = false;
|
2001-05-23 15:26:42 +02:00
|
|
|
XSQLDA sqlda;
|
|
|
|
SINT64 genid64 = 0;
|
|
|
|
SLONG genid = 0;
|
2003-11-30 07:41:29 +01:00
|
|
|
TEXT query[100], gen_name[WORDLENGTH * 2];
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
// Show all generators or named generator
|
|
|
|
FOR GEN IN RDB$GENERATORS
|
2004-04-23 20:39:04 +02:00
|
|
|
SORTED BY GEN.RDB$GENERATOR_NAME
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(GEN.RDB$GENERATOR_NAME);
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
if ((!*object && GEN.RDB$SYSTEM_FLAG.NULL) ||
|
2003-11-30 07:41:29 +01:00
|
|
|
(!strcmp (GEN.RDB$GENERATOR_NAME, object)))
|
|
|
|
{
|
|
|
|
// Get the current id for each generator
|
|
|
|
|
|
|
|
const bool delimited_yes = strchr(GEN.RDB$GENERATOR_NAME, DBL_QUOTE) != 0;
|
2004-05-24 19:16:02 +02:00
|
|
|
if (isqlGlob.db_SQL_dialect > SQL_DIALECT_V6_TRANSITION && delimited_yes) {
|
2003-11-30 07:41:29 +01:00
|
|
|
ISQL_copy_SQL_id (GEN.RDB$GENERATOR_NAME, gen_name, DBL_QUOTE);
|
|
|
|
}
|
|
|
|
else { // If we are extracting in dialect 1, identifiers may cause failures.
|
|
|
|
strcpy(gen_name, GEN.RDB$GENERATOR_NAME);
|
|
|
|
}
|
|
|
|
|
|
|
|
sprintf (query, "SELECT GEN_ID(%s, 0) FROM RDB$DATABASE", gen_name);
|
|
|
|
|
2003-09-29 14:43:14 +02:00
|
|
|
isc_stmt_handle stmt = 0;
|
2003-11-30 07:41:29 +01:00
|
|
|
isc_dsql_allocate_statement (isc_status, &DB, &stmt);
|
|
|
|
sqlda.sqln = 1;
|
|
|
|
sqlda.version = 1;
|
|
|
|
|
|
|
|
/* If the user has set his client dialect to 1, we take that to
|
|
|
|
mean that he wants to see just the lower 32 bits of the
|
|
|
|
generator, as in V5. Otherwise, we show him the whole 64-bit
|
|
|
|
value.
|
|
|
|
*/
|
|
|
|
if (isc_dsql_prepare (isc_status, &gds_trans, &stmt, 0, query,
|
2004-05-24 19:16:02 +02:00
|
|
|
isqlGlob.SQL_dialect, &sqlda))
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-11-30 07:41:29 +01:00
|
|
|
ISQL_errmsg (isc_status);
|
|
|
|
continue;
|
2004-11-07 11:38:13 +01:00
|
|
|
}
|
2004-05-24 19:16:02 +02:00
|
|
|
if (isqlGlob.SQL_dialect >= SQL_DIALECT_V6_TRANSITION)
|
2003-11-30 07:41:29 +01:00
|
|
|
sqlda.sqlvar[0].sqldata = (SCHAR*) &genid64;
|
|
|
|
else
|
|
|
|
sqlda.sqlvar[0].sqldata = (SCHAR*) &genid;
|
|
|
|
sqlda.sqlvar[0].sqlind = &indicator;
|
|
|
|
|
|
|
|
// Singleton select needs no fetch
|
|
|
|
if (isc_dsql_execute2 (isc_status, &gds_trans, &stmt,
|
2004-05-24 19:16:02 +02:00
|
|
|
isqlGlob.SQL_dialect, NULL, &sqlda))
|
2003-11-30 07:41:29 +01:00
|
|
|
{
|
|
|
|
ISQL_errmsg (isc_status);
|
|
|
|
}
|
|
|
|
else
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-11-30 07:41:29 +01:00
|
|
|
found = true;
|
2004-05-24 19:16:02 +02:00
|
|
|
if (isqlGlob.SQL_dialect >= SQL_DIALECT_V6_TRANSITION)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(
|
2003-11-30 07:41:29 +01:00
|
|
|
"Generator %s, current value is %" QUADFORMAT "d%s",
|
|
|
|
GEN.RDB$GENERATOR_NAME,
|
|
|
|
genid64,
|
|
|
|
NEWLINE);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
2003-11-30 07:41:29 +01:00
|
|
|
else
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("Generator %s, current value is %ld%s",
|
2003-11-30 07:41:29 +01:00
|
|
|
GEN.RDB$GENERATOR_NAME,
|
|
|
|
genid,
|
|
|
|
NEWLINE);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
|
|
|
if (isc_dsql_free_statement (isc_status, &stmt, DSQL_drop))
|
|
|
|
ISQL_errmsg (isc_status);
|
|
|
|
}
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
2005-05-14 16:50:41 +02:00
|
|
|
return ps_ERR;
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
2003-09-29 14:43:14 +02:00
|
|
|
if (!found)
|
2003-12-03 09:19:24 +01:00
|
|
|
return (OBJECT_NOT_FOUND);
|
2001-05-23 15:26:42 +02:00
|
|
|
return SKIP;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-09-29 14:43:14 +02:00
|
|
|
static void show_index(SCHAR* relation_name,
|
|
|
|
SCHAR* index_name,
|
|
|
|
const SSHORT unique_flag,
|
|
|
|
const SSHORT index_type,
|
|
|
|
const SSHORT inactive)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* s h o w _ i n d e x
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Show an index.
|
|
|
|
*
|
|
|
|
* relation_name -- Name of table to investigate
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
// Strip trailing blanks
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(relation_name);
|
|
|
|
fb_utils::exact_name(index_name);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%s%s%s INDEX ON %s", index_name,
|
2001-05-23 15:26:42 +02:00
|
|
|
(unique_flag ? " UNIQUE" : ""),
|
|
|
|
(index_type == 1 ? " DESCENDING" : ""), relation_name);
|
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
// Get column names
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2005-03-26 06:33:55 +01:00
|
|
|
SCHAR collist[BUFFER_LENGTH512];
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
if (ISQL_get_index_segments(collist, sizeof(collist), index_name, false))
|
|
|
|
{
|
|
|
|
isqlGlob.printf("(%s) %s%s", collist,
|
2001-05-23 15:26:42 +02:00
|
|
|
(inactive ? "(inactive)" : ""), NEWLINE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-12-03 09:19:24 +01:00
|
|
|
static processing_state show_indices(const SCHAR* const* cmd)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* s h o w _ i n d i c e s
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* shows indices for a given table name or index name or all tables
|
|
|
|
*
|
|
|
|
* Use a static SQL query to get the info and print it.
|
|
|
|
*
|
|
|
|
* relation_name -- Name of table to investigate
|
|
|
|
*
|
|
|
|
**************************************/
|
2003-09-05 13:25:53 +02:00
|
|
|
bool first = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
// The names stored in the database are all upper case
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-09-29 14:43:14 +02:00
|
|
|
const SCHAR* name = cmd[2];
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (*name) {
|
2004-04-23 20:39:04 +02:00
|
|
|
FOR IDX1 IN RDB$INDICES WITH
|
2003-11-30 07:41:29 +01:00
|
|
|
IDX1.RDB$RELATION_NAME EQ name OR
|
|
|
|
IDX1.RDB$INDEX_NAME EQ name
|
|
|
|
SORTED BY IDX1.RDB$INDEX_NAME
|
|
|
|
|
|
|
|
if (IDX1.RDB$INDEX_INACTIVE.NULL)
|
|
|
|
IDX1.RDB$INDEX_INACTIVE = 0;
|
|
|
|
|
|
|
|
show_index (IDX1.RDB$RELATION_NAME, IDX1.RDB$INDEX_NAME,
|
|
|
|
IDX1.RDB$UNIQUE_FLAG, IDX1.RDB$INDEX_TYPE, IDX1.RDB$INDEX_INACTIVE);
|
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
#ifdef EXPRESSION_INDICES
|
2003-11-30 07:41:29 +01:00
|
|
|
if (!IDX1.RDB$EXPRESSION_BLR.NULL) {
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(" COMPUTED BY ");
|
2003-11-30 07:41:29 +01:00
|
|
|
if (!IDX1.RDB$EXPRESSION_SOURCE.NULL)
|
2004-05-24 19:16:02 +02:00
|
|
|
SHOW_print_metadata_text_blob (isqlGlob.Out, &IDX1.RDB$EXPRESSION_SOURCE);
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf(NEWLINE);
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
#endif
|
2003-11-30 07:41:29 +01:00
|
|
|
|
|
|
|
first = false;
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR ISQL_errmsg(isc_status);
|
2005-05-14 16:50:41 +02:00
|
|
|
return ps_ERR;
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
|
|
|
if (first)
|
2003-12-03 09:19:24 +01:00
|
|
|
return (OBJECT_NOT_FOUND);
|
2001-05-23 15:26:42 +02:00
|
|
|
return (SKIP);
|
|
|
|
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-04-23 20:39:04 +02:00
|
|
|
FOR IDX2 IN RDB$INDICES CROSS
|
2003-11-30 07:41:29 +01:00
|
|
|
REL IN RDB$RELATIONS OVER RDB$RELATION_NAME WITH
|
|
|
|
REL.RDB$SYSTEM_FLAG NE 1 OR
|
|
|
|
REL.RDB$SYSTEM_FLAG MISSING
|
|
|
|
SORTED BY IDX2.RDB$RELATION_NAME, IDX2.RDB$INDEX_NAME
|
|
|
|
|
|
|
|
first = false;
|
|
|
|
|
|
|
|
show_index (IDX2.RDB$RELATION_NAME, IDX2.RDB$INDEX_NAME,
|
|
|
|
IDX2.RDB$UNIQUE_FLAG, IDX2.RDB$INDEX_TYPE, IDX2.RDB$INDEX_INACTIVE);
|
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
#ifdef EXPRESSION_INDICES
|
2003-11-30 07:41:29 +01:00
|
|
|
if (!IDX2.RDB$EXPRESSION_BLR.NULL) {
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(" COMPUTED BY ");
|
2003-11-30 07:41:29 +01:00
|
|
|
if (!IDX2.RDB$EXPRESSION_SOURCE.NULL)
|
2004-05-24 19:16:02 +02:00
|
|
|
SHOW_print_metadata_text_blob (isqlGlob.Out, &IDX2.RDB$EXPRESSION_SOURCE);
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf(NEWLINE);
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
#endif
|
2003-11-30 07:41:29 +01:00
|
|
|
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
2005-05-19 10:03:10 +02:00
|
|
|
return ps_ERR;
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
|
|
|
if (first)
|
2003-12-03 09:19:24 +01:00
|
|
|
return (OBJECT_NOT_FOUND);
|
2001-05-23 15:26:42 +02:00
|
|
|
return (SKIP);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-12-03 09:19:24 +01:00
|
|
|
static processing_state show_proc(const SCHAR* procname)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* s h o w _ p r o c
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* shows text of a stored procedure given a name.
|
|
|
|
* or lists procedures if no argument.
|
|
|
|
*
|
|
|
|
* procname -- Name of procedure to investigate
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
// If no procedure name was given, just list the procedures
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-09-29 14:43:14 +02:00
|
|
|
if (!procname || !strlen(procname)) {
|
2001-05-23 15:26:42 +02:00
|
|
|
/* This query gets the procedure name the next query
|
2003-11-30 07:41:29 +01:00
|
|
|
** gets all the dependencies if any
|
2001-05-23 15:26:42 +02:00
|
|
|
*/
|
2003-09-29 14:43:14 +02:00
|
|
|
bool first_proc = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
FOR PRC IN RDB$PROCEDURES
|
2003-11-30 07:41:29 +01:00
|
|
|
SORTED BY PRC.RDB$PROCEDURE_NAME
|
|
|
|
|
|
|
|
if (first_proc) {
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(
|
2003-11-30 07:41:29 +01:00
|
|
|
"Procedure Name Dependency, Type%s", NEWLINE);
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(
|
2003-11-30 07:41:29 +01:00
|
|
|
"================================= ======================================%s", NEWLINE);
|
|
|
|
first_proc = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Strip trailing blanks
|
|
|
|
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(PRC.RDB$PROCEDURE_NAME);
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%-34s", PRC.RDB$PROCEDURE_NAME);
|
2003-11-30 07:41:29 +01:00
|
|
|
|
|
|
|
bool first_dep = true;
|
|
|
|
FOR DEP IN RDB$DEPENDENCIES WITH
|
|
|
|
PRC.RDB$PROCEDURE_NAME EQ DEP.RDB$DEPENDENT_NAME
|
|
|
|
REDUCED TO DEP.RDB$DEPENDED_ON_TYPE, DEP.RDB$DEPENDED_ON_NAME
|
|
|
|
SORTED BY DEP.RDB$DEPENDED_ON_TYPE, DEP.RDB$DEPENDED_ON_NAME
|
|
|
|
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(DEP.RDB$DEPENDED_ON_NAME);
|
2003-11-30 07:41:29 +01:00
|
|
|
// Get column type name to print
|
|
|
|
if (!first_dep) {
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%s%34s", NEWLINE, "");
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
|
|
|
first_dep = false;
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%s, %s", DEP.RDB$DEPENDED_ON_NAME,
|
2003-11-30 07:41:29 +01:00
|
|
|
Object_types[DEP.RDB$DEPENDED_ON_TYPE]);
|
|
|
|
END_FOR
|
2004-04-23 20:39:04 +02:00
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg (isc_status);
|
2005-05-19 10:03:10 +02:00
|
|
|
return ps_ERR;
|
2004-04-23 20:39:04 +02:00
|
|
|
END_ERROR;
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf(NEWLINE);
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
END_FOR
|
2003-11-30 07:41:29 +01:00
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
2005-05-19 10:03:10 +02:00
|
|
|
return ps_ERR;
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
|
|
|
if (first_proc)
|
2003-12-03 09:19:24 +01:00
|
|
|
return OBJECT_NOT_FOUND;
|
2001-05-23 15:26:42 +02:00
|
|
|
return (SKIP);
|
|
|
|
}
|
2003-11-30 07:41:29 +01:00
|
|
|
|
|
|
|
// A procedure was named, so print all the info on that procedure
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-09-29 14:43:14 +02:00
|
|
|
SCHAR type_name[33];
|
|
|
|
SCHAR lenstring[33] = "";
|
|
|
|
bool first = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
FOR PRC IN RDB$PROCEDURES WITH
|
2003-11-30 07:41:29 +01:00
|
|
|
PRC.RDB$PROCEDURE_NAME EQ procname
|
|
|
|
first = false;
|
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("Procedure text:%s", NEWLINE);
|
|
|
|
isqlGlob.printf("=============================================================================%s", NEWLINE);
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
if (!PRC.RDB$PROCEDURE_SOURCE.NULL)
|
2004-05-24 19:16:02 +02:00
|
|
|
SHOW_print_metadata_text_blob (isqlGlob.Out, &PRC.RDB$PROCEDURE_SOURCE);
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%s=============================================================================%s", NEWLINE, NEWLINE);
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("Parameters:%s", NEWLINE);
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
FOR PRM IN RDB$PROCEDURE_PARAMETERS CROSS
|
2003-11-30 07:41:29 +01:00
|
|
|
FLD IN RDB$FIELDS WITH
|
|
|
|
PRC.RDB$PROCEDURE_NAME EQ PRM.RDB$PROCEDURE_NAME AND
|
|
|
|
PRM.RDB$FIELD_SOURCE EQ FLD.RDB$FIELD_NAME
|
|
|
|
SORTED BY PRM.RDB$PARAMETER_TYPE, PRM.RDB$PARAMETER_NUMBER
|
|
|
|
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(PRM.RDB$PARAMETER_NAME);
|
2003-11-30 07:41:29 +01:00
|
|
|
// Get column type name to print
|
2004-04-23 20:39:04 +02:00
|
|
|
// Look through types array
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2004-12-04 09:30:43 +01:00
|
|
|
for (int i = 0; Column_types[i].type; i++)
|
2003-11-30 07:41:29 +01:00
|
|
|
if (FLD.RDB$FIELD_TYPE == Column_types[i].type) {
|
|
|
|
bool precision_known = false;
|
|
|
|
|
2004-05-24 19:16:02 +02:00
|
|
|
if (isqlGlob.major_ods >= ODS_VERSION10) {
|
2003-11-30 07:41:29 +01:00
|
|
|
// Handle Integral subtypes NUMERIC and DECIMAL
|
|
|
|
|
|
|
|
if ((FLD.RDB$FIELD_TYPE == SMALLINT) ||
|
|
|
|
(FLD.RDB$FIELD_TYPE == INTEGER) ||
|
2004-09-22 03:55:37 +02:00
|
|
|
(FLD.RDB$FIELD_TYPE == BIGINT))
|
2003-11-30 07:41:29 +01:00
|
|
|
{
|
|
|
|
FOR FLD1 IN RDB$FIELDS
|
|
|
|
WITH FLD1.RDB$FIELD_NAME EQ FLD.RDB$FIELD_NAME
|
|
|
|
/* We are ODS >= 10 and could be any Dialect */
|
|
|
|
if (!FLD1.RDB$FIELD_PRECISION.NULL) {
|
|
|
|
/* We are Dialect >=3 since FIELD_PRECISION is
|
|
|
|
non-NULL */
|
|
|
|
if (FLD1.RDB$FIELD_SUB_TYPE > 0 &&
|
|
|
|
FLD1.RDB$FIELD_SUB_TYPE <= MAX_INTSUBTYPES)
|
|
|
|
{
|
|
|
|
sprintf (type_name, "%s(%d, %d)",
|
|
|
|
Integral_subtypes[FLD1.RDB$FIELD_SUB_TYPE],
|
|
|
|
FLD1.RDB$FIELD_PRECISION,
|
|
|
|
-FLD1.RDB$FIELD_SCALE);
|
|
|
|
precision_known = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg (isc_status);
|
2005-05-14 16:50:41 +02:00
|
|
|
return ps_ERR;
|
2003-11-30 07:41:29 +01:00
|
|
|
END_ERROR;
|
|
|
|
} // if field_type ...
|
2004-05-24 19:16:02 +02:00
|
|
|
} // if isqlGlob.major_ods ...
|
2003-11-30 07:41:29 +01:00
|
|
|
|
|
|
|
if (!precision_known) {
|
|
|
|
// Take a stab at numerics and decimals
|
|
|
|
if ((FLD.RDB$FIELD_TYPE == SMALLINT) && (FLD.RDB$FIELD_SCALE < 0)) {
|
|
|
|
sprintf (type_name, "NUMERIC(4, %d)", -FLD.RDB$FIELD_SCALE);
|
|
|
|
}
|
|
|
|
else if ((FLD.RDB$FIELD_TYPE == INTEGER) && (FLD.RDB$FIELD_SCALE < 0)) {
|
|
|
|
sprintf (type_name, "NUMERIC(9, %d)", -FLD.RDB$FIELD_SCALE);
|
|
|
|
}
|
|
|
|
else if ((FLD.RDB$FIELD_TYPE == DOUBLE_PRECISION) &&
|
|
|
|
(FLD.RDB$FIELD_SCALE < 0))
|
|
|
|
{
|
|
|
|
sprintf (type_name, "NUMERIC(15, %d)", -FLD.RDB$FIELD_SCALE);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
strcpy(type_name, Column_types[i].type_name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
/* Use RDB$CHARACTER_LENGTH instead of RDB$FIELD_LENGTH
|
|
|
|
FSG 19.Nov.2000
|
|
|
|
*/
|
2004-04-24 16:38:27 +02:00
|
|
|
if (((FLD.RDB$FIELD_TYPE == T_CHAR) || (FLD.RDB$FIELD_TYPE == VARCHAR)) &&
|
2003-11-30 07:41:29 +01:00
|
|
|
!FLD.RDB$CHARACTER_LENGTH.NULL)
|
2003-09-29 14:43:14 +02:00
|
|
|
{
|
2003-11-30 07:41:29 +01:00
|
|
|
sprintf (lenstring, "(%d)", FLD.RDB$CHARACTER_LENGTH);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
// CVC: the original programmer initialized it only once,
|
|
|
|
// outside the loop, so it may contain garbage from previous iteration.
|
|
|
|
strcpy(lenstring, "");
|
|
|
|
}
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%-33s %s %s%s ", PRM.RDB$PARAMETER_NAME,
|
2003-11-30 07:41:29 +01:00
|
|
|
(PRM.RDB$PARAMETER_TYPE ? "OUTPUT" : "INPUT"),
|
|
|
|
type_name, lenstring);
|
|
|
|
|
|
|
|
// Show international character sets and collations
|
|
|
|
|
2004-04-24 16:38:27 +02:00
|
|
|
if (FLD.RDB$FIELD_TYPE == T_CHAR ||
|
2003-11-30 07:41:29 +01:00
|
|
|
FLD.RDB$FIELD_TYPE == VARCHAR ||
|
2004-04-23 20:39:04 +02:00
|
|
|
FLD.RDB$FIELD_TYPE == BLOB)
|
2003-09-29 14:43:14 +02:00
|
|
|
{
|
2004-04-23 20:39:04 +02:00
|
|
|
show_charsets(NULL, FLD.RDB$FIELD_NAME, true, true, false, false);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf(NEWLINE);
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
END_FOR
|
2003-11-30 07:41:29 +01:00
|
|
|
ON_ERROR
|
2004-04-23 20:39:04 +02:00
|
|
|
ISQL_errmsg (isc_status);
|
2005-05-14 16:50:41 +02:00
|
|
|
return ps_ERR;
|
2004-04-23 20:39:04 +02:00
|
|
|
END_ERROR;
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
END_FOR
|
2003-11-30 07:41:29 +01:00
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
2005-05-14 16:50:41 +02:00
|
|
|
return ps_ERR;
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
|
|
|
if (first)
|
2003-12-03 09:19:24 +01:00
|
|
|
return (OBJECT_NOT_FOUND);
|
2001-05-23 15:26:42 +02:00
|
|
|
return (SKIP);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-12-03 09:19:24 +01:00
|
|
|
static processing_state show_role(const SCHAR* object)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-11-30 07:41:29 +01:00
|
|
|
if (object == NULL) { // show role with no parameters, show all roles
|
2001-05-23 15:26:42 +02:00
|
|
|
/**************************************
|
|
|
|
* Print the names of all roles from
|
2003-11-30 07:41:29 +01:00
|
|
|
* RDB$ROLES. We use a dynamic query
|
2001-05-23 15:26:42 +02:00
|
|
|
* If there is any roles, then returns SKIP.
|
2005-05-19 10:03:10 +02:00
|
|
|
* Otherwise returns OBJECT_NOT_FOUND.
|
2001-05-23 15:26:42 +02:00
|
|
|
**************************************/
|
2003-11-30 07:41:29 +01:00
|
|
|
bool first = true;
|
|
|
|
bool odd = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
FOR X IN RDB$ROLES WITH
|
|
|
|
X.RDB$ROLE_NAME NOT MISSING
|
|
|
|
SORTED BY X.RDB$ROLE_NAME
|
|
|
|
|
|
|
|
first = false;
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%38s%s", X.RDB$ROLE_NAME, (odd ? " " : NEWLINE));
|
2003-11-30 07:41:29 +01:00
|
|
|
odd = !odd;
|
|
|
|
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
2005-05-14 16:50:41 +02:00
|
|
|
return ps_ERR;
|
2003-11-30 07:41:29 +01:00
|
|
|
END_ERROR;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
if (!first)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf(NEWLINE);
|
2003-11-30 07:41:29 +01:00
|
|
|
return SKIP;
|
|
|
|
}
|
|
|
|
else
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-12-03 09:19:24 +01:00
|
|
|
return OBJECT_NOT_FOUND;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2003-11-30 07:41:29 +01:00
|
|
|
// show role with role supplied, display users granted this role
|
2003-09-29 14:43:14 +02:00
|
|
|
SCHAR role_name[BUFFER_LENGTH128];
|
2003-11-30 07:41:29 +01:00
|
|
|
bool first = true;
|
|
|
|
|
|
|
|
FOR FIRST 1 R IN RDB$ROLES WITH R.RDB$ROLE_NAME EQ object
|
|
|
|
|
|
|
|
FOR PRV IN RDB$USER_PRIVILEGES WITH
|
|
|
|
PRV.RDB$OBJECT_TYPE EQ obj_sql_role AND
|
|
|
|
PRV.RDB$USER_TYPE EQ obj_user AND
|
|
|
|
PRV.RDB$RELATION_NAME EQ object AND
|
|
|
|
PRV.RDB$PRIVILEGE EQ 'M'
|
|
|
|
SORTED BY PRV.RDB$USER
|
|
|
|
|
2004-08-30 12:10:14 +02:00
|
|
|
if (first)
|
|
|
|
{
|
|
|
|
first = false;
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(PRV.RDB$RELATION_NAME);
|
2004-08-30 12:10:14 +02:00
|
|
|
strcpy(role_name, PRV.RDB$RELATION_NAME);
|
|
|
|
if (isqlGlob.db_SQL_dialect > SQL_DIALECT_V6_TRANSITION)
|
|
|
|
ISQL_copy_SQL_id(role_name, SQL_identifier, DBL_QUOTE);
|
|
|
|
else
|
|
|
|
strcpy(SQL_identifier, role_name);
|
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("Role %s is granted to:\n", SQL_identifier);
|
2004-08-30 12:10:14 +02:00
|
|
|
}
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(PRV.RDB$USER);
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%s\n", PRV.RDB$USER);
|
2003-11-30 07:41:29 +01:00
|
|
|
|
|
|
|
END_FOR
|
2004-04-23 20:39:04 +02:00
|
|
|
ON_ERROR
|
2003-11-30 07:41:29 +01:00
|
|
|
ISQL_errmsg (isc_status);
|
2005-05-19 10:03:10 +02:00
|
|
|
return ps_ERR;
|
2004-08-31 08:26:27 +02:00
|
|
|
END_ERROR
|
2004-08-30 12:10:14 +02:00
|
|
|
|
|
|
|
if (first)
|
|
|
|
{
|
|
|
|
first = false;
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(R.RDB$ROLE_NAME);
|
2004-08-30 12:10:14 +02:00
|
|
|
strcpy(role_name, R.RDB$ROLE_NAME);
|
|
|
|
if (isqlGlob.db_SQL_dialect > SQL_DIALECT_V6_TRANSITION)
|
|
|
|
ISQL_copy_SQL_id(role_name, SQL_identifier, DBL_QUOTE);
|
|
|
|
else
|
|
|
|
strcpy(SQL_identifier, role_name);
|
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("Role %s isn't granted to anyone.\n", SQL_identifier);
|
2004-08-30 12:10:14 +02:00
|
|
|
}
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
END_FOR
|
2003-11-30 07:41:29 +01:00
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
2005-05-19 10:03:10 +02:00
|
|
|
return ps_ERR;
|
2004-08-31 08:26:27 +02:00
|
|
|
END_ERROR
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (first)
|
2003-12-03 09:19:24 +01:00
|
|
|
return (OBJECT_NOT_FOUND);
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
return (SKIP);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
static processing_state show_table(
|
|
|
|
const SCHAR* relation_name,
|
|
|
|
bool isView)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* s h o w _ t a b l e
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* shows columns, types, info for a given table name
|
|
|
|
* and text of views.
|
|
|
|
* Use a SQL query to get the info and print it.
|
2003-11-30 07:41:29 +01:00
|
|
|
* This also shows integrity constraints and triggers
|
2001-05-23 15:26:42 +02:00
|
|
|
*
|
|
|
|
* relation_name -- Name of table to investigate
|
|
|
|
*
|
|
|
|
**************************************/
|
2003-09-05 13:25:53 +02:00
|
|
|
bool first = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
// Query to obtain relation information
|
2004-04-23 20:39:04 +02:00
|
|
|
// REL.RDB$VIEW_BLR NOT MISSING
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
FOR REL IN RDB$RELATIONS
|
2004-04-23 20:39:04 +02:00
|
|
|
WITH REL.RDB$RELATION_NAME EQ relation_name
|
|
|
|
if (first) {
|
|
|
|
if (!REL.RDB$EXTERNAL_FILE.NULL)
|
|
|
|
{
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("External file: %s\n", REL.RDB$EXTERNAL_FILE);
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
first = false;
|
2004-04-23 20:39:04 +02:00
|
|
|
if (isView && REL.RDB$VIEW_BLR.NULL || !isView && !REL.RDB$VIEW_BLR.NULL)
|
|
|
|
first = true;
|
2003-11-30 07:41:29 +01:00
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
2005-05-14 16:50:41 +02:00
|
|
|
return ps_ERR;
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
|
|
|
|
|
|
|
if (first)
|
2003-12-03 09:19:24 +01:00
|
|
|
return (OBJECT_NOT_FOUND);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
/*
|
2001-05-23 15:26:42 +02:00
|
|
|
*FOR RFR IN RDB$RELATION_FIELDS CROSS
|
|
|
|
REL IN RDB$RELATIONS CROSS
|
|
|
|
FLD IN RDB$FIELDS WITH
|
|
|
|
RFR.RDB$FIELD_SOURCE EQ FLD.RDB$FIELD_NAME AND
|
|
|
|
RFR.RDB$RELATION_NAME EQ relation_name AND
|
|
|
|
REL.RDB$RELATION_NAME EQ RFR.RDB$RELATION_NAME
|
|
|
|
SORTED BY RFR.RDB$FIELD_POSITION, RFR.RDB$FIELD_NAME
|
|
|
|
*/
|
|
|
|
|
|
|
|
FOR RFR IN RDB$RELATION_FIELDS CROSS
|
2003-11-30 07:41:29 +01:00
|
|
|
FLD IN RDB$FIELDS WITH
|
|
|
|
RFR.RDB$FIELD_SOURCE EQ FLD.RDB$FIELD_NAME AND
|
|
|
|
RFR.RDB$RELATION_NAME EQ relation_name
|
|
|
|
SORTED BY RFR.RDB$FIELD_POSITION, RFR.RDB$FIELD_NAME
|
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
// Get length of colname to align columns for printing
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(RFR.RDB$FIELD_NAME);
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
// Print the column name in first column
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%-32s", RFR.RDB$FIELD_NAME);
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
// Decide if this is a user-created domain
|
|
|
|
if (!((strncmp (FLD.RDB$FIELD_NAME, "RDB$", 4) == 0) &&
|
2003-11-30 07:41:29 +01:00
|
|
|
isdigit (FLD.RDB$FIELD_NAME[4]) &&
|
|
|
|
FLD.RDB$SYSTEM_FLAG != 1))
|
2003-11-28 07:48:34 +01:00
|
|
|
{
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(FLD.RDB$FIELD_NAME);
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("(%s) ", FLD.RDB$FIELD_NAME);
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
// Detect the existence of arrays
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
if (!FLD.RDB$DIMENSIONS.NULL) {
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("ARRAY OF ");
|
2004-04-23 20:39:04 +02:00
|
|
|
ISQL_array_dimensions (FLD.RDB$FIELD_NAME);
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%s ", NEWLINE);
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
// If a computed field, show the source and exit
|
|
|
|
// Note that view columns which are computed are dealt with later.
|
|
|
|
if (!FLD.RDB$COMPUTED_BLR.NULL) {
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("Computed by: ");
|
2003-11-30 07:41:29 +01:00
|
|
|
if (!FLD.RDB$COMPUTED_SOURCE.NULL)
|
2004-05-24 19:16:02 +02:00
|
|
|
SHOW_print_metadata_text_blob (isqlGlob.Out, &FLD.RDB$COMPUTED_SOURCE);
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf(NEWLINE);
|
2003-11-30 07:41:29 +01:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
// Look through types array
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2004-12-04 09:30:43 +01:00
|
|
|
for (int i = 0; Column_types[i].type; i++)
|
2003-11-30 07:41:29 +01:00
|
|
|
if (FLD.RDB$FIELD_TYPE == Column_types[i].type) {
|
|
|
|
bool precision_known = false;
|
|
|
|
|
2004-05-24 19:16:02 +02:00
|
|
|
if (isqlGlob.major_ods >= ODS_VERSION10) {
|
2003-11-30 07:41:29 +01:00
|
|
|
// Handle Integral subtypes NUMERIC and DECIMAL
|
|
|
|
if ((FLD.RDB$FIELD_TYPE == SMALLINT) ||
|
|
|
|
(FLD.RDB$FIELD_TYPE == INTEGER) ||
|
2004-09-22 03:55:37 +02:00
|
|
|
(FLD.RDB$FIELD_TYPE == BIGINT))
|
2003-11-30 07:41:29 +01:00
|
|
|
{
|
|
|
|
FOR FLD1 IN RDB$FIELDS WITH
|
|
|
|
FLD1.RDB$FIELD_NAME EQ FLD.RDB$FIELD_NAME
|
|
|
|
|
|
|
|
/* We are ODS >= 10 and could be any Dialect */
|
|
|
|
if (!FLD1.RDB$FIELD_PRECISION.NULL) {
|
|
|
|
/* We are Dialect >=3 since FIELD_PRECISION is
|
|
|
|
non-NULL */
|
|
|
|
if (FLD1.RDB$FIELD_SUB_TYPE > 0 &&
|
|
|
|
FLD1.RDB$FIELD_SUB_TYPE <= MAX_INTSUBTYPES)
|
|
|
|
{
|
|
|
|
sprintf (Print_buffer, "%s(%d, %d)",
|
|
|
|
Integral_subtypes[FLD1.RDB$FIELD_SUB_TYPE],
|
|
|
|
FLD1.RDB$FIELD_PRECISION,
|
|
|
|
-FLD1.RDB$FIELD_SCALE);
|
|
|
|
precision_known = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
END_FOR
|
2004-04-23 20:39:04 +02:00
|
|
|
ON_ERROR
|
2003-11-30 07:41:29 +01:00
|
|
|
ISQL_errmsg (isc_status);
|
2005-05-14 16:50:41 +02:00
|
|
|
return ps_ERR;
|
2004-04-23 20:39:04 +02:00
|
|
|
END_ERROR;
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!precision_known) {
|
|
|
|
// Take a stab at numerics and decimals
|
|
|
|
if ((FLD.RDB$FIELD_TYPE == SMALLINT) && (FLD.RDB$FIELD_SCALE < 0)) {
|
|
|
|
sprintf (Print_buffer, "NUMERIC(4, %d)", -FLD.RDB$FIELD_SCALE);
|
|
|
|
}
|
|
|
|
else if ((FLD.RDB$FIELD_TYPE == INTEGER) && (FLD.RDB$FIELD_SCALE < 0)) {
|
|
|
|
sprintf (Print_buffer, "NUMERIC(9, %d)", -FLD.RDB$FIELD_SCALE);
|
|
|
|
}
|
|
|
|
else if ((FLD.RDB$FIELD_TYPE == DOUBLE_PRECISION) &&
|
2005-05-26 08:45:25 +02:00
|
|
|
(FLD.RDB$FIELD_SCALE < 0))
|
|
|
|
{
|
2003-11-30 07:41:29 +01:00
|
|
|
sprintf (Print_buffer, "NUMERIC(15, %d)", -FLD.RDB$FIELD_SCALE);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
sprintf (Print_buffer, "%s", Column_types[i].type_name);
|
|
|
|
}
|
|
|
|
}
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.prints(Print_buffer);
|
2003-11-30 07:41:29 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2004-04-24 16:38:27 +02:00
|
|
|
if ((FLD.RDB$FIELD_TYPE == T_CHAR) || (FLD.RDB$FIELD_TYPE == VARCHAR)) {
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("(%d)", ISQL_get_field_length(FLD.RDB$FIELD_NAME));
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
// Show international character sets and collations
|
|
|
|
show_charsets(relation_name, RFR.RDB$FIELD_NAME, true, false, false, false);
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
if (FLD.RDB$FIELD_TYPE == BLOB) {
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(" segment %u, subtype ", (USHORT) FLD.RDB$SEGMENT_LENGTH);
|
2004-12-07 01:33:16 +01:00
|
|
|
const int subtype = FLD.RDB$FIELD_SUB_TYPE;
|
2004-05-09 07:48:33 +02:00
|
|
|
if (subtype >= 0 && subtype <= MAX_BLOBSUBTYPES)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.prints(Sub_types[subtype]);
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
|
|
|
else
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%d", subtype);
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
// Show international character sets and collations
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
show_charsets(relation_name, RFR.RDB$FIELD_NAME, true, false, false, false);
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
if (!FLD.RDB$COMPUTED_BLR.NULL) {
|
2003-11-30 07:41:29 +01:00
|
|
|
// A view expression. Other computed fields will not reach this point.
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(" Expression%s", NEWLINE);
|
2003-11-30 07:41:29 +01:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
// The null flag is either 1 or null (for nullable)
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
if (RFR.RDB$NULL_FLAG == 1 || FLD.RDB$NULL_FLAG == 1 ||
|
|
|
|
(!RFR.RDB$BASE_FIELD.NULL &&
|
|
|
|
!ISQL_get_null_flag (relation_name, RFR.RDB$FIELD_NAME)))
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(" Not Null ");
|
2004-04-23 20:39:04 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(" Nullable ");
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
// Handle defaults for columns
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
if (!RFR.RDB$DEFAULT_SOURCE.NULL)
|
2004-05-24 19:16:02 +02:00
|
|
|
SHOW_print_metadata_text_blob (isqlGlob.Out, &RFR.RDB$DEFAULT_SOURCE);
|
2004-04-23 20:39:04 +02:00
|
|
|
else if (!FLD.RDB$DEFAULT_SOURCE.NULL)
|
2004-05-24 19:16:02 +02:00
|
|
|
SHOW_print_metadata_text_blob (isqlGlob.Out, &FLD.RDB$DEFAULT_SOURCE);
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf(NEWLINE);
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
// Validation clause for domains
|
|
|
|
if (!FLD.RDB$VALIDATION_SOURCE.NULL) {
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(" ");
|
2004-05-24 19:16:02 +02:00
|
|
|
SHOW_print_metadata_text_blob (isqlGlob.Out, &FLD.RDB$VALIDATION_SOURCE);
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf(NEWLINE);
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
// Handle collations
|
2004-04-24 16:38:27 +02:00
|
|
|
if ((FLD.RDB$FIELD_TYPE == T_CHAR) || (FLD.RDB$FIELD_TYPE == VARCHAR) || (FLD.RDB$FIELD_TYPE == BLOB)) {
|
2004-04-23 20:39:04 +02:00
|
|
|
show_charsets(relation_name, RFR.RDB$FIELD_NAME, false, true, true, true);
|
|
|
|
}
|
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
END_FOR
|
2003-11-30 07:41:29 +01:00
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
2005-05-14 16:50:41 +02:00
|
|
|
return ps_ERR;
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
// If this is a view and there were columns, print the view text
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (!first) {
|
2004-04-23 20:39:04 +02:00
|
|
|
FOR REL IN RDB$RELATIONS WITH
|
2003-11-30 07:41:29 +01:00
|
|
|
REL.RDB$RELATION_NAME EQ relation_name AND
|
|
|
|
REL.RDB$VIEW_BLR NOT MISSING
|
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("View Source:%s==== ======%s", NEWLINE, NEWLINE);
|
2003-11-30 07:41:29 +01:00
|
|
|
if (!REL.RDB$VIEW_SOURCE.NULL)
|
2004-05-24 19:16:02 +02:00
|
|
|
SHOW_print_metadata_text_blob (isqlGlob.Out, &REL.RDB$VIEW_SOURCE);
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf(NEWLINE);
|
2003-11-30 07:41:29 +01:00
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
2005-05-14 16:50:41 +02:00
|
|
|
return ps_ERR;
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
|
|
|
}
|
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
// Handle any referential or primary constraint on this table
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2005-03-26 06:33:55 +01:00
|
|
|
SCHAR collist[BUFFER_LENGTH512];
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
// Static queries for obtaining referential constraints
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
FOR RELC1 IN RDB$RELATION_CONSTRAINTS WITH
|
|
|
|
RELC1.RDB$RELATION_NAME EQ relation_name
|
|
|
|
SORTED BY RELC1.RDB$CONSTRAINT_TYPE, RELC1.RDB$CONSTRAINT_NAME
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2005-03-26 06:33:55 +01:00
|
|
|
ISQL_get_index_segments (collist, sizeof(collist), RELC1.RDB$INDEX_NAME, false);
|
2004-04-23 20:39:04 +02:00
|
|
|
if (!strncmp (RELC1.RDB$CONSTRAINT_TYPE, "PRIMARY", 7)) {
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(RELC1.RDB$CONSTRAINT_NAME);
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("CONSTRAINT %s:%s", RELC1.RDB$CONSTRAINT_NAME, NEWLINE);
|
|
|
|
isqlGlob.printf(" Primary key (%s)%s", collist, NEWLINE);
|
2004-04-23 20:39:04 +02:00
|
|
|
}
|
|
|
|
else if (!strncmp (RELC1.RDB$CONSTRAINT_TYPE, "UNIQUE", 6)) {
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(RELC1.RDB$CONSTRAINT_NAME);
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("CONSTRAINT %s:%s", RELC1.RDB$CONSTRAINT_NAME, NEWLINE);
|
|
|
|
isqlGlob.printf(" Unique key (%s)%s", collist, NEWLINE);
|
2004-04-23 20:39:04 +02:00
|
|
|
}
|
|
|
|
else if (!strncmp (RELC1.RDB$CONSTRAINT_TYPE, "FOREIGN", 7)) {
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(RELC1.RDB$CONSTRAINT_NAME);
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("CONSTRAINT %s:%s", RELC1.RDB$CONSTRAINT_NAME, NEWLINE);
|
2005-03-26 06:33:55 +01:00
|
|
|
ISQL_get_index_segments (collist, sizeof(collist), RELC1.RDB$INDEX_NAME, false);
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(" Foreign key (%s)", collist);
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
FOR RELC2 IN RDB$RELATION_CONSTRAINTS CROSS
|
|
|
|
REFC IN RDB$REF_CONSTRAINTS WITH
|
|
|
|
RELC2.RDB$CONSTRAINT_NAME EQ REFC.RDB$CONST_NAME_UQ AND
|
|
|
|
REFC.RDB$CONSTRAINT_NAME EQ RELC1.RDB$CONSTRAINT_NAME
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2005-03-26 06:33:55 +01:00
|
|
|
ISQL_get_index_segments (collist, sizeof(collist), RELC2.RDB$INDEX_NAME, false);
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(RELC2.RDB$RELATION_NAME);
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(" References %s (%s)",
|
2004-04-23 20:39:04 +02:00
|
|
|
RELC2.RDB$RELATION_NAME, collist);
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
if (!REFC.RDB$UPDATE_RULE.NULL) {
|
|
|
|
ISQL_truncate_term (REFC.RDB$UPDATE_RULE,
|
|
|
|
sizeof(REFC.RDB$UPDATE_RULE));
|
|
|
|
ISQL_ri_action_print (REFC.RDB$UPDATE_RULE, " On Update",
|
|
|
|
false);
|
|
|
|
}
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
if (!REFC.RDB$DELETE_RULE.NULL) {
|
|
|
|
ISQL_truncate_term (REFC.RDB$DELETE_RULE,
|
|
|
|
sizeof(REFC.RDB$DELETE_RULE));
|
|
|
|
ISQL_ri_action_print (REFC.RDB$DELETE_RULE, " On Delete",
|
|
|
|
false);
|
|
|
|
}
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf(NEWLINE);
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg (isc_status);
|
2005-05-14 16:50:41 +02:00
|
|
|
return ps_ERR;
|
2004-04-23 20:39:04 +02:00
|
|
|
END_ERROR;
|
|
|
|
}
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
2005-05-14 16:50:41 +02:00
|
|
|
return ps_ERR;
|
2004-04-23 20:39:04 +02:00
|
|
|
END_ERROR;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
FOR R_C IN RDB$RELATION_CONSTRAINTS CROSS
|
|
|
|
C_C IN RDB$CHECK_CONSTRAINTS
|
|
|
|
WITH R_C.RDB$RELATION_NAME EQ relation_name
|
|
|
|
AND R_C.RDB$CONSTRAINT_TYPE EQ 'NOT NULL'
|
|
|
|
AND R_C.RDB$CONSTRAINT_NAME EQ C_C.RDB$CONSTRAINT_NAME
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
if (strncmp (R_C.RDB$CONSTRAINT_NAME, "INTEG_", 6)) {
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(C_C.RDB$TRIGGER_NAME);
|
|
|
|
fb_utils::exact_name(R_C.RDB$CONSTRAINT_NAME);
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("CONSTRAINT %s:%s", R_C.RDB$CONSTRAINT_NAME,
|
2004-04-23 20:39:04 +02:00
|
|
|
NEWLINE);
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(" Not Null Column (%s)%s",
|
2004-04-23 20:39:04 +02:00
|
|
|
C_C.RDB$TRIGGER_NAME, NEWLINE);
|
|
|
|
}
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
2005-05-14 16:50:41 +02:00
|
|
|
return ps_ERR;
|
2004-04-23 20:39:04 +02:00
|
|
|
END_ERROR;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
// Do check constraints
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-08-28 15:07:29 +02:00
|
|
|
show_check(relation_name);
|
2003-11-30 07:41:29 +01:00
|
|
|
|
|
|
|
// Do triggers
|
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
show_trigger(relation_name, false, false);
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
if (first)
|
2003-12-03 09:19:24 +01:00
|
|
|
return (OBJECT_NOT_FOUND);
|
2001-05-23 15:26:42 +02:00
|
|
|
return SKIP;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
static processing_state show_trigger(
|
|
|
|
const SCHAR* object,
|
|
|
|
bool show_source,
|
|
|
|
bool isTriggerName)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* s h o w _ t r i g g e r
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Show triggers in general or for the named object or trigger
|
|
|
|
*
|
|
|
|
**************************************/
|
2003-09-05 13:25:53 +02:00
|
|
|
bool first = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
// Show all triggers
|
2001-05-23 15:26:42 +02:00
|
|
|
if (!*object)
|
|
|
|
{
|
2004-04-23 20:39:04 +02:00
|
|
|
FOR TRG IN RDB$TRIGGERS CROSS REL IN RDB$RELATIONS
|
|
|
|
WITH (REL.RDB$SYSTEM_FLAG NE 1 OR REL.RDB$SYSTEM_FLAG MISSING) AND
|
|
|
|
TRG.RDB$RELATION_NAME = REL.RDB$RELATION_NAME AND
|
|
|
|
NOT (ANY CHK IN RDB$CHECK_CONSTRAINTS WITH
|
|
|
|
TRG.RDB$TRIGGER_NAME EQ CHK.RDB$TRIGGER_NAME)
|
|
|
|
SORTED BY TRG.RDB$RELATION_NAME, TRG.RDB$TRIGGER_NAME
|
|
|
|
|
|
|
|
if (first)
|
|
|
|
{
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(
|
2004-04-23 20:39:04 +02:00
|
|
|
"Table name Trigger name%s", NEWLINE);
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(
|
2004-04-23 20:39:04 +02:00
|
|
|
"=========== ============%s", NEWLINE);
|
|
|
|
first = false;
|
|
|
|
}
|
|
|
|
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(TRG.RDB$TRIGGER_NAME);
|
|
|
|
fb_utils::exact_name(TRG.RDB$RELATION_NAME);
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%-32s %s%s%s",
|
2004-04-23 20:39:04 +02:00
|
|
|
TRG.RDB$RELATION_NAME,
|
|
|
|
TRG.RDB$TRIGGER_NAME,
|
|
|
|
(TRG.RDB$SYSTEM_FLAG == 1 ? "(system)" : ""),
|
|
|
|
NEWLINE);
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
2005-05-14 16:50:41 +02:00
|
|
|
return ps_ERR;
|
2004-04-23 20:39:04 +02:00
|
|
|
END_ERROR;
|
2001-05-23 15:26:42 +02:00
|
|
|
if (first)
|
2003-12-03 09:19:24 +01:00
|
|
|
return OBJECT_NOT_FOUND;
|
2001-05-23 15:26:42 +02:00
|
|
|
else
|
|
|
|
return (SKIP);
|
|
|
|
}
|
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
// Show triggers for the named object
|
|
|
|
// and avoid check constraints
|
2004-05-09 07:48:33 +02:00
|
|
|
BASED_ON RDB$TRIGGERS.RDB$TRIGGER_NAME triggerName;
|
|
|
|
BASED_ON RDB$TRIGGERS.RDB$RELATION_NAME relationName;
|
|
|
|
|
|
|
|
if (isTriggerName) {
|
2004-06-29 06:37:59 +02:00
|
|
|
sprintf(triggerName, "%s", object);
|
2004-04-23 20:39:04 +02:00
|
|
|
relationName[0] = '\0';
|
|
|
|
}
|
|
|
|
else {
|
2004-06-29 06:37:59 +02:00
|
|
|
sprintf(relationName, "%s", object);
|
2004-04-23 20:39:04 +02:00
|
|
|
triggerName[0] = '\0';
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
FOR TRG IN RDB$TRIGGERS WITH
|
2004-04-23 20:39:04 +02:00
|
|
|
(TRG.RDB$RELATION_NAME EQ relationName OR
|
|
|
|
TRG.RDB$TRIGGER_NAME EQ triggerName)
|
2003-11-30 07:41:29 +01:00
|
|
|
SORTED BY TRG.RDB$RELATION_NAME, TRG.RDB$TRIGGER_TYPE,
|
|
|
|
TRG.RDB$TRIGGER_SEQUENCE, TRG.RDB$TRIGGER_NAME;
|
|
|
|
|
2004-12-04 09:30:43 +01:00
|
|
|
bool skip = false;
|
2004-04-23 20:39:04 +02:00
|
|
|
// Skip triggers for check constraints
|
|
|
|
FOR FIRST 1 CHK IN RDB$CHECK_CONSTRAINTS WITH
|
|
|
|
TRG.RDB$TRIGGER_NAME EQ CHK.RDB$TRIGGER_NAME
|
|
|
|
skip = true;
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg (isc_status);
|
2005-05-14 16:50:41 +02:00
|
|
|
return ps_ERR;
|
2004-04-23 20:39:04 +02:00
|
|
|
END_ERROR;
|
|
|
|
|
|
|
|
if (skip)
|
2003-11-30 07:41:29 +01:00
|
|
|
continue;
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(TRG.RDB$TRIGGER_NAME);
|
|
|
|
fb_utils::exact_name(TRG.RDB$RELATION_NAME);
|
2003-11-30 07:41:29 +01:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
if (first) {
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%sTriggers on Table %s:%s",
|
2003-11-30 07:41:29 +01:00
|
|
|
NEWLINE,
|
|
|
|
TRG.RDB$RELATION_NAME,
|
|
|
|
NEWLINE);
|
2004-04-23 20:39:04 +02:00
|
|
|
first = false;
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%s, Sequence: %d, Type: %s, %s%s",
|
2004-04-23 20:39:04 +02:00
|
|
|
TRG.RDB$TRIGGER_NAME,
|
2003-11-30 07:41:29 +01:00
|
|
|
TRG.RDB$TRIGGER_SEQUENCE,
|
|
|
|
trigger_action (TRG.RDB$TRIGGER_TYPE),
|
|
|
|
(TRG.RDB$TRIGGER_INACTIVE ? "Inactive" : "Active"),
|
|
|
|
NEWLINE);
|
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
if (show_source) {
|
2003-11-30 07:41:29 +01:00
|
|
|
// Use print_blob to print the blob
|
|
|
|
|
|
|
|
if (!TRG.RDB$TRIGGER_SOURCE.NULL)
|
2004-05-24 19:16:02 +02:00
|
|
|
SHOW_print_metadata_text_blob (isqlGlob.Out, &TRG.RDB$TRIGGER_SOURCE);
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%s+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%s", NEWLINE, NEWLINE);
|
2003-11-30 07:41:29 +01:00
|
|
|
}
|
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
END_FOR
|
2003-11-30 07:41:29 +01:00
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(isc_status);
|
2005-05-14 16:50:41 +02:00
|
|
|
return ps_ERR;
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
|
|
|
if (first)
|
2003-12-03 09:19:24 +01:00
|
|
|
return OBJECT_NOT_FOUND;
|
2001-05-23 15:26:42 +02:00
|
|
|
return SKIP;
|
|
|
|
}
|
2003-09-09 13:03:37 +02:00
|
|
|
|