2001-05-23 15:26:42 +02:00
|
|
|
/*
|
|
|
|
* PROGRAM: Interactive SQL utility
|
2003-09-29 14:43:14 +02:00
|
|
|
* MODULE: extract.epp
|
2001-05-23 15:26:42 +02:00
|
|
|
* DESCRIPTION: Definition extract 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.3 2000/11/22 17:07:25 patrickgriffin
|
2001-07-30 01:43:24 +02:00
|
|
|
* In get_procedure_args change comment style from // to c style
|
2001-05-23 15:26:42 +02:00
|
|
|
*
|
|
|
|
* ...pat
|
|
|
|
*
|
2003-09-29 14:43:14 +02:00
|
|
|
* 2001.09.09 Claudio Valderrama: procedure's parameter names may need
|
2002-06-29 15:39:11 +02:00
|
|
|
* double quotes if they are in dialect 3 and have special characters.
|
|
|
|
* 2001.09.21 Claudio Valderrama: Show correct mechanism for UDF parameters
|
|
|
|
* and support the RETURNS PARAMETER <n> syntax.
|
|
|
|
* 2001.10.01 Claudio Valderrama: list_all_grants2() and EXTRACT_list_grants()
|
|
|
|
* to better organize the code that should be called to handle SHOW GRANTS.
|
|
|
|
*
|
2001-05-23 15:26:42 +02:00
|
|
|
* Revision 1.2 2000/11/18 16:49:24 fsg
|
|
|
|
* Increased PRINT_BUFFER_LENGTH to 2048 to show larger plans
|
|
|
|
* Fixed Bug #122563 in extract.e get_procedure_args
|
|
|
|
* Apparently this has to be done in show.e also,
|
|
|
|
* but that is for another day :-)
|
|
|
|
*
|
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>
|
2001-05-23 15:26:42 +02:00
|
|
|
#include <string.h>
|
|
|
|
#include <math.h>
|
2003-11-28 07:48:34 +01:00
|
|
|
#include <ctype.h> // isdigit
|
2001-05-23 15:26:42 +02:00
|
|
|
#include "../jrd/common.h"
|
2003-11-08 17:40:17 +01:00
|
|
|
#include "../jrd/ibase.h"
|
2004-04-24 23:43:35 +02:00
|
|
|
#include "../jrd/gds_proto.h"
|
2001-05-23 15:26:42 +02:00
|
|
|
#include "../isql/isql.h"
|
|
|
|
#include "../isql/extra_proto.h"
|
|
|
|
#include "../isql/isql_proto.h"
|
|
|
|
#include "../isql/show_proto.h"
|
2002-06-29 15:39:11 +02:00
|
|
|
#include "../jrd/obj.h"
|
2001-05-23 15:26:42 +02:00
|
|
|
#include "../jrd/ods.h"
|
2003-12-31 06:36:12 +01:00
|
|
|
#include "../common/utils_proto.h"
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
DATABASE DB = EXTERN COMPILETIME "yachts.lnk";
|
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
static void list_all_grants();
|
2003-12-03 09:19:24 +01:00
|
|
|
static processing_state list_all_grants2(bool, const SCHAR*);
|
2003-11-30 07:41:29 +01:00
|
|
|
static void list_all_procs();
|
2005-05-19 10:03:10 +02:00
|
|
|
static void list_all_tables(LegacyTables flag, SSHORT);
|
2003-11-30 07:41:29 +01:00
|
|
|
static void list_all_triggers();
|
|
|
|
static void list_check();
|
|
|
|
static void list_create_db();
|
|
|
|
static void list_domain_table(const SCHAR*, SSHORT);
|
2001-05-23 15:26:42 +02:00
|
|
|
static void list_domains(SSHORT);
|
2003-11-30 07:41:29 +01:00
|
|
|
static void list_exception();
|
|
|
|
static void list_filters();
|
|
|
|
static void list_foreign();
|
|
|
|
static void list_functions();
|
|
|
|
static void list_generators();
|
|
|
|
static void list_index();
|
|
|
|
static void list_views();
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-12-03 08:22:49 +01:00
|
|
|
static void get_procedure_args(const char*);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-02-04 16:36:46 +01:00
|
|
|
extern const char* trigger_action(int);
|
|
|
|
|
2004-06-05 11:37:18 +02:00
|
|
|
static const char* Procterm = "^"; // TXNN: script use only
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
/* Maybe 512 would be really enough as Print_buffer size, but
|
2003-09-29 14:43:14 +02:00
|
|
|
as we have PRINT_BUFFER_LENGTH in isql.h, we should use it
|
2001-05-23 15:26:42 +02:00
|
|
|
FSG 17.Nov.2000
|
|
|
|
*/
|
|
|
|
|
|
|
|
static TEXT Print_buffer[PRINT_BUFFER_LENGTH];
|
|
|
|
static TEXT SQL_identifier[BUFFER_LENGTH128];
|
|
|
|
static TEXT SQL_identifier2[BUFFER_LENGTH128];
|
|
|
|
|
|
|
|
|
|
|
|
|
2005-05-19 10:03:10 +02:00
|
|
|
int EXTRACT_ddl(LegacyTables flag,
|
2004-11-23 12:03:48 +01:00
|
|
|
const SCHAR* tabname)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* E X T R A C T _ d d l
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Extract all sql information
|
|
|
|
* 0 flag means SQL only tables. 1 flag means all tables
|
|
|
|
*
|
|
|
|
**************************************/
|
2003-09-05 13:25:53 +02:00
|
|
|
bool did_attach = false;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (!DB)
|
|
|
|
{
|
2004-05-24 19:16:02 +02:00
|
|
|
if (isc_attach_database(gds_status, 0, isqlGlob.global_Db_name, &DB, 0, NULL))
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2001-07-12 08:32:05 +02:00
|
|
|
ISQL_errmsg(gds_status);
|
2003-12-03 09:19:24 +01:00
|
|
|
return FINI_ERROR;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
2003-09-05 13:25:53 +02:00
|
|
|
did_attach = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2003-09-05 13:25:53 +02:00
|
|
|
ISQL_get_version(false);
|
2004-05-24 19:16:02 +02:00
|
|
|
if (isqlGlob.SQL_dialect != isqlGlob.db_SQL_dialect)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(
|
2001-05-23 15:26:42 +02:00
|
|
|
"/*=========================================================*/%s",
|
|
|
|
NEWLINE);
|
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(
|
2001-05-23 15:26:42 +02:00
|
|
|
"/*= ==*/%s",
|
|
|
|
NEWLINE);
|
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(
|
2001-05-23 15:26:42 +02:00
|
|
|
"/*= Command Line -sqldialect %d is overwritten by ==*/%s",
|
2004-05-24 19:16:02 +02:00
|
|
|
isqlGlob.SQL_dialect, NEWLINE);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(
|
2001-05-23 15:26:42 +02:00
|
|
|
"/*= Database SQL Dialect %d. ==*/%s",
|
2004-05-24 19:16:02 +02:00
|
|
|
isqlGlob.db_SQL_dialect, NEWLINE);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(
|
2001-05-23 15:26:42 +02:00
|
|
|
"/*= ==*/%s",
|
|
|
|
NEWLINE);
|
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(
|
2001-05-23 15:26:42 +02:00
|
|
|
"/*=========================================================*/%s",
|
|
|
|
NEWLINE);
|
|
|
|
}
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf(NEWLINE);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("SET SQL DIALECT %d; %s", isqlGlob.db_SQL_dialect, NEWLINE);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(NEWLINE);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-12-04 09:30:43 +01:00
|
|
|
bool did_start = false;
|
2001-07-12 08:32:05 +02:00
|
|
|
if (!gds_trans)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-09-01 09:58:04 +02:00
|
|
|
if (isc_start_transaction(gds_status, &gds_trans, 1, &DB, 0, NULL))
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2001-07-12 08:32:05 +02:00
|
|
|
ISQL_errmsg(gds_status);
|
2003-12-03 09:19:24 +01:00
|
|
|
return FINI_ERROR;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
2003-09-05 13:25:53 +02:00
|
|
|
did_start = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
const SSHORT default_char_set_id = ISQL_get_default_char_set_id();
|
2004-12-04 09:30:43 +01:00
|
|
|
int ret_code = FINI_OK;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2005-05-19 10:03:10 +02:00
|
|
|
// If a table name was passed, extract only that table and domains
|
2001-05-23 15:26:42 +02:00
|
|
|
if (*tabname)
|
|
|
|
{
|
2003-09-05 13:25:53 +02:00
|
|
|
if (EXTRACT_list_table(tabname, NULL, true, default_char_set_id))
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2005-03-31 09:50:32 +02:00
|
|
|
SCHAR errbuf[MSG_LENGTH];
|
2005-05-19 10:03:10 +02:00
|
|
|
ISQL_msg_get(NOT_FOUND_MSG, errbuf, tabname);
|
2005-03-26 06:33:55 +01:00
|
|
|
STDERROUT(errbuf);
|
2003-12-03 09:19:24 +01:00
|
|
|
ret_code = FINI_ERROR;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
list_create_db();
|
|
|
|
list_filters();
|
|
|
|
list_functions();
|
2003-09-29 14:43:14 +02:00
|
|
|
list_generators();
|
2001-05-23 15:26:42 +02:00
|
|
|
list_domains(default_char_set_id);
|
|
|
|
list_all_tables(flag, default_char_set_id);
|
|
|
|
list_index();
|
|
|
|
list_foreign();
|
|
|
|
list_views();
|
|
|
|
list_check();
|
|
|
|
list_exception();
|
|
|
|
list_all_procs();
|
|
|
|
list_all_triggers();
|
|
|
|
list_all_grants();
|
2005-05-19 10:03:10 +02:00
|
|
|
SHOW_comments(false); // Let's make this an option later.
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2001-07-12 08:32:05 +02:00
|
|
|
if (gds_trans && did_start)
|
|
|
|
if (isc_commit_transaction(gds_status, &gds_trans))
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2001-07-12 08:32:05 +02:00
|
|
|
ISQL_errmsg(gds_status);
|
2003-12-03 09:19:24 +01:00
|
|
|
return FINI_ERROR;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (DB && did_attach)
|
|
|
|
{
|
2001-07-12 08:32:05 +02:00
|
|
|
if (isc_detach_database(gds_status, &DB))
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2001-07-12 08:32:05 +02:00
|
|
|
ISQL_errmsg(gds_status);
|
2003-12-03 09:19:24 +01:00
|
|
|
return FINI_ERROR;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
2004-05-03 01:06:37 +02:00
|
|
|
DB = 0;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2003-12-03 09:19:24 +01:00
|
|
|
return ret_code;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2003-09-05 13:25:53 +02:00
|
|
|
|
2003-12-03 09:19:24 +01:00
|
|
|
processing_state EXTRACT_list_grants(const SCHAR* terminator)
|
2002-06-29 15:39:11 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* E X T R A C T _ l i s t _ g r a n t s
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
2005-04-02 05:51:43 +02:00
|
|
|
* Print the permissions on all user tables, views and procedures.
|
2002-06-29 15:39:11 +02:00
|
|
|
*
|
|
|
|
**************************************/
|
2003-11-30 07:41:29 +01:00
|
|
|
return list_all_grants2(false, terminator);
|
2002-06-29 15:39:11 +02:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-09-05 13:25:53 +02:00
|
|
|
|
2003-12-03 09:19:24 +01:00
|
|
|
int EXTRACT_list_table(const SCHAR* relation_name,
|
2003-11-30 07:41:29 +01:00
|
|
|
const SCHAR* new_name,
|
2003-09-05 13:25:53 +02:00
|
|
|
bool domain_flag,
|
|
|
|
SSHORT default_char_set_id)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* E X T R A C T _ l i s t _ t a b l e
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Shows columns, types, info for a given table name
|
|
|
|
* and text of views.
|
|
|
|
* Use a GDML query to get the info and print it.
|
|
|
|
* If a new_name is passed, substitute it for relation_name
|
|
|
|
*
|
|
|
|
* relation_name -- Name of table to investigate
|
|
|
|
* new_name -- Name of a new name for a replacement table
|
|
|
|
* domain_flag -- extract needed domains before the table
|
|
|
|
* default_char_set_id -- character set def to supress
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
/**************************************
|
|
|
|
* default_char_set_id warrents special
|
|
|
|
* consideration. If the metadata for a
|
|
|
|
* table is being extracted when there is
|
|
|
|
* really no need to redundantly and repeatedly
|
|
|
|
* list the databases default character set
|
|
|
|
* for every field.
|
|
|
|
*
|
|
|
|
* At the same time there is a need to list
|
|
|
|
* the character set NONE when it is not
|
|
|
|
* the default character set for the database.
|
|
|
|
*
|
|
|
|
* EXCEPT! If the metadata is being extracted
|
|
|
|
* with the intention of coping that tables structure
|
|
|
|
* into another database, and it is not possible
|
|
|
|
* to know the default character set for the
|
|
|
|
* target database, then list every fields
|
|
|
|
* character set. This includes the character
|
|
|
|
* set NONE.
|
|
|
|
*
|
|
|
|
* Fields with no character set definition will
|
|
|
|
* not have any character set listed.
|
|
|
|
*
|
|
|
|
* Use -1 as the default_char_set_id
|
|
|
|
* in this case.
|
|
|
|
*
|
|
|
|
* POTENTIAL TRAP! Consider the following:
|
|
|
|
* When copying a table from one database
|
|
|
|
* to another how should fields using the
|
|
|
|
* default character set be handled?
|
|
|
|
*
|
|
|
|
* If both databases have the same default
|
|
|
|
* character set, then there is no problem
|
|
|
|
* or confusion.
|
|
|
|
*
|
|
|
|
* If the databases have different default
|
|
|
|
* character sets then should fields using
|
|
|
|
* the default is the source database use
|
|
|
|
* the default of the target database?
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
|
2003-09-05 13:25:53 +02:00
|
|
|
bool first = true;
|
|
|
|
SCHAR char_sets[86];
|
2004-12-04 09:30:43 +01:00
|
|
|
//bool intchar = false;
|
2003-09-29 14:43:14 +02:00
|
|
|
// CVC: shouldn't this var be initialized inside the FOR statement instead?
|
2004-12-04 09:30:43 +01:00
|
|
|
// CVC: 2004.12.03: I discovered someone made this variable obsolete;
|
|
|
|
// it's set but never used. Hope the change was right. I commented it.
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-11-28 07:48:34 +01:00
|
|
|
// Query to obtain relation detail information
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
FOR REL IN RDB$RELATIONS CROSS
|
2003-09-29 14:43:14 +02:00
|
|
|
RFR IN RDB$RELATION_FIELDS CROSS
|
|
|
|
FLD IN RDB$FIELDS WITH
|
|
|
|
RFR.RDB$FIELD_SOURCE EQ FLD.RDB$FIELD_NAME AND
|
|
|
|
RFR.RDB$RELATION_NAME EQ REL.RDB$RELATION_NAME AND
|
|
|
|
REL.RDB$RELATION_NAME EQ relation_name
|
|
|
|
SORTED BY RFR.RDB$FIELD_POSITION, RFR.RDB$FIELD_NAME
|
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
SSHORT collation = 0;
|
|
|
|
SSHORT char_set_id = 0;
|
|
|
|
|
2003-09-29 14:43:14 +02:00
|
|
|
if (first)
|
|
|
|
{
|
|
|
|
first = false;
|
2003-11-28 07:48:34 +01:00
|
|
|
// Do we need to print domains
|
2003-09-29 14:43:14 +02:00
|
|
|
if (domain_flag)
|
2003-11-30 07:41:29 +01:00
|
|
|
list_domain_table (relation_name, default_char_set_id);
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(REL.RDB$OWNER_NAME);
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%s/* Table: %s, Owner: %s */%s",
|
2003-09-29 14:43:14 +02:00
|
|
|
NEWLINE,
|
|
|
|
relation_name,
|
|
|
|
REL.RDB$OWNER_NAME,
|
|
|
|
NEWLINE);
|
2004-05-24 19:16:02 +02:00
|
|
|
if (isqlGlob.db_SQL_dialect > SQL_DIALECT_V6_TRANSITION)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-09-29 14:43:14 +02:00
|
|
|
if (new_name)
|
|
|
|
ISQL_copy_SQL_id (new_name, SQL_identifier, DBL_QUOTE);
|
|
|
|
else
|
|
|
|
ISQL_copy_SQL_id (relation_name, SQL_identifier, DBL_QUOTE);
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("CREATE TABLE %s ", SQL_identifier);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
else
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("CREATE TABLE %s ",
|
2003-09-29 14:43:14 +02:00
|
|
|
new_name ? new_name : relation_name);
|
|
|
|
if (!REL.RDB$EXTERNAL_FILE.NULL)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-09-29 14:43:14 +02:00
|
|
|
ISQL_copy_SQL_id (REL.RDB$EXTERNAL_FILE, SQL_identifier2,
|
|
|
|
SINGLE_QUOTE);
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("EXTERNAL FILE %s ", SQL_identifier2);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf("(");
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(",%s%s", NEWLINE, TAB_AS_SPACES);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
|
2004-05-24 19:16:02 +02:00
|
|
|
if (isqlGlob.db_SQL_dialect > SQL_DIALECT_V6_TRANSITION)
|
2003-09-29 14:43:14 +02:00
|
|
|
{
|
2004-09-26 03:49:52 +02:00
|
|
|
ISQL_copy_SQL_id (fb_utils::exact_name(RFR.RDB$FIELD_NAME),
|
2003-09-29 14:43:14 +02:00
|
|
|
SQL_identifier, DBL_QUOTE);
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%s ", SQL_identifier);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
else
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%s ", fb_utils::exact_name(RFR.RDB$FIELD_NAME));
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
/*
|
|
|
|
** Check first for computed fields, then domains.
|
|
|
|
** If this is a known domain, then just print the domain rather than type
|
|
|
|
** Domains won't have length, array, or blob definitions, but they
|
|
|
|
** may have not null, default and check overriding their definitions
|
|
|
|
*/
|
2003-09-29 14:43:14 +02:00
|
|
|
|
|
|
|
if (!FLD.RDB$COMPUTED_BLR.NULL)
|
|
|
|
{
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf("COMPUTED BY ");
|
2003-09-29 14:43:14 +02:00
|
|
|
if (!FLD.RDB$COMPUTED_SOURCE.NULL)
|
2004-05-24 19:16:02 +02:00
|
|
|
ISQL_print_validation (isqlGlob.Out, &FLD.RDB$COMPUTED_SOURCE, true, gds_trans);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
else if (!((strncmp(FLD.RDB$FIELD_NAME, "RDB$", 4) == 0) &&
|
|
|
|
isdigit (FLD.RDB$FIELD_NAME[4]) &&
|
|
|
|
FLD.RDB$SYSTEM_FLAG != 1))
|
|
|
|
{
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(FLD.RDB$FIELD_NAME);
|
2004-05-24 19:16:02 +02:00
|
|
|
if (isqlGlob.db_SQL_dialect > SQL_DIALECT_V6_TRANSITION)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-09-29 14:43:14 +02:00
|
|
|
ISQL_copy_SQL_id (FLD.RDB$FIELD_NAME, SQL_identifier, DBL_QUOTE);
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.prints(SQL_identifier);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
else
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.prints(FLD.RDB$FIELD_NAME);
|
2005-05-24 06:42:01 +02:00
|
|
|
|
|
|
|
// International character sets
|
2004-04-23 20:39:04 +02:00
|
|
|
// Print only the character set
|
2004-04-24 16:38:27 +02:00
|
|
|
if ((FLD.RDB$FIELD_TYPE == T_CHAR || FLD.RDB$FIELD_TYPE == VARCHAR)
|
2003-09-29 14:43:14 +02:00
|
|
|
&& !RFR.RDB$COLLATION_ID.NULL && RFR.RDB$COLLATION_ID)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-11-28 07:48:34 +01:00
|
|
|
char_sets[0] = '\0';
|
2003-09-29 14:43:14 +02:00
|
|
|
collation = RFR.RDB$COLLATION_ID;
|
2004-04-23 20:39:04 +02:00
|
|
|
char_set_id = FLD.RDB$CHARACTER_SET_ID;
|
|
|
|
ISQL_get_character_sets (FLD.RDB$CHARACTER_SET_ID, 0, true, char_sets);
|
2003-11-28 07:48:34 +01:00
|
|
|
if (char_sets[0])
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.prints(char_sets);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2003-11-28 07:48:34 +01:00
|
|
|
// Look through types array
|
2004-12-04 09:30:43 +01:00
|
|
|
for (int i = 0; Column_types[i].type; i++)
|
2003-11-28 07:48:34 +01:00
|
|
|
if (FLD.RDB$FIELD_TYPE == Column_types[i].type)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-09-29 14:43:14 +02:00
|
|
|
bool precision_known = false;
|
|
|
|
|
2004-05-24 19:16:02 +02:00
|
|
|
if (isqlGlob.major_ods >= ODS_VERSION10)
|
2003-09-29 14:43:14 +02:00
|
|
|
{
|
2003-11-28 07:48:34 +01:00
|
|
|
// Handle Integral subtypes NUMERIC and DECIMAL
|
2003-09-29 14:43:14 +02:00
|
|
|
if ((FLD.RDB$FIELD_TYPE == SMALLINT) ||
|
|
|
|
(FLD.RDB$FIELD_TYPE == INTEGER) ||
|
2004-09-22 03:55:37 +02:00
|
|
|
(FLD.RDB$FIELD_TYPE == BIGINT))
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-09-29 14:43:14 +02: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)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-09-29 14:43:14 +02:00
|
|
|
sprintf (Print_buffer, "%s(%d, %d)",
|
2003-11-28 07:48:34 +01:00
|
|
|
Integral_subtypes[FLD1.RDB$FIELD_SUB_TYPE],
|
2003-09-29 14:43:14 +02:00
|
|
|
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-09-29 14:43:14 +02:00
|
|
|
END_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!precision_known)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2003-11-28 07:48:34 +01:00
|
|
|
// Take a stab at numerics and decimals
|
2003-09-29 14:43:14 +02:00
|
|
|
if ((FLD.RDB$FIELD_TYPE == SMALLINT) &&
|
|
|
|
(FLD.RDB$FIELD_SCALE < 0))
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-09-29 14:43:14 +02:00
|
|
|
sprintf (Print_buffer, "NUMERIC(4, %d)",
|
|
|
|
-FLD.RDB$FIELD_SCALE);
|
|
|
|
}
|
|
|
|
else if ((FLD.RDB$FIELD_TYPE == INTEGER) &&
|
|
|
|
(FLD.RDB$FIELD_SCALE < 0))
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-09-29 14:43:14 +02:00
|
|
|
sprintf (Print_buffer, "NUMERIC(9, %d)",
|
|
|
|
-FLD.RDB$FIELD_SCALE);
|
|
|
|
}
|
|
|
|
else if ((FLD.RDB$FIELD_TYPE == DOUBLE_PRECISION) &&
|
|
|
|
(FLD.RDB$FIELD_SCALE < 0))
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-09-29 14:43:14 +02:00
|
|
|
sprintf (Print_buffer, "NUMERIC(15, %d)",
|
|
|
|
-FLD.RDB$FIELD_SCALE);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
sprintf (Print_buffer, "%s",
|
2003-11-28 07:48:34 +01:00
|
|
|
Column_types[i].type_name);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.prints(Print_buffer);
|
2003-09-29 14:43:14 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-04-24 16:38:27 +02:00
|
|
|
if ((FLD.RDB$FIELD_TYPE == T_CHAR) || (FLD.RDB$FIELD_TYPE == VARCHAR))
|
2003-09-29 14:43:14 +02:00
|
|
|
if (FLD.RDB$CHARACTER_LENGTH.NULL)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf("(%d)", FLD.RDB$FIELD_LENGTH);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
else
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf("(%d)", FLD.RDB$CHARACTER_LENGTH);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
|
2003-11-28 07:48:34 +01:00
|
|
|
// Catch arrays after printing the type
|
2003-09-29 14:43:14 +02:00
|
|
|
|
|
|
|
if (!FLD.RDB$DIMENSIONS.NULL)
|
|
|
|
ISQL_array_dimensions (FLD.RDB$FIELD_NAME);
|
|
|
|
|
|
|
|
if (FLD.RDB$FIELD_TYPE == BLOB)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2004-12-07 01:33:16 +01:00
|
|
|
const int subtype = FLD.RDB$FIELD_SUB_TYPE;
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf(" SUB_TYPE ");
|
2004-05-24 19:16:02 +02:00
|
|
|
if ((subtype > 0) && (subtype <= MAX_BLOBSUBTYPES))
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.prints(Sub_types[subtype]);
|
2003-09-29 14:43:14 +02:00
|
|
|
else
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf("%d", subtype);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf(" SEGMENT SIZE %u",
|
2003-09-29 14:43:14 +02:00
|
|
|
(USHORT) FLD.RDB$SEGMENT_LENGTH);
|
|
|
|
}
|
|
|
|
|
2003-11-28 07:48:34 +01:00
|
|
|
// International character sets
|
2004-04-24 16:38:27 +02:00
|
|
|
if ((FLD.RDB$FIELD_TYPE == T_CHAR || FLD.RDB$FIELD_TYPE == VARCHAR ||
|
2003-09-29 14:43:14 +02:00
|
|
|
FLD.RDB$FIELD_TYPE == BLOB) &&
|
|
|
|
!FLD.RDB$CHARACTER_SET_ID.NULL)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
|
2003-11-28 07:48:34 +01:00
|
|
|
char_sets[0] = '\0';
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2004-03-07 08:58:55 +01:00
|
|
|
// Override rdb$fields id with relation_fields if present
|
2003-09-29 14:43:14 +02:00
|
|
|
|
|
|
|
if (!RFR.RDB$COLLATION_ID.NULL)
|
|
|
|
collation = RFR.RDB$COLLATION_ID;
|
|
|
|
else if (!FLD.RDB$COLLATION_ID.NULL)
|
|
|
|
collation = FLD.RDB$COLLATION_ID;
|
|
|
|
|
|
|
|
if (!FLD.RDB$CHARACTER_SET_ID.NULL)
|
|
|
|
char_set_id = FLD.RDB$CHARACTER_SET_ID;
|
|
|
|
if ((char_set_id != default_char_set_id) || collation)
|
|
|
|
ISQL_get_character_sets (char_set_id, 0, false, char_sets);
|
2003-11-28 07:48:34 +01:00
|
|
|
if (char_sets[0])
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.prints(char_sets);
|
2004-12-04 09:30:43 +01:00
|
|
|
// CVC: Someone deleted the code that checks intchar when handling collations
|
|
|
|
// several lines below, so it didn't have any effect. Commented it.
|
|
|
|
//if (!char_set_id)
|
|
|
|
// intchar = true;
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-11-28 07:48:34 +01:00
|
|
|
// Handle defaults for columns
|
2003-09-29 14:43:14 +02:00
|
|
|
|
|
|
|
if (!RFR.RDB$DEFAULT_SOURCE.NULL)
|
|
|
|
{
|
|
|
|
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf(" ");
|
2004-05-24 19:16:02 +02:00
|
|
|
SHOW_print_metadata_text_blob (isqlGlob.Out, &RFR.RDB$DEFAULT_SOURCE);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
/* The null flag is either 1 or null (for nullable) . if there is
|
|
|
|
** a constraint name, print that too. Domains cannot have named
|
|
|
|
** constraints. The column name is in rdb$trigger_name in
|
|
|
|
** rdb$check_constraints. We hope we get at most one row back.
|
|
|
|
*/
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
if (RFR.RDB$NULL_FLAG == 1)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-09-29 14:43:14 +02:00
|
|
|
FOR RCO IN RDB$RELATION_CONSTRAINTS CROSS
|
|
|
|
CON IN RDB$CHECK_CONSTRAINTS WITH
|
|
|
|
CON.RDB$TRIGGER_NAME = RFR.RDB$FIELD_NAME AND
|
|
|
|
CON.RDB$CONSTRAINT_NAME = RCO.RDB$CONSTRAINT_NAME AND
|
|
|
|
RCO.RDB$CONSTRAINT_TYPE EQ "NOT NULL" AND
|
|
|
|
RCO.RDB$RELATION_NAME = RFR.RDB$RELATION_NAME
|
|
|
|
|
|
|
|
if (strncmp(CON.RDB$CONSTRAINT_NAME, "INTEG", 5))
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(CON.RDB$CONSTRAINT_NAME);
|
2004-05-24 19:16:02 +02:00
|
|
|
if (isqlGlob.db_SQL_dialect > SQL_DIALECT_V6_TRANSITION)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
|
2003-09-29 14:43:14 +02:00
|
|
|
ISQL_copy_SQL_id (CON.RDB$CONSTRAINT_NAME, SQL_identifier,
|
|
|
|
DBL_QUOTE);
|
|
|
|
sprintf (Print_buffer, " CONSTRAINT %s", SQL_identifier);
|
|
|
|
}
|
|
|
|
else
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf(" CONSTRAINT %s",
|
2003-09-29 14:43:14 +02:00
|
|
|
CON.RDB$CONSTRAINT_NAME);
|
|
|
|
}
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg (gds_status);
|
2005-03-26 06:33:55 +01:00
|
|
|
return FINI_ERROR;
|
2003-09-29 14:43:14 +02:00
|
|
|
END_ERROR;
|
|
|
|
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf(" NOT NULL");
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
// Handle collations after defaults
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
if (collation)
|
|
|
|
{
|
|
|
|
char_sets[0] = '\0';
|
|
|
|
ISQL_get_character_sets (char_set_id, collation, true, char_sets);
|
|
|
|
if (char_sets[0])
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.prints(char_sets);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
END_FOR
|
2003-09-29 14:43:14 +02:00
|
|
|
ON_ERROR
|
2004-04-23 20:39:04 +02:00
|
|
|
ISQL_errmsg(gds_status);
|
2005-03-26 06:33:55 +01:00
|
|
|
return FINI_ERROR;
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
|
|
|
|
2003-11-28 07:48:34 +01:00
|
|
|
// Do primary and unique keys only. references come later
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2005-03-26 06:33:55 +01:00
|
|
|
SCHAR collist[BUFFER_LENGTH512 * 2];
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
FOR RELC IN RDB$RELATION_CONSTRAINTS WITH
|
2003-09-29 14:43:14 +02:00
|
|
|
(RELC.RDB$CONSTRAINT_TYPE EQ "PRIMARY KEY" OR
|
|
|
|
RELC.RDB$CONSTRAINT_TYPE EQ "UNIQUE") AND
|
|
|
|
RELC.RDB$RELATION_NAME EQ relation_name
|
|
|
|
SORTED BY RELC.RDB$CONSTRAINT_NAME
|
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(",%s", NEWLINE);
|
|
|
|
// If the name of the constraint is not INTEG..., print it
|
2003-09-29 14:43:14 +02:00
|
|
|
if (strncmp(RELC.RDB$CONSTRAINT_NAME, "INTEG", 5))
|
|
|
|
{
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(RELC.RDB$CONSTRAINT_NAME);
|
2004-05-24 19:16:02 +02:00
|
|
|
if (isqlGlob.db_SQL_dialect > SQL_DIALECT_V6_TRANSITION)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-09-29 14:43:14 +02:00
|
|
|
ISQL_copy_SQL_id (RELC.RDB$CONSTRAINT_NAME, SQL_identifier,
|
|
|
|
DBL_QUOTE);
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("CONSTRAINT %s ", SQL_identifier);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
else
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("CONSTRAINT %s ", RELC.RDB$CONSTRAINT_NAME);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!strncmp (RELC.RDB$CONSTRAINT_TYPE, "PRIMARY", 7))
|
|
|
|
{
|
2005-03-26 06:33:55 +01:00
|
|
|
ISQL_get_index_segments (collist, sizeof(collist), RELC.RDB$INDEX_NAME, true);
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("PRIMARY KEY (%s)", collist);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
else if (!strncmp (RELC.RDB$CONSTRAINT_TYPE, "UNIQUE", 6))
|
|
|
|
{
|
2005-03-26 06:33:55 +01:00
|
|
|
ISQL_get_index_segments (collist, sizeof(collist), RELC.RDB$INDEX_NAME, true);
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("UNIQUE (%s)", collist);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(gds_status);
|
2005-03-26 06:33:55 +01:00
|
|
|
return FINI_ERROR;
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
|
|
|
|
2005-04-02 05:51:43 +02:00
|
|
|
// Check constaints are now deferred
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2005-03-26 06:33:55 +01:00
|
|
|
if (first) // we extracted nothing
|
|
|
|
return FINI_ERROR;
|
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(")%s%s", isqlGlob.global_Term, NEWLINE);
|
2005-03-26 06:33:55 +01:00
|
|
|
return FINI_OK;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2003-09-05 13:25:53 +02:00
|
|
|
|
2004-12-03 08:22:49 +01:00
|
|
|
static void get_procedure_args(const char* proc_name)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* g e t _ p r o c e d u r e _ a r g s
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* This function extract the procedure parameters and adds it to the
|
|
|
|
* extract file
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
SCHAR char_sets[86];
|
|
|
|
|
2003-11-28 07:48:34 +01:00
|
|
|
// query to retrieve the parameters.
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
|
|
|
|
/* placed the two identical code blocks into one
|
2004-12-03 08:22:49 +01:00
|
|
|
for loop as suggested by Ann H. and Claudio V.
|
2001-05-23 15:26:42 +02:00
|
|
|
FSG 18.Nov.2000
|
|
|
|
*/
|
|
|
|
|
2004-12-03 08:22:49 +01:00
|
|
|
// Parameter types 0 = input
|
|
|
|
// Parameter types 1 = return
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-12-03 08:22:49 +01:00
|
|
|
for (SSHORT ptype = 0; ptype < 2; ptype++)
|
|
|
|
{
|
|
|
|
bool first_time = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-12-03 08:22:49 +01:00
|
|
|
FOR PRM IN RDB$PROCEDURE_PARAMETERS CROSS
|
|
|
|
FLD IN RDB$FIELDS WITH
|
|
|
|
PRM.RDB$PROCEDURE_NAME = proc_name AND
|
|
|
|
PRM.RDB$FIELD_SOURCE EQ FLD.RDB$FIELD_NAME AND
|
|
|
|
PRM.RDB$PARAMETER_TYPE = ptype
|
|
|
|
SORTED BY PRM.RDB$PARAMETER_NUMBER
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2004-12-03 08:22:49 +01:00
|
|
|
if (first_time)
|
|
|
|
{
|
|
|
|
first_time = false;
|
|
|
|
if (ptype == 0)
|
|
|
|
{ // this is the input part
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf("(");
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
else
|
2004-12-03 08:22:49 +01:00
|
|
|
{ // we are in the output part
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf("RETURNS (");
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
2004-12-03 08:22:49 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(",%s", NEWLINE);
|
2004-12-03 08:22:49 +01:00
|
|
|
}
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2004-12-03 08:22:49 +01:00
|
|
|
fb_utils::exact_name(PRM.RDB$PARAMETER_NAME);
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2004-12-03 08:22:49 +01:00
|
|
|
// CVC: Parameter names need check for dialect 3, too.
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2004-12-03 08:22:49 +01:00
|
|
|
if (isqlGlob.db_SQL_dialect > SQL_DIALECT_V6_TRANSITION)
|
|
|
|
ISQL_copy_SQL_id (PRM.RDB$PARAMETER_NAME, SQL_identifier, DBL_QUOTE);
|
|
|
|
else
|
|
|
|
strcpy (SQL_identifier, PRM.RDB$PARAMETER_NAME);
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%s ", SQL_identifier);
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2004-12-03 08:22:49 +01:00
|
|
|
// Get column type name to print
|
|
|
|
for (int i = 0; Column_types[i].type; i++)
|
|
|
|
if (FLD.RDB$FIELD_TYPE == Column_types[i].type)
|
|
|
|
{
|
|
|
|
bool precision_known = false;
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2004-12-03 08:22:49 +01:00
|
|
|
if (isqlGlob.major_ods >= ODS_VERSION10)
|
|
|
|
{
|
|
|
|
// Handle Integral subtypes NUMERIC and DECIMAL
|
|
|
|
if ((FLD.RDB$FIELD_TYPE == SMALLINT) ||
|
|
|
|
(FLD.RDB$FIELD_TYPE == INTEGER) ||
|
|
|
|
(FLD.RDB$FIELD_TYPE == BIGINT))
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2004-12-03 08:22:49 +01:00
|
|
|
/* We are ODS >= 10 and could be any Dialect */
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2004-12-03 08:22:49 +01:00
|
|
|
FOR FLD1 IN RDB$FIELDS WITH
|
|
|
|
FLD1.RDB$FIELD_NAME EQ FLD.RDB$FIELD_NAME
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2004-12-03 08:22:49 +01:00
|
|
|
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)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2004-12-03 08:22:49 +01:00
|
|
|
sprintf (Print_buffer, "%s(%d, %d)",
|
|
|
|
Integral_subtypes[FLD1.RDB$FIELD_SUB_TYPE],
|
|
|
|
FLD1.RDB$FIELD_PRECISION,
|
|
|
|
-FLD1.RDB$FIELD_SCALE);
|
|
|
|
precision_known = true;
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
2004-12-03 08:22:49 +01:00
|
|
|
}
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg (isc_status);
|
|
|
|
return;
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
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);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
2004-12-03 08:22:49 +01:00
|
|
|
else
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2004-12-03 08:22:49 +01:00
|
|
|
sprintf (Print_buffer, "%s",
|
|
|
|
Column_types[i].type_name);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
}
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.prints(Print_buffer);
|
2004-12-03 08:22:49 +01:00
|
|
|
break;
|
|
|
|
}
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2004-12-03 08:22:49 +01:00
|
|
|
/* Changed this to return RDB$CHARACTER_LENGTH if available
|
|
|
|
Fix for Bug #122563
|
|
|
|
FSG 18.Nov.2000
|
|
|
|
*/
|
|
|
|
if ((FLD.RDB$FIELD_TYPE == T_CHAR) || (FLD.RDB$FIELD_TYPE == VARCHAR))
|
|
|
|
if (FLD.RDB$CHARACTER_LENGTH.NULL)
|
|
|
|
{
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf("(%d)", FLD.RDB$FIELD_LENGTH);
|
2004-12-03 08:22:49 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf("(%d)", FLD.RDB$CHARACTER_LENGTH);
|
2004-12-03 08:22:49 +01:00
|
|
|
}
|
2003-09-29 14:43:14 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
2004-12-03 08:22:49 +01:00
|
|
|
// Show international character sets and collations
|
|
|
|
if (!FLD.RDB$COLLATION_ID.NULL || !FLD.RDB$CHARACTER_SET_ID.NULL)
|
|
|
|
{
|
|
|
|
char_sets[0] = 0;
|
|
|
|
if (FLD.RDB$COLLATION_ID.NULL)
|
|
|
|
FLD.RDB$COLLATION_ID = 0;
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2004-12-03 08:22:49 +01:00
|
|
|
if (FLD.RDB$CHARACTER_SET_ID.NULL)
|
|
|
|
FLD.RDB$CHARACTER_SET_ID = 0;
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2004-12-03 08:22:49 +01:00
|
|
|
ISQL_get_character_sets (FLD.RDB$CHARACTER_SET_ID,
|
|
|
|
FLD.RDB$COLLATION_ID, false, char_sets);
|
|
|
|
if (char_sets[0])
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.prints(char_sets);
|
2004-12-03 08:22:49 +01:00
|
|
|
}
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(gds_status);
|
|
|
|
return;
|
|
|
|
END_ERROR;
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2004-12-03 08:22:49 +01:00
|
|
|
// If there was at least one param, close parens
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2004-12-03 08:22:49 +01:00
|
|
|
if (!first_time)
|
|
|
|
{
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(")%s", NEWLINE);
|
2004-12-03 08:22:49 +01:00
|
|
|
}
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2004-12-03 08:22:49 +01:00
|
|
|
} // end for ptype
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("AS %s", NEWLINE);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2003-09-05 13:25:53 +02:00
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
static void list_all_grants()
|
2002-06-29 15:39:11 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* l i s t _ a l l _ g r a n t s
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
2005-04-02 05:51:43 +02:00
|
|
|
* Print the permissions on all user tables, views and procedures.
|
2002-06-29 15:39:11 +02:00
|
|
|
*
|
|
|
|
* Wrapper around list_all_grants2().
|
|
|
|
*
|
|
|
|
**************************************/
|
2004-05-24 19:16:02 +02:00
|
|
|
list_all_grants2(true, isqlGlob.global_Term);
|
2002-06-29 15:39:11 +02:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-09-05 13:25:53 +02:00
|
|
|
|
2003-12-03 09:19:24 +01:00
|
|
|
static processing_state list_all_grants2(bool show_role_list,
|
2003-11-30 07:41:29 +01:00
|
|
|
const SCHAR* terminator)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* l i s t _ a l l _ g r a n t s
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Print the permissions on all user tables.
|
|
|
|
*
|
2005-04-02 05:51:43 +02:00
|
|
|
* Get separate permissions on table/views and then procedures.
|
2001-05-23 15:26:42 +02:00
|
|
|
*
|
|
|
|
**************************************/
|
2005-04-04 10:33:43 +02:00
|
|
|
bool first_role = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
TEXT prev_owner[44];
|
|
|
|
|
2005-04-04 10:33:43 +02:00
|
|
|
// Process GRANT roles
|
2004-05-24 19:16:02 +02:00
|
|
|
if (isqlGlob.major_ods >= ODS_VERSION9 && show_role_list)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
prev_owner[0] = '\0';
|
|
|
|
|
2003-09-29 14:43:14 +02:00
|
|
|
FOR XX IN RDB$ROLES
|
|
|
|
SORTED BY XX.RDB$ROLE_NAME
|
|
|
|
|
2005-04-04 10:33:43 +02:00
|
|
|
if (first_role)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%s/* Grant roles for this database */%s",
|
2003-09-29 14:43:14 +02:00
|
|
|
NEWLINE,
|
|
|
|
NEWLINE);
|
2005-04-04 10:33:43 +02:00
|
|
|
first_role = false;
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
|
2005-04-04 10:33:43 +02:00
|
|
|
// Null terminate name string
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(XX.RDB$ROLE_NAME);
|
|
|
|
fb_utils::exact_name(XX.RDB$OWNER_NAME);
|
2003-09-29 14:43:14 +02:00
|
|
|
|
|
|
|
if (strcmp (prev_owner, XX.RDB$OWNER_NAME) != 0)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%s/* Role: %s, Owner: %s */%s",
|
2003-09-29 14:43:14 +02:00
|
|
|
NEWLINE,
|
|
|
|
XX.RDB$ROLE_NAME,
|
|
|
|
XX.RDB$OWNER_NAME,
|
|
|
|
NEWLINE);
|
|
|
|
strcpy (prev_owner, XX.RDB$OWNER_NAME);
|
|
|
|
}
|
|
|
|
|
2004-05-24 19:16:02 +02:00
|
|
|
if (isqlGlob.db_SQL_dialect > SQL_DIALECT_V6_TRANSITION)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-09-29 14:43:14 +02:00
|
|
|
|
|
|
|
ISQL_copy_SQL_id (XX.RDB$ROLE_NAME, SQL_identifier, DBL_QUOTE);
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("CREATE ROLE %s;%s",
|
2003-09-29 14:43:14 +02:00
|
|
|
SQL_identifier, NEWLINE);
|
|
|
|
}
|
|
|
|
else
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("CREATE ROLE %s;%s",
|
2003-09-29 14:43:14 +02:00
|
|
|
XX.RDB$ROLE_NAME, NEWLINE);
|
|
|
|
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(gds_status);
|
2003-12-03 09:19:24 +01:00
|
|
|
return OBJECT_NOT_FOUND;
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
|
|
|
}
|
|
|
|
|
2005-04-04 10:33:43 +02:00
|
|
|
// This version of cursor gets only sql tables identified by security class
|
|
|
|
// and misses views, getting only null view_source
|
|
|
|
|
|
|
|
char banner[100];
|
|
|
|
sprintf(banner, "%s/* Grant permissions for this database */%s",
|
|
|
|
NEWLINE,
|
|
|
|
NEWLINE);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2005-04-04 10:33:43 +02:00
|
|
|
bool first = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
FOR REL IN RDB$RELATIONS WITH
|
2003-09-29 14:43:14 +02:00
|
|
|
(REL.RDB$SYSTEM_FLAG NE 1 OR REL.RDB$SYSTEM_FLAG MISSING) AND
|
|
|
|
REL.RDB$SECURITY_CLASS STARTING "SQL$"
|
|
|
|
SORTED BY REL.RDB$RELATION_NAME
|
|
|
|
|
2005-04-04 10:33:43 +02:00
|
|
|
// Null terminate name string
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(REL.RDB$RELATION_NAME);
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2003-12-03 09:19:24 +01:00
|
|
|
const processing_state rc =
|
2005-04-04 10:33:43 +02:00
|
|
|
SHOW_grants2(REL.RDB$RELATION_NAME, terminator, obj_relation,
|
|
|
|
first ? banner : 0);
|
2003-09-29 14:43:14 +02:00
|
|
|
if (rc == SKIP) {
|
|
|
|
first = false;
|
|
|
|
}
|
2002-06-29 15:39:11 +02:00
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
END_FOR
|
2003-09-29 14:43:14 +02:00
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(gds_status);
|
2003-12-03 09:19:24 +01:00
|
|
|
return OBJECT_NOT_FOUND;
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
|
|
|
|
2003-09-29 14:43:14 +02:00
|
|
|
if (first)
|
2005-04-04 10:33:43 +02:00
|
|
|
SHOW_grant_roles2(terminator, &first, banner);
|
2003-09-29 14:43:14 +02:00
|
|
|
else
|
2005-04-04 10:33:43 +02:00
|
|
|
SHOW_grant_roles(terminator, 0);
|
2002-06-29 15:39:11 +02:00
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2005-04-04 10:33:43 +02:00
|
|
|
// Again for stored procedures
|
2003-09-29 14:43:14 +02:00
|
|
|
FOR PRC IN RDB$PROCEDURES
|
|
|
|
SORTED BY PRC.RDB$PROCEDURE_NAME
|
|
|
|
|
2005-04-04 10:33:43 +02:00
|
|
|
// Null terminate name string
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(PRC.RDB$PROCEDURE_NAME);
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2003-12-03 09:19:24 +01:00
|
|
|
const processing_state rc =
|
2005-04-04 10:33:43 +02:00
|
|
|
SHOW_grants2(PRC.RDB$PROCEDURE_NAME, terminator, obj_procedure,
|
|
|
|
first ? banner: 0);
|
2003-09-29 14:43:14 +02:00
|
|
|
if (rc == SKIP)
|
|
|
|
first = false;
|
|
|
|
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(gds_status);
|
2003-12-03 09:19:24 +01:00
|
|
|
return OBJECT_NOT_FOUND;
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
|
|
|
|
2005-04-04 10:33:43 +02:00
|
|
|
return first_role && first ? OBJECT_NOT_FOUND : SKIP;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void list_all_procs()
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* l i s t _ a l l _ p r o c s
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Shows text of a stored procedure given a name.
|
|
|
|
* or lists procedures if no argument.
|
|
|
|
* Since procedures may reference each other, we will create all
|
|
|
|
* dummy procedures of the correct name, then alter these to their
|
2003-09-29 14:43:14 +02:00
|
|
|
* correct form.
|
2001-05-23 15:26:42 +02:00
|
|
|
* Add the parameter names when these procedures are created.
|
|
|
|
*
|
|
|
|
* procname -- Name of procedure to investigate
|
|
|
|
*
|
|
|
|
**************************************/
|
2003-09-05 13:25:53 +02:00
|
|
|
bool header = true;
|
2003-11-30 07:41:29 +01:00
|
|
|
static const SCHAR* create_procedure_str1 = "CREATE PROCEDURE %s ";
|
|
|
|
static const SCHAR* create_procedure_str2 = "BEGIN EXIT; END %s%s";
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
|
2003-11-28 07:48:34 +01:00
|
|
|
// First the dummy procedures
|
|
|
|
// create the procedures with their parameters
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
FOR PRC IN RDB$PROCEDURES
|
2003-09-29 14:43:14 +02:00
|
|
|
SORTED BY PRC.RDB$PROCEDURE_NAME
|
|
|
|
if (header)
|
|
|
|
{
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("COMMIT WORK;%s", NEWLINE);
|
|
|
|
isqlGlob.printf("SET AUTODDL OFF;%s", NEWLINE);
|
|
|
|
isqlGlob.printf("SET TERM %s %s%s", Procterm, isqlGlob.global_Term, NEWLINE);
|
|
|
|
isqlGlob.printf("%s/* Stored procedures */%s", NEWLINE, NEWLINE);
|
2003-09-29 14:43:14 +02:00
|
|
|
header = false;
|
|
|
|
}
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(PRC.RDB$PROCEDURE_NAME);
|
2004-05-24 19:16:02 +02:00
|
|
|
if (isqlGlob.db_SQL_dialect > SQL_DIALECT_V6_TRANSITION)
|
2003-09-29 14:43:14 +02:00
|
|
|
{
|
|
|
|
ISQL_copy_SQL_id (PRC.RDB$PROCEDURE_NAME, SQL_identifier, DBL_QUOTE);
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(create_procedure_str1,
|
2003-09-29 14:43:14 +02:00
|
|
|
SQL_identifier);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(create_procedure_str1,
|
2003-09-29 14:43:14 +02:00
|
|
|
PRC.RDB$PROCEDURE_NAME);
|
|
|
|
}
|
|
|
|
|
2004-03-25 08:33:36 +01:00
|
|
|
get_procedure_args (PRC.RDB$PROCEDURE_NAME);
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(create_procedure_str2, Procterm, NEWLINE);
|
2004-03-25 08:33:36 +01:00
|
|
|
|
2003-09-29 14:43:14 +02:00
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
2004-04-23 20:39:04 +02:00
|
|
|
ISQL_errmsg(gds_status);
|
|
|
|
return;
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
|
|
|
|
|
|
|
/* This query gets the procedure name and the source. We then nest a query
|
|
|
|
to retrieve the parameters. Alter is used, because the procedures are already there*/
|
2004-12-04 09:30:43 +01:00
|
|
|
TEXT msg[MSG_LENGTH];
|
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
FOR PRC IN RDB$PROCEDURES
|
2003-09-29 14:43:14 +02:00
|
|
|
SORTED BY PRC.RDB$PROCEDURE_NAME
|
|
|
|
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(PRC.RDB$PROCEDURE_NAME);
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2004-05-24 19:16:02 +02:00
|
|
|
if (isqlGlob.db_SQL_dialect > SQL_DIALECT_V6_TRANSITION)
|
2003-09-29 14:43:14 +02:00
|
|
|
{
|
|
|
|
ISQL_copy_SQL_id (PRC.RDB$PROCEDURE_NAME, SQL_identifier, DBL_QUOTE);
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%sALTER PROCEDURE %s ", NEWLINE,
|
2003-09-29 14:43:14 +02:00
|
|
|
SQL_identifier);
|
|
|
|
}
|
|
|
|
else
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%sALTER PROCEDURE %s ", NEWLINE,
|
2003-09-29 14:43:14 +02:00
|
|
|
PRC.RDB$PROCEDURE_NAME);
|
|
|
|
get_procedure_args (PRC.RDB$PROCEDURE_NAME);
|
|
|
|
|
2003-11-28 07:48:34 +01:00
|
|
|
// Print the procedure body
|
2003-09-29 14:43:14 +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);
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(" %s%s", Procterm, NEWLINE);
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
2005-03-31 09:50:32 +02:00
|
|
|
ISQL_msg_get(GEN_ERR, msg, (TEXT*) (IPTR) isc_sqlcode(gds_status));
|
2005-03-26 06:33:55 +01:00
|
|
|
STDERROUT(msg); // Statement failed, SQLCODE = %d\n\n
|
2003-09-29 14:43:14 +02:00
|
|
|
ISQL_errmsg(gds_status);
|
|
|
|
return;
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
|
|
|
|
2003-11-28 07:48:34 +01:00
|
|
|
// Only reset the terminators is there were procs to print
|
2001-05-23 15:26:42 +02:00
|
|
|
if (!header)
|
|
|
|
{
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("SET TERM %s %s%s", isqlGlob.global_Term, Procterm, NEWLINE);
|
|
|
|
isqlGlob.printf("COMMIT WORK %s%s", isqlGlob.global_Term, NEWLINE);
|
|
|
|
isqlGlob.printf("SET AUTODDL ON;%s", NEWLINE);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-05-19 10:03:10 +02:00
|
|
|
static void list_all_tables(LegacyTables flag,
|
2003-09-05 13:25:53 +02:00
|
|
|
SSHORT default_char_set_id)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* l i s t _ a l l _ t a b l e s
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Extract the names of all user tables from
|
|
|
|
* rdb$relations. Filter SQL tables by
|
|
|
|
* security class after we fetch them
|
|
|
|
* Parameters: flag -- 0, get all tables
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
|
2003-09-29 14:43:14 +02:00
|
|
|
/* This version of cursor gets only sql tables identified by security class
|
2001-05-23 15:26:42 +02:00
|
|
|
and misses views, getting only null view_source */
|
|
|
|
|
|
|
|
FOR REL IN RDB$RELATIONS WITH
|
2003-09-29 14:43:14 +02:00
|
|
|
(REL.RDB$SYSTEM_FLAG NE 1 OR REL.RDB$SYSTEM_FLAG MISSING) AND
|
|
|
|
REL.RDB$VIEW_BLR MISSING
|
|
|
|
SORTED BY REL.RDB$RELATION_NAME
|
|
|
|
|
2003-11-28 07:48:34 +01:00
|
|
|
// If this is not an SQL table and we aren't doing ALL objects
|
2003-09-29 14:43:14 +02:00
|
|
|
if ((REL.RDB$FLAGS.NULL || !(REL.RDB$FLAGS & REL_sql)) && (flag != ALL_objects) )
|
|
|
|
continue;
|
2003-11-28 07:48:34 +01:00
|
|
|
// Null terminate name string
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(REL.RDB$RELATION_NAME);
|
2003-09-29 14:43:14 +02:00
|
|
|
|
|
|
|
if (flag || !strncmp (REL.RDB$SECURITY_CLASS, "SQL$", 4))
|
2004-11-24 09:58:11 +01:00
|
|
|
EXTRACT_list_table (REL.RDB$RELATION_NAME, NULL, false, default_char_set_id);
|
2003-09-29 14:43:14 +02:00
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(gds_status);
|
|
|
|
ROLLBACK;
|
|
|
|
return;
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void list_all_triggers()
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* l i s t _ a l l _ t r i g g e r s
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Lists triggers in general on non-system
|
|
|
|
* tables with sql source only.
|
|
|
|
*
|
|
|
|
**************************************/
|
2003-09-05 13:25:53 +02:00
|
|
|
bool header = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-09-29 14:43:14 +02:00
|
|
|
/* Query gets the trigger info for non-system triggers with
|
2001-05-23 15:26:42 +02:00
|
|
|
source that are not part of an SQL constraint */
|
|
|
|
|
|
|
|
FOR TRG IN RDB$TRIGGERS CROSS REL IN RDB$RELATIONS OVER RDB$RELATION_NAME
|
2003-09-29 14:43:14 +02:00
|
|
|
WITH (REL.RDB$SYSTEM_FLAG NE 1 OR REL.RDB$SYSTEM_FLAG MISSING) 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_TYPE,
|
|
|
|
TRG.RDB$TRIGGER_SEQUENCE, TRG.RDB$TRIGGER_NAME
|
|
|
|
|
|
|
|
if (header)
|
|
|
|
{
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("SET TERM %s %s%s", Procterm, isqlGlob.global_Term, NEWLINE);
|
|
|
|
isqlGlob.printf(
|
2003-09-29 14:43:14 +02:00
|
|
|
"%s/* Triggers only will work for SQL triggers */%s",
|
|
|
|
NEWLINE,
|
|
|
|
NEWLINE);
|
|
|
|
header = 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);
|
2003-09-29 14:43:14 +02:00
|
|
|
|
|
|
|
if (TRG.RDB$TRIGGER_INACTIVE.NULL)
|
|
|
|
TRG.RDB$TRIGGER_INACTIVE = 0;
|
|
|
|
|
2003-11-28 07:48:34 +01:00
|
|
|
// If trigger is not SQL put it in comments
|
2003-09-29 14:43:14 +02:00
|
|
|
if (TRG.RDB$FLAGS != TRG_sql)
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf("/* ");
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2004-05-24 19:16:02 +02:00
|
|
|
if (isqlGlob.db_SQL_dialect > SQL_DIALECT_V6_TRANSITION)
|
2003-09-29 14:43:14 +02:00
|
|
|
{
|
|
|
|
ISQL_copy_SQL_id (TRG.RDB$TRIGGER_NAME, SQL_identifier, DBL_QUOTE);
|
|
|
|
ISQL_copy_SQL_id (TRG.RDB$RELATION_NAME, SQL_identifier2, DBL_QUOTE);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
strcpy (SQL_identifier, TRG.RDB$TRIGGER_NAME);
|
|
|
|
strcpy (SQL_identifier2, TRG.RDB$RELATION_NAME);
|
|
|
|
}
|
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("CREATE TRIGGER %s FOR %s %s%s %s POSITION %d %s",
|
2003-09-29 14:43:14 +02:00
|
|
|
SQL_identifier, SQL_identifier2, NEWLINE,
|
|
|
|
(TRG.RDB$TRIGGER_INACTIVE ? "INACTIVE" : "ACTIVE"),
|
|
|
|
trigger_action (TRG.RDB$TRIGGER_TYPE), TRG.RDB$TRIGGER_SEQUENCE,
|
|
|
|
NEWLINE);
|
|
|
|
|
|
|
|
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);
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(" %s%s", Procterm, NEWLINE);
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf(NEWLINE);
|
2003-09-29 14:43:14 +02:00
|
|
|
|
|
|
|
if (TRG.RDB$FLAGS != TRG_sql)
|
|
|
|
{
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("*/%s", NEWLINE);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
END_FOR
|
2003-09-29 14:43:14 +02:00
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(gds_status);
|
|
|
|
return;
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
|
|
|
|
|
|
|
if (!header)
|
|
|
|
{
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("COMMIT WORK %s%s", Procterm, NEWLINE);
|
|
|
|
isqlGlob.printf("SET TERM %s %s%s", isqlGlob.global_Term, Procterm, NEWLINE);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
static void list_check()
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* l i s t _ c h e c k
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* List check constraints for all objects to allow forward references
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
|
2003-11-28 07:48:34 +01:00
|
|
|
// Query gets the check clauses for triggers stored for check constraints
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
FOR TRG IN RDB$TRIGGERS CROSS
|
2003-09-29 14:43:14 +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
|
|
|
|
(ANY RELC IN RDB$RELATION_CONSTRAINTS WITH
|
|
|
|
CHK.RDB$CONSTRAINT_NAME EQ RELC.RDB$CONSTRAINT_NAME)
|
|
|
|
REDUCED TO CHK.RDB$CONSTRAINT_NAME
|
|
|
|
SORTED BY CHK.RDB$CONSTRAINT_NAME
|
|
|
|
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(TRG.RDB$RELATION_NAME);
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf(NEWLINE);
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2004-05-24 19:16:02 +02:00
|
|
|
if (isqlGlob.db_SQL_dialect > SQL_DIALECT_V6_TRANSITION)
|
2003-09-29 14:43:14 +02:00
|
|
|
{
|
|
|
|
ISQL_copy_SQL_id (TRG.RDB$RELATION_NAME, SQL_identifier, DBL_QUOTE);
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("ALTER TABLE %s ADD %s%s",
|
2003-09-29 14:43:14 +02:00
|
|
|
SQL_identifier, NEWLINE, TAB_AS_SPACES);
|
|
|
|
}
|
|
|
|
else
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("ALTER TABLE %s ADD %s%s",
|
2003-09-29 14:43:14 +02:00
|
|
|
TRG.RDB$RELATION_NAME, NEWLINE, TAB_AS_SPACES);
|
|
|
|
|
2003-11-28 07:48:34 +01:00
|
|
|
// If the name of the constraint is not INTEG..., print it
|
2003-09-29 14:43:14 +02:00
|
|
|
if (strncmp(CHK.RDB$CONSTRAINT_NAME, "INTEG", 5))
|
|
|
|
{
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(CHK.RDB$CONSTRAINT_NAME);
|
2004-05-24 19:16:02 +02:00
|
|
|
if (isqlGlob.db_SQL_dialect > SQL_DIALECT_V6_TRANSITION)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-09-29 14:43:14 +02:00
|
|
|
ISQL_copy_SQL_id (CHK.RDB$CONSTRAINT_NAME, SQL_identifier,
|
|
|
|
DBL_QUOTE);
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("CONSTRAINT %s ", SQL_identifier);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
else
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("CONSTRAINT %s ", CHK.RDB$CONSTRAINT_NAME);
|
2003-09-29 14:43:14 +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);
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%s%s", isqlGlob.global_Term, NEWLINE);
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
END_FOR
|
2003-09-29 14:43:14 +02:00
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(gds_status);
|
|
|
|
return;
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-04-21 02:18:48 +02:00
|
|
|
#ifdef NOT_USED_OR_REPLACED
|
2003-11-30 07:41:29 +01:00
|
|
|
static void print_set(bool* set_used)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* p r i n t _ s e t
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
2005-05-26 08:45:25 +02:00
|
|
|
* print the word "SET"
|
|
|
|
* in the first line of the ALTER DATABASE
|
2001-05-23 15:26:42 +02:00
|
|
|
* settings options. Also, add trailing
|
|
|
|
* comma for end of prior line if needed.
|
2003-09-29 14:43:14 +02:00
|
|
|
*
|
2001-05-23 15:26:42 +02:00
|
|
|
* uses Print_buffer, a global
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
if (!*set_used)
|
|
|
|
{
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(" SET ");
|
2003-09-05 13:25:53 +02:00
|
|
|
*set_used = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(", %s ", NEWLINE);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
}
|
2004-04-21 02:18:48 +02:00
|
|
|
#endif
|
2003-09-05 13:25:53 +02:00
|
|
|
|
2005-05-26 08:45:25 +02:00
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
static void list_create_db()
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* l i s t _ c r e a t e _ d b
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
2003-09-29 14:43:14 +02:00
|
|
|
* Print the create database command if requested. At least put
|
2001-05-23 15:26:42 +02:00
|
|
|
* the page size in a comment with the extracted db name
|
|
|
|
*
|
|
|
|
**************************************/
|
2003-02-13 10:42:18 +01:00
|
|
|
static const SCHAR page_items[] = {
|
2001-05-23 15:26:42 +02:00
|
|
|
isc_info_page_size,
|
|
|
|
isc_info_end
|
|
|
|
};
|
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
// Comment out the create database if no db param was specified
|
2003-09-05 13:25:53 +02:00
|
|
|
bool nodb = false;
|
2004-05-24 19:16:02 +02:00
|
|
|
if (!*isqlGlob.global_Target_db)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf("/* ");
|
2004-05-24 19:16:02 +02:00
|
|
|
strcpy(isqlGlob.global_Target_db, isqlGlob.global_Db_name);
|
2003-09-05 13:25:53 +02:00
|
|
|
nodb = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("CREATE DATABASE '%s'", isqlGlob.global_Target_db);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-11-28 07:48:34 +01:00
|
|
|
// Get the page size from db_info call
|
2003-11-30 07:41:29 +01:00
|
|
|
SCHAR info_buf[20];
|
2004-09-22 03:55:37 +02:00
|
|
|
// CVC: Finally I got the idea: translate is associated with WISQL that
|
|
|
|
// no longer exists. Localizing the messages means also not printing
|
|
|
|
// any CRLF and therefore the output looks ugly.
|
|
|
|
const bool translate = true;
|
2003-11-30 07:41:29 +01:00
|
|
|
if (!SHOW_dbb_parameters(DB, info_buf, page_items, sizeof(page_items),
|
|
|
|
translate))
|
|
|
|
{
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(" %s", info_buf);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
FOR DBP IN RDB$DATABASE
|
|
|
|
WITH DBP.RDB$CHARACTER_SET_NAME NOT MISSING
|
|
|
|
AND DBP.RDB$CHARACTER_SET_NAME != " ";
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(" DEFAULT CHARACTER SET %s",
|
|
|
|
fb_utils::exact_name(DBP.RDB$CHARACTER_SET_NAME));
|
2001-05-23 15:26:42 +02:00
|
|
|
END_FOR
|
2003-09-29 14:43:14 +02:00
|
|
|
ON_ERROR
|
2004-04-23 20:39:04 +02:00
|
|
|
ISQL_errmsg(gds_status);
|
|
|
|
return;
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
|
|
|
|
|
|
|
if (nodb)
|
|
|
|
{
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(" */%s", NEWLINE);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%s%s", isqlGlob.global_Term, NEWLINE);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2003-11-28 07:48:34 +01:00
|
|
|
// List secondary files and shadows as alter db and create shadow in comment
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
bool first = true;
|
|
|
|
|
2003-09-29 14:43:14 +02:00
|
|
|
FOR FIL IN RDB$FILES
|
|
|
|
SORTED BY FIL.RDB$SHADOW_NUMBER, FIL.RDB$FILE_SEQUENCE
|
|
|
|
|
|
|
|
if (first)
|
|
|
|
{
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%s/* Add secondary files in comments %s",
|
2003-09-29 14:43:14 +02:00
|
|
|
NEWLINE,
|
|
|
|
NEWLINE);
|
|
|
|
}
|
|
|
|
|
|
|
|
first = false;
|
2003-11-28 07:48:34 +01:00
|
|
|
// reset nulls to zero
|
2003-09-29 14:43:14 +02:00
|
|
|
|
|
|
|
if (FIL.RDB$FILE_FLAGS.NULL)
|
|
|
|
FIL.RDB$FILE_FLAGS = 0;
|
|
|
|
if (FIL.RDB$FILE_LENGTH.NULL)
|
|
|
|
FIL.RDB$FILE_LENGTH = 0;
|
|
|
|
if (FIL.RDB$FILE_SEQUENCE.NULL)
|
|
|
|
FIL.RDB$FILE_SEQUENCE = 0;
|
|
|
|
if (FIL.RDB$FILE_START.NULL)
|
|
|
|
FIL.RDB$FILE_START = 0;
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(FIL.RDB$FILE_NAME);
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2003-11-28 07:48:34 +01:00
|
|
|
// Pure secondary files
|
2003-09-29 14:43:14 +02:00
|
|
|
if (FIL.RDB$FILE_FLAGS == 0)
|
|
|
|
{
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%sALTER DATABASE ADD FILE '%s'",
|
2003-09-29 14:43:14 +02:00
|
|
|
NEWLINE,
|
|
|
|
FIL.RDB$FILE_NAME);
|
|
|
|
if (FIL.RDB$FILE_START)
|
|
|
|
{
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(" STARTING %ld", FIL.RDB$FILE_START);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
if (FIL.RDB$FILE_LENGTH)
|
|
|
|
{
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(" LENGTH %ld", FIL.RDB$FILE_LENGTH);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf(NEWLINE);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (FIL.RDB$FILE_FLAGS & FILE_shadow)
|
|
|
|
{
|
|
|
|
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-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%sCREATE SHADOW %d '%s' ",
|
2003-09-29 14:43:14 +02:00
|
|
|
NEWLINE,
|
|
|
|
FIL.RDB$SHADOW_NUMBER,
|
|
|
|
FIL.RDB$FILE_NAME);
|
|
|
|
if (FIL.RDB$FILE_FLAGS & FILE_inactive)
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf("INACTIVE ");
|
2003-09-29 14:43:14 +02:00
|
|
|
if (FIL.RDB$FILE_FLAGS & FILE_manual)
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf("MANUAL ");
|
2003-09-29 14:43:14 +02:00
|
|
|
else
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf("AUTO ");
|
2003-09-29 14:43:14 +02:00
|
|
|
if (FIL.RDB$FILE_FLAGS & FILE_conditional)
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf("CONDITIONAL ");
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
if (FIL.RDB$FILE_LENGTH)
|
|
|
|
{
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("LENGTH %ld ", FIL.RDB$FILE_LENGTH);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
if (FIL.RDB$FILE_START)
|
|
|
|
{
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("STARTING %ld ", FIL.RDB$FILE_START);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf(NEWLINE);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
END_FOR
|
2003-09-29 14:43:14 +02:00
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(gds_status);
|
|
|
|
return;
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
|
|
|
|
|
|
|
if (!first)
|
|
|
|
{
|
|
|
|
if (nodb)
|
|
|
|
{
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%s */%s", NEWLINE, NEWLINE);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%s%s%s", isqlGlob.global_Term, NEWLINE, NEWLINE);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
static void list_domain_table(const SCHAR* table_name,
|
2003-09-05 13:25:53 +02:00
|
|
|
SSHORT default_char_set_id)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
2003-09-29 14:43:14 +02:00
|
|
|
* l i s t _ d o m a i n _ t a b l e
|
2001-05-23 15:26:42 +02:00
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* List domains as identified by fields with any constraints on them
|
|
|
|
* for the named table
|
|
|
|
*
|
2003-09-29 14:43:14 +02:00
|
|
|
* Parameters: table_name == only extract domains for this table
|
2001-05-23 15:26:42 +02:00
|
|
|
* default_char_set_id -- character set def to supress
|
|
|
|
*
|
|
|
|
**************************************/
|
2003-09-05 13:25:53 +02:00
|
|
|
bool first = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
SCHAR char_sets[86];
|
|
|
|
|
|
|
|
FOR FLD IN RDB$FIELDS CROSS
|
2003-09-29 14:43:14 +02:00
|
|
|
RFR IN RDB$RELATION_FIELDS WITH
|
|
|
|
RFR.RDB$FIELD_SOURCE EQ FLD.RDB$FIELD_NAME AND
|
|
|
|
RFR.RDB$RELATION_NAME EQ table_name
|
|
|
|
SORTED BY FLD.RDB$FIELD_NAME
|
|
|
|
|
2003-11-28 07:48:34 +01:00
|
|
|
// Skip over artifical domains
|
2003-09-29 14:43:14 +02:00
|
|
|
if (strncmp (FLD.RDB$FIELD_NAME, "RDB$", 4) == 0 &&
|
|
|
|
isdigit (FLD.RDB$FIELD_NAME[4]) &&
|
|
|
|
FLD.RDB$SYSTEM_FLAG != 1)
|
2003-11-28 07:48:34 +01:00
|
|
|
{
|
2003-09-29 14:43:14 +02:00
|
|
|
continue;
|
2003-11-28 07:48:34 +01:00
|
|
|
}
|
2003-09-29 14:43:14 +02:00
|
|
|
|
|
|
|
if (first)
|
|
|
|
{
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("/* Domain definitions */%s", NEWLINE);
|
2003-09-29 14:43:14 +02:00
|
|
|
first = false;
|
|
|
|
}
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(FLD.RDB$FIELD_NAME);
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("CREATE DOMAIN %s AS ", FLD.RDB$FIELD_NAME);
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2004-12-04 09:30:43 +01:00
|
|
|
for (int i = 0; Column_types[i].type; i++)
|
2003-11-28 07:48:34 +01:00
|
|
|
if (FLD.RDB$FIELD_TYPE == Column_types[i].type)
|
2003-09-29 14:43:14 +02:00
|
|
|
{
|
|
|
|
bool precision_known = false;
|
|
|
|
|
2004-05-24 19:16:02 +02:00
|
|
|
if (isqlGlob.major_ods >= ODS_VERSION10)
|
2003-09-29 14:43:14 +02:00
|
|
|
{
|
2003-11-28 07:48:34 +01:00
|
|
|
// Handle Integral subtypes NUMERIC and DECIMAL
|
2003-09-29 14:43:14 +02:00
|
|
|
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-09-29 14:43:14 +02:00
|
|
|
{
|
|
|
|
/* We are ODS >= 10 and could be any Dialect */
|
|
|
|
|
|
|
|
FOR FLD1 IN RDB$FIELDS WITH
|
|
|
|
FLD1.RDB$FIELD_NAME EQ FLD.RDB$FIELD_NAME
|
|
|
|
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)",
|
2003-11-28 07:48:34 +01:00
|
|
|
Integral_subtypes[FLD1.RDB$FIELD_SUB_TYPE],
|
2003-09-29 14:43:14 +02:00
|
|
|
FLD1.RDB$FIELD_PRECISION,
|
|
|
|
-FLD1.RDB$FIELD_SCALE);
|
|
|
|
precision_known = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg (isc_status);
|
|
|
|
return;
|
|
|
|
END_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!precision_known)
|
|
|
|
{
|
2003-11-28 07:48:34 +01:00
|
|
|
// Take a stab at numerics and decimals
|
2003-09-29 14:43:14 +02:00
|
|
|
if ((FLD.RDB$FIELD_TYPE == SMALLINT) && (FLD.RDB$FIELD_SCALE < 0))
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-09-29 14:43:14 +02:00
|
|
|
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) &&
|
|
|
|
(FLD.RDB$FIELD_SCALE < 0))
|
|
|
|
{
|
|
|
|
sprintf (Print_buffer, "NUMERIC(15, %d)", -FLD.RDB$FIELD_SCALE);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2003-11-28 07:48:34 +01:00
|
|
|
sprintf (Print_buffer, "%s", Column_types[i].type_name);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
}
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.prints(Print_buffer);
|
2003-09-29 14:43:14 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (FLD.RDB$FIELD_TYPE == BLOB)
|
|
|
|
{
|
2004-12-04 09:30:43 +01:00
|
|
|
const int subtype = FLD.RDB$FIELD_SUB_TYPE;
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf(" SUB_TYPE ");
|
2004-05-24 19:16:02 +02:00
|
|
|
if ((subtype > 0) && (subtype <= MAX_BLOBSUBTYPES))
|
2003-09-29 14:43:14 +02:00
|
|
|
{
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.prints(Sub_types[subtype]);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
else
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf("%d", subtype);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf(" SEGMENT SIZE %u", (USHORT) FLD.RDB$SEGMENT_LENGTH);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
|
2004-04-24 16:38:27 +02:00
|
|
|
else if ((FLD.RDB$FIELD_TYPE == T_CHAR) || (FLD.RDB$FIELD_TYPE == VARCHAR))
|
2003-09-29 14:43:14 +02:00
|
|
|
{
|
2003-11-28 07:48:34 +01:00
|
|
|
// Length for chars
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf("(%d)", ISQL_get_field_length(FLD.RDB$FIELD_NAME));
|
2004-11-07 11:38:13 +01:00
|
|
|
}
|
2003-09-29 14:43:14 +02:00
|
|
|
|
|
|
|
/* Bug 8261: do not show the collation information just yet! If you
|
|
|
|
do, then the domain syntax when printed is not correct */
|
|
|
|
|
|
|
|
/* since the character set is part of the field type, display that
|
|
|
|
information now. */
|
|
|
|
if (!FLD.RDB$CHARACTER_SET_ID.NULL)
|
|
|
|
{
|
|
|
|
|
|
|
|
char_sets[0] = 0;
|
|
|
|
if ((FLD.RDB$CHARACTER_SET_ID != default_char_set_id) ||
|
|
|
|
(!FLD.RDB$COLLATION_ID.NULL && FLD.RDB$COLLATION_ID != 0))
|
|
|
|
ISQL_get_character_sets (FLD.RDB$CHARACTER_SET_ID, 0, false, char_sets);
|
|
|
|
if (char_sets[0])
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.prints(char_sets);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!FLD.RDB$DIMENSIONS.NULL)
|
|
|
|
ISQL_array_dimensions (FLD.RDB$FIELD_NAME);
|
|
|
|
|
|
|
|
if (!FLD.RDB$DEFAULT_SOURCE.NULL)
|
|
|
|
{
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%s%s ", NEWLINE, TAB_AS_SPACES);
|
2004-05-24 19:16:02 +02:00
|
|
|
SHOW_print_metadata_text_blob (isqlGlob.Out, &FLD.RDB$DEFAULT_SOURCE);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
if (!FLD.RDB$VALIDATION_SOURCE.NULL)
|
|
|
|
{
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%s%s ", NEWLINE, TAB_AS_SPACES);
|
2004-05-24 19:16:02 +02:00
|
|
|
ISQL_print_validation (isqlGlob.Out, &FLD.RDB$VALIDATION_SOURCE, false, gds_trans);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
if (FLD.RDB$NULL_FLAG == 1)
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf(" NOT NULL");
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2003-11-28 07:48:34 +01:00
|
|
|
// Bug 8261: Now show the collation order information
|
2003-09-29 14:43:14 +02:00
|
|
|
/* Show the collation order if one has been specified. If the collation
|
|
|
|
order is the default for the character set being used, then no collation
|
|
|
|
order will be shown ( because it isn't needed ).
|
|
|
|
|
2004-04-23 20:39:04 +02:00
|
|
|
If the collation id is 0, then the default for the character set is
|
|
|
|
being used so there is no need to retrieve the collation information.*/
|
2003-09-29 14:43:14 +02:00
|
|
|
|
|
|
|
if (!FLD.RDB$COLLATION_ID.NULL && FLD.RDB$COLLATION_ID != 0)
|
|
|
|
{
|
|
|
|
char_sets[0] = 0;
|
|
|
|
ISQL_get_character_sets (FLD.RDB$CHARACTER_SET_ID, FLD.RDB$COLLATION_ID,
|
2003-09-05 13:25:53 +02:00
|
|
|
true, char_sets);
|
2003-09-29 14:43:14 +02:00
|
|
|
if (char_sets[0])
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.prints(char_sets);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%s%s", isqlGlob.global_Term, NEWLINE);
|
2003-09-29 14:43:14 +02:00
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(gds_status);
|
|
|
|
return;
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-09-05 13:25:53 +02:00
|
|
|
static void list_domains(SSHORT default_char_set_id)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* l i s t _ d o m a i n s
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
2003-09-29 14:43:14 +02:00
|
|
|
* List domains
|
2001-05-23 15:26:42 +02:00
|
|
|
*
|
2003-09-29 14:43:14 +02:00
|
|
|
* Parameters:
|
2001-05-23 15:26:42 +02:00
|
|
|
* default_char_set_id -- character set def to supress
|
|
|
|
*
|
|
|
|
**************************************/
|
2003-09-05 13:25:53 +02:00
|
|
|
bool first = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
SCHAR char_sets[86];
|
|
|
|
|
|
|
|
FOR FLD IN RDB$FIELDS WITH
|
2003-09-29 14:43:14 +02:00
|
|
|
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
|
|
|
|
|
|
|
|
if (first)
|
|
|
|
{
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("/* Domain definitions */%s", NEWLINE);
|
2003-09-29 14:43:14 +02:00
|
|
|
first = false;
|
|
|
|
}
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(FLD.RDB$FIELD_NAME);
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2004-05-24 19:16:02 +02:00
|
|
|
if (isqlGlob.db_SQL_dialect > SQL_DIALECT_V6_TRANSITION)
|
2003-09-29 14:43:14 +02:00
|
|
|
{
|
|
|
|
ISQL_copy_SQL_id(FLD.RDB$FIELD_NAME, SQL_identifier, DBL_QUOTE);
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("CREATE DOMAIN %s AS ", SQL_identifier);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
else
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("CREATE DOMAIN %s AS ", FLD.RDB$FIELD_NAME);
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
// Get domain type
|
2004-12-04 09:30:43 +01:00
|
|
|
for (int i = 0; Column_types[i].type; i++)
|
2003-11-28 07:48:34 +01:00
|
|
|
if (FLD.RDB$FIELD_TYPE == Column_types[i].type)
|
2003-09-29 14:43:14 +02:00
|
|
|
{
|
|
|
|
bool precision_known = false;
|
|
|
|
|
2004-05-24 19:16:02 +02:00
|
|
|
if (isqlGlob.major_ods >= ODS_VERSION10)
|
2003-09-29 14:43:14 +02:00
|
|
|
{
|
2003-11-28 07:48:34 +01:00
|
|
|
// Handle Integral subtypes NUMERIC and DECIMAL
|
2003-09-29 14:43:14 +02:00
|
|
|
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-09-29 14:43:14 +02:00
|
|
|
{
|
|
|
|
/* We are ODS >= 10 and could be any Dialect */
|
|
|
|
FOR FLD1 IN RDB$FIELDS WITH
|
|
|
|
FLD1.RDB$FIELD_NAME EQ FLD.RDB$FIELD_NAME
|
|
|
|
|
|
|
|
if (!FLD1.RDB$FIELD_PRECISION.NULL)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-09-29 14:43:14 +02:00
|
|
|
/* 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)",
|
2003-11-28 07:48:34 +01:00
|
|
|
Integral_subtypes[FLD1.RDB$FIELD_SUB_TYPE],
|
2003-09-29 14:43:14 +02:00
|
|
|
FLD1.RDB$FIELD_PRECISION,
|
|
|
|
-FLD1.RDB$FIELD_SCALE);
|
|
|
|
precision_known = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg (isc_status);
|
|
|
|
return;
|
|
|
|
END_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!precision_known)
|
|
|
|
{
|
2003-11-28 07:48:34 +01:00
|
|
|
// Take a stab at numerics and decimals
|
2003-09-29 14:43:14 +02:00
|
|
|
if ((FLD.RDB$FIELD_TYPE == SMALLINT) && (FLD.RDB$FIELD_SCALE < 0))
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-09-29 14:43:14 +02:00
|
|
|
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) &&
|
|
|
|
(FLD.RDB$FIELD_SCALE < 0))
|
|
|
|
{
|
|
|
|
sprintf (Print_buffer, "NUMERIC(15, %d)", -FLD.RDB$FIELD_SCALE);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2003-11-28 07:48:34 +01:00
|
|
|
sprintf (Print_buffer, "%s", Column_types[i].type_name);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
}
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.prints(Print_buffer);
|
2003-09-29 14:43:14 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (FLD.RDB$FIELD_TYPE == BLOB)
|
|
|
|
{
|
2004-12-04 09:30:43 +01:00
|
|
|
const int subtype = FLD.RDB$FIELD_SUB_TYPE;
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf(" SUB_TYPE ");
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2004-05-24 19:16:02 +02:00
|
|
|
if ((subtype > 0) && (subtype <= MAX_BLOBSUBTYPES))
|
2003-09-29 14:43:14 +02:00
|
|
|
{
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.prints(Sub_types[subtype]);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%d", subtype);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(" SEGMENT SIZE %u", (USHORT) FLD.RDB$SEGMENT_LENGTH);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
|
2004-04-24 16:38:27 +02:00
|
|
|
else if ((FLD.RDB$FIELD_TYPE == T_CHAR) || (FLD.RDB$FIELD_TYPE == VARCHAR))
|
2003-09-29 14:43:14 +02:00
|
|
|
{
|
2003-11-28 07:48:34 +01:00
|
|
|
// Length for chars
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("(%d)", ISQL_get_field_length(FLD.RDB$FIELD_NAME));
|
2004-11-07 11:38:13 +01:00
|
|
|
}
|
2003-09-29 14:43:14 +02:00
|
|
|
|
|
|
|
/* Bug 8261: do not show the collation information just yet! If you
|
|
|
|
do, then the domain syntax when printed is not correct */
|
|
|
|
|
|
|
|
/* since the character set is part of the field type, display that
|
|
|
|
information now. */
|
|
|
|
if (!FLD.RDB$CHARACTER_SET_ID.NULL)
|
|
|
|
{
|
|
|
|
char_sets[0] = 0;
|
|
|
|
if ((FLD.RDB$CHARACTER_SET_ID != default_char_set_id) ||
|
|
|
|
(!FLD.RDB$COLLATION_ID.NULL && FLD.RDB$COLLATION_ID != 0))
|
|
|
|
{
|
|
|
|
ISQL_get_character_sets (FLD.RDB$CHARACTER_SET_ID, 0, false, char_sets);
|
|
|
|
}
|
|
|
|
if (char_sets[0])
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.prints(char_sets);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!FLD.RDB$DIMENSIONS.NULL)
|
|
|
|
ISQL_array_dimensions (FLD.RDB$FIELD_NAME);
|
|
|
|
|
|
|
|
if (!FLD.RDB$DEFAULT_SOURCE.NULL)
|
|
|
|
{
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%s%s ", NEWLINE, TAB_AS_SPACES);
|
2004-05-24 19:16:02 +02:00
|
|
|
SHOW_print_metadata_text_blob (isqlGlob.Out, &FLD.RDB$DEFAULT_SOURCE);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
if (!FLD.RDB$VALIDATION_SOURCE.NULL)
|
|
|
|
{
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%s%s ", NEWLINE, TAB_AS_SPACES);
|
2004-05-24 19:16:02 +02:00
|
|
|
ISQL_print_validation (isqlGlob.Out, &FLD.RDB$VALIDATION_SOURCE, false, gds_trans);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
if (FLD.RDB$NULL_FLAG == 1)
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf(" NOT NULL");
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2003-11-28 07:48:34 +01:00
|
|
|
// Bug 8261: Now show the collation order information
|
2003-09-29 14:43:14 +02:00
|
|
|
/* Show the collation order if one has been specified. If the collation
|
|
|
|
order is the default for the character set being used, then no collation
|
|
|
|
order will be shown ( because it isn't needed
|
|
|
|
|
|
|
|
If the collation id is 0, then the default for the character set is
|
|
|
|
being used so there is no need to retrieve the collation information.*/
|
|
|
|
|
|
|
|
if (!FLD.RDB$COLLATION_ID.NULL && FLD.RDB$COLLATION_ID != 0)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-09-29 14:43:14 +02:00
|
|
|
char_sets[0] = 0;
|
|
|
|
ISQL_get_character_sets (FLD.RDB$CHARACTER_SET_ID, FLD.RDB$COLLATION_ID,
|
2003-09-05 13:25:53 +02:00
|
|
|
true, char_sets);
|
2003-09-29 14:43:14 +02:00
|
|
|
if (char_sets[0])
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.prints(char_sets);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%s%s", isqlGlob.global_Term, NEWLINE);
|
2003-09-29 14:43:14 +02:00
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(gds_status);
|
|
|
|
return;
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
static void list_exception()
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* l i s t _ e x c e p t i o n
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* List all exceptions defined in the database
|
|
|
|
*
|
|
|
|
* Parameters: none
|
|
|
|
*
|
|
|
|
**************************************/
|
2003-09-05 13:25:53 +02:00
|
|
|
bool first = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
FOR EXC IN RDB$EXCEPTIONS
|
2003-09-29 14:43:14 +02:00
|
|
|
SORTED BY EXC.RDB$EXCEPTION_NAME
|
|
|
|
|
|
|
|
if (first)
|
|
|
|
{
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%s/* Exceptions */%s", NEWLINE, NEWLINE);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
first = false;
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(EXC.RDB$EXCEPTION_NAME);
|
2003-09-29 14:43:14 +02:00
|
|
|
|
|
|
|
ISQL_copy_SQL_id (EXC.RDB$MESSAGE, SQL_identifier2, SINGLE_QUOTE);
|
2004-05-24 19:16:02 +02:00
|
|
|
if (isqlGlob.db_SQL_dialect > SQL_DIALECT_V6_TRANSITION)
|
2003-09-29 14:43:14 +02:00
|
|
|
{
|
|
|
|
ISQL_copy_SQL_id (EXC.RDB$EXCEPTION_NAME, SQL_identifier, DBL_QUOTE);
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("CREATE EXCEPTION %s %s%s%s",
|
2004-05-24 19:16:02 +02:00
|
|
|
SQL_identifier, SQL_identifier2, isqlGlob.global_Term, NEWLINE);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
else
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("CREATE EXCEPTION %s %s%s%s",
|
2004-05-24 19:16:02 +02:00
|
|
|
EXC.RDB$EXCEPTION_NAME, SQL_identifier2, isqlGlob.global_Term, NEWLINE);
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
END_FOR
|
2003-09-29 14:43:14 +02:00
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(gds_status);
|
|
|
|
return;
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
static void list_filters()
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* l i s t _ f i l t e r s
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* List all blob filters
|
|
|
|
*
|
|
|
|
* Parameters: none
|
2003-09-29 14:43:14 +02:00
|
|
|
* Results in
|
2001-05-23 15:26:42 +02:00
|
|
|
* DECLARE FILTER <fname> INPUT_TYPE <blob_sub_type> OUTPUT_TYPE <blob_subtype>
|
|
|
|
* ENTRY_POINT <string> MODULE_NAME <string>
|
|
|
|
**************************************/
|
2003-09-05 13:25:53 +02:00
|
|
|
bool first = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-09-29 14:43:14 +02:00
|
|
|
FOR FIL IN RDB$FILTERS
|
|
|
|
SORTED BY FIL.RDB$FUNCTION_NAME
|
|
|
|
|
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-09-29 14:43:14 +02:00
|
|
|
|
|
|
|
if (first)
|
|
|
|
{
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%s/* BLOB Filter declarations */%s",
|
2003-09-29 14:43:14 +02:00
|
|
|
NEWLINE,
|
|
|
|
NEWLINE);
|
|
|
|
}
|
|
|
|
first = false;
|
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("DECLARE FILTER %s INPUT_TYPE %d OUTPUT_TYPE %d%s%sENTRY_POINT '%s' MODULE_NAME '%s'%s%s%s",
|
2003-09-29 14:43:14 +02:00
|
|
|
FIL.RDB$FUNCTION_NAME, FIL.RDB$INPUT_SUB_TYPE, FIL.RDB$OUTPUT_SUB_TYPE,
|
2004-05-24 19:16:02 +02:00
|
|
|
NEWLINE, TAB_AS_SPACES, FIL.RDB$ENTRYPOINT, FIL.RDB$MODULE_NAME, isqlGlob.global_Term, NEWLINE,
|
2003-09-29 14:43:14 +02:00
|
|
|
NEWLINE);
|
|
|
|
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(gds_status);
|
|
|
|
return;
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void list_foreign()
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* l i s t _ f o r e i g n
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* List all foreign key constraints and alter the tables
|
|
|
|
*
|
|
|
|
**************************************/
|
2005-03-26 06:33:55 +01:00
|
|
|
SCHAR collist[BUFFER_LENGTH512 * 2];
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
/* Static queries for obtaining foreign constraints, where RELC1 is the
|
|
|
|
foreign key constraints, RELC2 is the primary key lookup and REFC
|
|
|
|
is the join table */
|
|
|
|
|
|
|
|
FOR RELC1 IN RDB$RELATION_CONSTRAINTS CROSS
|
2003-09-29 14:43:14 +02:00
|
|
|
RELC2 IN RDB$RELATION_CONSTRAINTS CROSS
|
|
|
|
REFC IN RDB$REF_CONSTRAINTS WITH
|
|
|
|
RELC1.RDB$CONSTRAINT_TYPE EQ "FOREIGN KEY" AND
|
|
|
|
REFC.RDB$CONST_NAME_UQ EQ RELC2.RDB$CONSTRAINT_NAME AND
|
|
|
|
REFC.RDB$CONSTRAINT_NAME EQ RELC1.RDB$CONSTRAINT_NAME AND
|
|
|
|
(RELC2.RDB$CONSTRAINT_TYPE EQ "UNIQUE" OR
|
|
|
|
RELC2.RDB$CONSTRAINT_TYPE EQ "PRIMARY KEY")
|
|
|
|
SORTED BY RELC1.RDB$RELATION_NAME, RELC1.RDB$CONSTRAINT_NAME
|
|
|
|
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(RELC1.RDB$RELATION_NAME);
|
|
|
|
fb_utils::exact_name(RELC2.RDB$RELATION_NAME);
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2005-03-26 06:33:55 +01:00
|
|
|
ISQL_get_index_segments (collist, sizeof(collist), RELC1.RDB$INDEX_NAME, true);
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf(NEWLINE);
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2004-05-24 19:16:02 +02:00
|
|
|
if (isqlGlob.db_SQL_dialect > SQL_DIALECT_V6_TRANSITION)
|
2003-09-29 14:43:14 +02:00
|
|
|
{
|
|
|
|
ISQL_copy_SQL_id (RELC1.RDB$RELATION_NAME, SQL_identifier,
|
|
|
|
DBL_QUOTE);
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("ALTER TABLE %s ADD ", SQL_identifier);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
else
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("ALTER TABLE %s ADD ",
|
2003-09-29 14:43:14 +02:00
|
|
|
RELC1.RDB$RELATION_NAME);
|
|
|
|
|
|
|
|
/* If the name of the constraint is not INTEG..., print it.
|
2001-05-23 15:26:42 +02:00
|
|
|
INTEG... are internally generated names. */
|
2003-09-29 14:43:14 +02:00
|
|
|
if (!RELC1.RDB$CONSTRAINT_NAME.NULL &&
|
|
|
|
strncmp(RELC1.RDB$CONSTRAINT_NAME, "INTEG", 5))
|
|
|
|
{
|
|
|
|
ISQL_truncate_term (RELC1.RDB$CONSTRAINT_NAME,
|
|
|
|
strlen(RELC1.RDB$CONSTRAINT_NAME));
|
2004-05-24 19:16:02 +02:00
|
|
|
if (isqlGlob.db_SQL_dialect > SQL_DIALECT_V6_TRANSITION)
|
2003-09-29 14:43:14 +02:00
|
|
|
{
|
|
|
|
ISQL_copy_SQL_id (RELC1.RDB$CONSTRAINT_NAME, SQL_identifier,
|
|
|
|
DBL_QUOTE);
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("CONSTRAINT %s ", SQL_identifier);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
else
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("CONSTRAINT %s ",
|
2003-09-29 14:43:14 +02:00
|
|
|
RELC1.RDB$CONSTRAINT_NAME);
|
|
|
|
}
|
|
|
|
|
2004-05-24 19:16:02 +02:00
|
|
|
if (isqlGlob.db_SQL_dialect > SQL_DIALECT_V6_TRANSITION)
|
2003-09-29 14:43:14 +02:00
|
|
|
{
|
|
|
|
ISQL_copy_SQL_id (RELC2.RDB$RELATION_NAME, SQL_identifier,
|
|
|
|
DBL_QUOTE);
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("FOREIGN KEY (%s) REFERENCES %s ",
|
2003-09-29 14:43:14 +02:00
|
|
|
collist, SQL_identifier);
|
|
|
|
}
|
|
|
|
else
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("FOREIGN KEY (%s) REFERENCES %s ",
|
2003-09-29 14:43:14 +02:00
|
|
|
collist,
|
|
|
|
RELC2.RDB$RELATION_NAME);
|
|
|
|
|
2003-11-28 07:48:34 +01:00
|
|
|
// Get the column list for the primary key
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2005-03-26 06:33:55 +01:00
|
|
|
ISQL_get_index_segments (collist, sizeof(collist), RELC2.RDB$INDEX_NAME, true);
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("(%s)", collist);
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2003-11-28 07:48:34 +01:00
|
|
|
// Add the referential actions, if any
|
2003-09-29 14:43:14 +02:00
|
|
|
if (!REFC.RDB$UPDATE_RULE.NULL)
|
|
|
|
{
|
|
|
|
ISQL_truncate_term (REFC.RDB$UPDATE_RULE,
|
|
|
|
strlen(REFC.RDB$UPDATE_RULE));
|
|
|
|
ISQL_ri_action_print (REFC.RDB$UPDATE_RULE, " ON UPDATE", true);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!REFC.RDB$DELETE_RULE.NULL)
|
|
|
|
{
|
|
|
|
ISQL_truncate_term (REFC.RDB$DELETE_RULE,
|
|
|
|
strlen(REFC.RDB$DELETE_RULE));
|
|
|
|
ISQL_ri_action_print (REFC.RDB$DELETE_RULE, " ON DELETE", true);
|
|
|
|
}
|
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%s%s", isqlGlob.global_Term, NEWLINE);
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
END_FOR
|
2003-09-29 14:43:14 +02:00
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(gds_status);
|
|
|
|
return;
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
static void list_functions()
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* l i s t _ f u n c t i o n s
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* List all external functions
|
|
|
|
*
|
|
|
|
* Parameters: none
|
2003-09-29 14:43:14 +02:00
|
|
|
* Results in
|
2001-05-23 15:26:42 +02:00
|
|
|
* DECLARE EXTERNAL FUNCTION function_name
|
2003-11-28 07:48:34 +01:00
|
|
|
* CHAR(256) , INTEGER, ....
|
2001-05-23 15:26:42 +02:00
|
|
|
* RETURNS INTEGER BY VALUE
|
|
|
|
* ENTRY_POINT entrypoint MODULE_NAME module;
|
|
|
|
**************************************/
|
2005-03-26 06:33:55 +01:00
|
|
|
char type_buffer[BUFFER_LENGTH128];
|
|
|
|
char return_buffer[BUFFER_LENGTH128];
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-12-04 09:30:43 +01:00
|
|
|
bool first = true;
|
|
|
|
|
2003-09-29 14:43:14 +02:00
|
|
|
FOR FUN IN RDB$FUNCTIONS
|
2004-11-30 04:22:50 +01:00
|
|
|
WITH FUN.RDB$SYSTEM_FLAG NE 1 OR FUN.RDB$SYSTEM_FLAG MISSING
|
2003-09-29 14:43:14 +02:00
|
|
|
SORTED BY FUN.RDB$FUNCTION_NAME
|
|
|
|
|
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-09-29 14:43:14 +02:00
|
|
|
if (first)
|
|
|
|
{
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%s/* External Function declarations */%s",
|
2003-09-29 14:43:14 +02:00
|
|
|
NEWLINE,
|
|
|
|
NEWLINE);
|
|
|
|
first = false;
|
|
|
|
}
|
|
|
|
|
2003-11-28 07:48:34 +01:00
|
|
|
// Start new function declaration
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("DECLARE EXTERNAL FUNCTION %s %s",
|
2003-09-29 14:43:14 +02:00
|
|
|
FUN.RDB$FUNCTION_NAME,
|
|
|
|
NEWLINE);
|
|
|
|
|
2004-12-04 09:30:43 +01:00
|
|
|
bool firstarg = true;
|
2003-09-29 14:43:14 +02:00
|
|
|
|
|
|
|
FOR FNA IN RDB$FUNCTION_ARGUMENTS WITH
|
|
|
|
FUN.RDB$FUNCTION_NAME EQ FNA.RDB$FUNCTION_NAME
|
|
|
|
SORTED BY FNA.RDB$ARGUMENT_POSITION
|
|
|
|
|
2003-11-28 07:48:34 +01:00
|
|
|
// Find parameter type
|
2004-11-10 05:26:45 +01:00
|
|
|
int i = 0;
|
2003-11-28 07:48:34 +01:00
|
|
|
while (FNA.RDB$FIELD_TYPE != Column_types[i].type)
|
2003-09-29 14:43:14 +02:00
|
|
|
i++;
|
|
|
|
|
2003-11-28 07:48:34 +01:00
|
|
|
// Print length where appropriate
|
2004-04-24 16:38:27 +02:00
|
|
|
if ((FNA.RDB$FIELD_TYPE == T_CHAR) ||
|
2003-09-29 14:43:14 +02:00
|
|
|
(FNA.RDB$FIELD_TYPE == VARCHAR) ||
|
|
|
|
(FNA.RDB$FIELD_TYPE == CSTRING))
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-11-28 07:48:34 +01:00
|
|
|
bool did_charset = false;
|
2003-09-29 14:43:14 +02:00
|
|
|
FOR CHARSET IN RDB$CHARACTER_SETS
|
|
|
|
WITH CHARSET.RDB$CHARACTER_SET_ID = FNA.RDB$CHARACTER_SET_ID
|
|
|
|
|
2003-11-28 07:48:34 +01:00
|
|
|
did_charset = true;
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(CHARSET.RDB$CHARACTER_SET_NAME);
|
2003-09-29 14:43:14 +02:00
|
|
|
sprintf (type_buffer, "%s(%d) CHARACTER SET %s",
|
2003-11-28 07:48:34 +01:00
|
|
|
Column_types[i].type_name,
|
|
|
|
(FNA.RDB$FIELD_LENGTH / MAX (1, CHARSET.RDB$BYTES_PER_CHARACTER)),
|
2003-09-29 14:43:14 +02:00
|
|
|
CHARSET.RDB$CHARACTER_SET_NAME);
|
|
|
|
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg (gds_status);
|
|
|
|
return;
|
|
|
|
END_ERROR;
|
|
|
|
|
|
|
|
if (!did_charset)
|
2003-11-28 07:48:34 +01:00
|
|
|
sprintf (type_buffer, "%s(%d)", Column_types[i].type_name,
|
2003-09-29 14:43:14 +02:00
|
|
|
FNA.RDB$FIELD_LENGTH);
|
|
|
|
}
|
|
|
|
else
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-09-29 14:43:14 +02:00
|
|
|
bool precision_known = false;
|
|
|
|
|
2004-05-24 19:16:02 +02:00
|
|
|
if ( (isqlGlob.major_ods >= ODS_VERSION10) &&
|
2003-09-29 14:43:14 +02: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-09-29 14:43:14 +02:00
|
|
|
FOR FNA1 IN RDB$FUNCTION_ARGUMENTS WITH
|
|
|
|
FNA1.RDB$FUNCTION_NAME EQ FNA.RDB$FUNCTION_NAME AND
|
|
|
|
FNA1.RDB$ARGUMENT_POSITION EQ FNA.RDB$ARGUMENT_POSITION
|
|
|
|
|
|
|
|
/* We are ODS >= 10 and could be any Dialect */
|
|
|
|
if (!FNA1.RDB$FIELD_PRECISION.NULL)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-09-29 14:43:14 +02: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-09-29 14:43:14 +02:00
|
|
|
sprintf (type_buffer, "%s(%d, %d)",
|
2003-11-28 07:48:34 +01:00
|
|
|
Integral_subtypes[FNA1.RDB$FIELD_SUB_TYPE],
|
2003-09-29 14:43:14 +02:00
|
|
|
FNA1.RDB$FIELD_PRECISION,
|
|
|
|
-FNA1.RDB$FIELD_SCALE);
|
|
|
|
precision_known = true;
|
|
|
|
}
|
2003-11-28 07:48:34 +01:00
|
|
|
} // if field_precision is not null
|
2003-09-29 14:43:14 +02:00
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg (isc_status);
|
|
|
|
return;
|
|
|
|
END_ERROR;
|
2004-05-24 19:16:02 +02:00
|
|
|
} /* if isqlGlob.major_ods >= ods_version10 && */
|
2003-09-29 14:43:14 +02:00
|
|
|
|
|
|
|
if (!precision_known)
|
|
|
|
{
|
2003-11-28 07:48:34 +01:00
|
|
|
// Take a stab at numerics and decimals
|
2003-09-29 14:43:14 +02:00
|
|
|
if ((FNA.RDB$FIELD_TYPE == SMALLINT) &&
|
|
|
|
(FNA.RDB$FIELD_SCALE < 0))
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-09-29 14:43:14 +02:00
|
|
|
sprintf (type_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-09-29 14:43:14 +02:00
|
|
|
sprintf (type_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-09-29 14:43:14 +02:00
|
|
|
sprintf (type_buffer, "NUMERIC(15, %d)",
|
|
|
|
-FNA.RDB$FIELD_SCALE);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
sprintf (type_buffer, "%s",
|
2003-11-28 07:48:34 +01:00
|
|
|
Column_types[i].type_name);
|
2004-03-07 08:58:55 +01:00
|
|
|
} // if !precision_known
|
2004-04-24 16:38:27 +02:00
|
|
|
} // if T_CHAR or VARCHAR or CSTRING ... else
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2003-11-28 07:48:34 +01:00
|
|
|
// If a return argument, save it for the end, otherwise print
|
2003-09-29 14:43:14 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Changed the following to not return a BLOB by value.
|
|
|
|
* To be sincere, this code doesn't cater for the RETURNS PARAMETER syntax but
|
|
|
|
* it would require more surgery than I'm willing to do, since I'm sick of isql
|
|
|
|
* so I started my own metadata extraction utility based on IBO that does this
|
|
|
|
* trick and others.
|
|
|
|
* Claudio Valderrama (by way of) MOD 23-Apr-2001
|
|
|
|
|
|
|
|
CVC: Finally enhanced the UDF metadata extraction.
|
|
|
|
*/
|
|
|
|
|
2004-11-10 05:26:45 +01:00
|
|
|
int ptype = (int) abs(FNA.RDB$MECHANISM);
|
2004-09-22 03:55:37 +02:00
|
|
|
if (ptype > MAX_UDFPARAM_TYPES)
|
|
|
|
ptype = MAX_UDFPARAM_TYPES;
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2004-12-04 09:30:43 +01:00
|
|
|
bool printarg = true;
|
2003-09-29 14:43:14 +02:00
|
|
|
|
|
|
|
if (FUN.RDB$RETURN_ARGUMENT == FNA.RDB$ARGUMENT_POSITION) {
|
|
|
|
if (FUN.RDB$RETURN_ARGUMENT) {
|
|
|
|
sprintf (return_buffer, "RETURNS PARAMETER %d",
|
|
|
|
FUN.RDB$RETURN_ARGUMENT);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
sprintf (return_buffer, "RETURNS %s%s %s", type_buffer,
|
|
|
|
UDF_param_types[ptype],
|
|
|
|
(FNA.RDB$MECHANISM < 0 ? "FREE_IT" : ""));
|
|
|
|
printarg = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (printarg) {
|
2003-11-28 07:48:34 +01:00
|
|
|
// First arg needs no comma
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%s%s%s", (firstarg ? "" : ", "), type_buffer,
|
2003-09-29 14:43:14 +02:00
|
|
|
UDF_param_types[ptype]);
|
|
|
|
firstarg = false;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
2002-06-29 15:39:11 +02:00
|
|
|
|
2003-09-29 14:43:14 +02:00
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg (gds_status);
|
|
|
|
return;
|
|
|
|
END_ERROR;
|
|
|
|
|
2003-11-28 07:48:34 +01:00
|
|
|
// Print the return type -- All functions return a type
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%s%s%s",
|
2003-09-29 14:43:14 +02:00
|
|
|
NEWLINE,
|
|
|
|
return_buffer,
|
|
|
|
NEWLINE);
|
|
|
|
|
2003-11-28 07:48:34 +01:00
|
|
|
// Print out entrypoint information
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("ENTRY_POINT '%s' MODULE_NAME '%s'%s%s%s",
|
2003-09-29 14:43:14 +02:00
|
|
|
FUN.RDB$ENTRYPOINT,
|
|
|
|
FUN.RDB$MODULE_NAME,
|
2004-05-24 19:16:02 +02:00
|
|
|
isqlGlob.global_Term,
|
2003-09-29 14:43:14 +02:00
|
|
|
NEWLINE,
|
|
|
|
NEWLINE);
|
2002-06-29 15:39:11 +02:00
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
END_FOR
|
2003-09-29 14:43:14 +02:00
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(gds_status);
|
|
|
|
return;
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2003-11-30 07:41:29 +01:00
|
|
|
static void list_generators()
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* l i s t _ g e n e r a t o r s
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Re create all non-system generators
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
|
2005-05-19 10:03:10 +02:00
|
|
|
bool first = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
FOR GEN IN RDB$GENERATORS WITH
|
2003-09-29 14:43:14 +02:00
|
|
|
GEN.RDB$GENERATOR_NAME NOT MATCHING "RDB$+" USING "+=[0-9][0-9]* *" AND
|
|
|
|
GEN.RDB$GENERATOR_NAME NOT MATCHING "SQL$+" USING "+=[0-9][0-9]* *" AND
|
|
|
|
(GEN.RDB$SYSTEM_FLAG MISSING OR GEN.RDB$SYSTEM_FLAG NE 1)
|
|
|
|
SORTED BY GEN.RDB$GENERATOR_NAME
|
|
|
|
|
2005-05-19 10:03:10 +02:00
|
|
|
if (first)
|
|
|
|
{
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf(
|
2005-05-19 10:03:10 +02:00
|
|
|
"%s/* Generators or sequences */%s",
|
|
|
|
NEWLINE,
|
|
|
|
NEWLINE);
|
|
|
|
first = false;
|
|
|
|
}
|
|
|
|
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(GEN.RDB$GENERATOR_NAME);
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2004-05-24 19:16:02 +02:00
|
|
|
if (isqlGlob.db_SQL_dialect > SQL_DIALECT_V6_TRANSITION)
|
2003-09-29 14:43:14 +02:00
|
|
|
ISQL_copy_SQL_id (GEN.RDB$GENERATOR_NAME, SQL_identifier, DBL_QUOTE);
|
|
|
|
else
|
|
|
|
strcpy (SQL_identifier, GEN.RDB$GENERATOR_NAME);
|
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("CREATE GENERATOR %s%s%s",
|
2003-09-29 14:43:14 +02:00
|
|
|
SQL_identifier,
|
2004-05-24 19:16:02 +02:00
|
|
|
isqlGlob.global_Term,
|
2003-09-29 14:43:14 +02:00
|
|
|
NEWLINE);
|
2001-05-23 15:26:42 +02:00
|
|
|
END_FOR
|
2003-09-29 14:43:14 +02:00
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(gds_status);
|
|
|
|
return;
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
|
|
|
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf(NEWLINE);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void list_index()
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* l i s t _ i n d e x
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Define all non-constraint indices
|
|
|
|
* Use a static SQL query to get the info and print it.
|
|
|
|
*
|
|
|
|
* Uses get_index_segment to provide a key list for each index
|
|
|
|
*
|
|
|
|
**************************************/
|
2005-03-26 06:33:55 +01:00
|
|
|
char collist[BUFFER_LENGTH512 * 2];
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-04-11 06:04:18 +02:00
|
|
|
bool first = true;
|
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
FOR IDX IN RDB$INDICES CROSS RELC IN RDB$RELATIONS
|
2003-09-29 14:43:14 +02:00
|
|
|
OVER RDB$RELATION_NAME
|
|
|
|
WITH (RELC.RDB$SYSTEM_FLAG NE 1 OR RELC.RDB$SYSTEM_FLAG MISSING)
|
|
|
|
AND NOT (ANY RC IN RDB$RELATION_CONSTRAINTS
|
2005-05-19 10:03:10 +02:00
|
|
|
WITH RC.RDB$INDEX_NAME EQ IDX.RDB$INDEX_NAME)
|
2003-09-29 14:43:14 +02:00
|
|
|
SORTED BY IDX.RDB$RELATION_NAME, IDX.RDB$INDEX_NAME
|
|
|
|
|
|
|
|
if (first)
|
|
|
|
{
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf(
|
2003-09-29 14:43:14 +02:00
|
|
|
"%s/* Index definitions for all user tables */%s",
|
|
|
|
NEWLINE,
|
|
|
|
NEWLINE);
|
2005-05-19 10:03:10 +02:00
|
|
|
first = false;
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
|
2005-05-19 10:03:10 +02:00
|
|
|
// Strip trailing blanks
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(IDX.RDB$RELATION_NAME);
|
|
|
|
fb_utils::exact_name(IDX.RDB$INDEX_NAME);
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2004-05-24 19:16:02 +02:00
|
|
|
if (isqlGlob.db_SQL_dialect > SQL_DIALECT_V6_TRANSITION)
|
2003-09-29 14:43:14 +02:00
|
|
|
{
|
|
|
|
ISQL_copy_SQL_id (IDX.RDB$INDEX_NAME, SQL_identifier, DBL_QUOTE);
|
|
|
|
ISQL_copy_SQL_id (IDX.RDB$RELATION_NAME, SQL_identifier2, DBL_QUOTE);
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("CREATE%s%s INDEX %s ON %s",
|
2005-05-18 17:53:41 +02:00
|
|
|
(IDX.RDB$UNIQUE_FLAG ? " UNIQUE" : ""),
|
|
|
|
(IDX.RDB$INDEX_TYPE ? " DESCENDING" : ""),
|
|
|
|
SQL_identifier,
|
|
|
|
SQL_identifier2);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
else
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("CREATE%s%s INDEX %s ON %s",
|
2005-05-18 17:53:41 +02:00
|
|
|
(IDX.RDB$UNIQUE_FLAG ? " UNIQUE" : ""),
|
|
|
|
(IDX.RDB$INDEX_TYPE ? " DESCENDING" : ""),
|
|
|
|
IDX.RDB$INDEX_NAME,
|
|
|
|
IDX.RDB$RELATION_NAME);
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2005-05-18 17:53:41 +02:00
|
|
|
// Get index expression or column names
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2005-05-18 17:53:41 +02:00
|
|
|
#ifdef EXPRESSION_INDICES
|
|
|
|
if (!IDX.RDB$EXPRESSION_BLR.NULL)
|
|
|
|
{
|
2005-05-26 08:45:25 +02:00
|
|
|
isqlGlob.printf(" COMPUTED BY ");
|
2005-05-18 17:53:41 +02:00
|
|
|
if (!IDX.RDB$EXPRESSION_SOURCE.NULL)
|
|
|
|
SHOW_print_metadata_text_blob (isqlGlob.Out, &IDX.RDB$EXPRESSION_SOURCE);
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%s%s", isqlGlob.global_Term, NEWLINE);
|
2005-05-18 17:53:41 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
#endif
|
2005-03-26 06:33:55 +01:00
|
|
|
if (ISQL_get_index_segments (collist, sizeof(collist), IDX.RDB$INDEX_NAME, true))
|
2003-09-29 14:43:14 +02:00
|
|
|
{
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(" (%s)%s%s", collist, isqlGlob.global_Term, NEWLINE);
|
2003-09-29 14:43:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(gds_status);
|
|
|
|
return;
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void list_views()
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* l i s t _ v i e w s
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Show text of views.
|
|
|
|
* Use a SQL query to get the info and print it.
|
|
|
|
* Note: This should also contain check option
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
|
2003-11-28 07:48:34 +01:00
|
|
|
// If this is a view, use print_blob to print the view text
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
FOR REL IN RDB$RELATIONS WITH
|
2003-09-29 14:43:14 +02:00
|
|
|
(REL.RDB$SYSTEM_FLAG NE 1 OR REL.RDB$SYSTEM_FLAG MISSING) AND
|
|
|
|
REL.RDB$VIEW_BLR NOT MISSING AND
|
|
|
|
REL.RDB$FLAGS = REL_sql
|
|
|
|
SORTED BY REL.RDB$RELATION_ID
|
|
|
|
|
2004-04-11 06:04:18 +02:00
|
|
|
bool first = true;
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(REL.RDB$RELATION_NAME);
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2004-05-24 19:16:02 +02:00
|
|
|
if (isqlGlob.db_SQL_dialect > SQL_DIALECT_V6_TRANSITION)
|
2003-09-29 14:43:14 +02:00
|
|
|
ISQL_copy_SQL_id (REL.RDB$RELATION_NAME, SQL_identifier, DBL_QUOTE);
|
|
|
|
else
|
|
|
|
strcpy (SQL_identifier, REL.RDB$RELATION_NAME);
|
|
|
|
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(REL.RDB$OWNER_NAME);
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%s/* View: %s, Owner: %s */%s",
|
2003-09-29 14:43:14 +02:00
|
|
|
NEWLINE,
|
|
|
|
REL.RDB$RELATION_NAME,
|
|
|
|
REL.RDB$OWNER_NAME,
|
|
|
|
NEWLINE);
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("CREATE VIEW %s (", SQL_identifier);
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2003-11-28 07:48:34 +01:00
|
|
|
// Get column list
|
2003-09-29 14:43:14 +02:00
|
|
|
FOR RFR IN RDB$RELATION_FIELDS WITH
|
|
|
|
RFR.RDB$RELATION_NAME = REL.RDB$RELATION_NAME
|
|
|
|
SORTED BY RFR.RDB$FIELD_POSITION
|
|
|
|
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name(RFR.RDB$FIELD_NAME);
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2004-05-24 19:16:02 +02:00
|
|
|
if (isqlGlob.db_SQL_dialect > SQL_DIALECT_V6_TRANSITION)
|
2003-09-29 14:43:14 +02:00
|
|
|
ISQL_copy_SQL_id (RFR.RDB$FIELD_NAME, SQL_identifier, DBL_QUOTE);
|
|
|
|
else
|
|
|
|
strcpy (SQL_identifier, RFR.RDB$FIELD_NAME);
|
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%s%s", (first ? "" : ", "), SQL_identifier);
|
2003-09-29 14:43:14 +02:00
|
|
|
first = false;
|
|
|
|
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg (gds_status);
|
|
|
|
return;
|
|
|
|
END_ERROR;
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf(") AS%s", NEWLINE);
|
2003-09-29 14:43:14 +02: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);
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2005-05-24 06:42:01 +02:00
|
|
|
isqlGlob.printf("%s%s", isqlGlob.global_Term, NEWLINE);
|
2003-09-29 14:43:14 +02:00
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
END_FOR
|
2003-09-29 14:43:14 +02:00
|
|
|
ON_ERROR
|
|
|
|
ISQL_errmsg(gds_status);
|
|
|
|
return;
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
|
|
|
}
|
2003-09-29 14:43:14 +02:00
|
|
|
|
|
|
|
|