📄 isql.e
字号:
/* * PROGRAM: Interactive SQL utility * MODULE: isql.e * DESCRIPTION: Main line routine * * 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): ______________________________________. *//* $Id: isql.e,v 1.1.1.1 2002/01/14 05:59:56 robocop Exp $ Revision 1.5 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 :-) 2001/05/20 Neil McCalden add planonly option 2001.09.09 Claudio Valderrama: put double quotes around identifiers in dialect 3 only when needed. Solve mischievous declaration/invocation of ISQL_copy_SQL_id that made no sense and caused pointer problems. 2001/10/03 Neil McCalden pick up Firebird version from database server and display it with client version when -z used. 2001.10.09 Claudio Valderrama: try to disconnect gracefully in batch mode. 2001.11.23 Claudio Valderrama: skip any number of -- comments but only at the beginning and ignore void statements like block comments followed by a semicolon.*/#include "../jrd/ib_stdio.h"#include <stdlib.h>#include <string.h>#include <signal.h>#include <math.h>#include <ctype.h>#include <errno.h>#define TIME_ERR 101#define BLANK '\040'#define DBL_QUOTE '\042'#define SINGLE_QUOTE '\''#define KW_FILE "IB_FILE"#define INIT_STR_FLAG 0#define SINGLE_QUOTED_STRING 1#define DOUBLE_QUOTED_STRING 2#define NO_MORE_STRING 3#define INCOMPLETE_STRING 4#define KW_ROLE "ROLE"#include "../jrd/time.h"#define ISQL_MAIN#include "../jrd/common.h"#if defined(WIN_NT) || defined(GUI_TOOLS)#include <windows.h>#endif#include "../jrd/codes.h"#include "../jrd/gds.h"#include "../isql/isql.h"#include "../jrd/perf.h"#include "../jrd/license.h"#include "../jrd/constants.h"#include "../jrd/ods.h"#include "../isql/extra_proto.h"#include "../isql/isql_proto.h"#include "../isql/show_proto.h"#include "../jrd/gds_proto.h"#include "../jrd/perf_proto.h"#include "../jrd/utl_proto.h"#ifdef GUI_TOOLS#include "../wisql/isqlcomm.h"#endif#ifdef WINDOWS_ONLY#include "../jrd/seg_proto.h"#endif#include "../jrd/gdsassert.h"DATABASE DB = COMPILETIME "yachts.lnk";#define STUFF(x) *dpb++ = (x)#define STUFF_INT(x) {STUFF (x); STUFF ((x) >> 8); STUFF ((x) >> 16); STUFF ((x) >> 24);}#define DIGIT(c) ((c) >= '0' && (c) <= '9')#define INT64_LIMIT ((((SINT64) 1) << 62) / 5) /* same as in cvt.c *//* Print lengths of numeric values */#define MAXCHARSET_LENGTH 32 /* CHARSET names */#define SHORT_LEN 7 /* NUMERIC (4,2) = -327.68 */#define LONG_LEN 12 /* NUMERIC (9,2) = -21474836.48 */#define INT64_LEN 21 /* NUMERIC(18,2) = -92233720368547758.08 */#define QUAD_LEN 19#define FLOAT_LEN 14 /* -1.2345678E+38 */#define DOUBLE_LEN 23 /* -1.234567890123456E+300 */#define DATE_LEN 11 /* 11 for date only */#define DATETIME_LEN 25 /* 25 for date-time */#define TIME_ONLY_LEN 13 /* 13 for time only */#define DATE_ONLY_LEN 11#define UNKNOWN_LEN 20 /* Unknown type: %d */#define MAX_TERMS 10 /* max # of terms in an interactive cmd */#define COMMIT_TRANS(x) {if (isc_commit_transaction (isc_status, x)) { ISQL_errmsg (isc_status); isc_rollback_transaction (isc_status, x); }}typedef struct indev { struct indev *indev_next; IB_FILE *indev_fpointer; ULONG lines, global_lines; TEXT *InputFileName;} *INDEV;typedef struct collist { struct collist *collist_next; TEXT col_name [WORDLENGTH]; SSHORT col_len;} COLLIST;typedef struct ri_actions { SCHAR *ri_action_name; SCHAR *ri_action_print_caps; SCHAR *ri_action_print_mixed;} RI_ACTIONS;static SSHORT add_row (TEXT *);static SSHORT blobedit (TEXT *, TEXT **);static void col_check (TEXT *, SSHORT *);static void compute_script_position (TEXT *, ULONG, BOOLEAN, TEXT *);static void copy_str (TEXT **, TEXT **, BOOLEAN *, TEXT *, TEXT *, SSHORT);static SSHORT copy_table (TEXT *, TEXT *, TEXT *);static SSHORT create_db (TEXT *, TEXT *);static void do_isql (void);static SSHORT drop_db (void);static SSHORT edit (TEXT **);static int end_trans (void);static SSHORT escape (TEXT *);static SSHORT frontend (TEXT *, ULONG *, ULONG *);static SSHORT get_statement (TEXT **, USHORT *, TEXT*, ULONG *, ULONG *);static BOOLEAN get_numeric (UCHAR *, USHORT, SSHORT *, SINT64 *);static void get_str (TEXT *, TEXT **, TEXT **, SSHORT *);static SSHORT print_sets (void);static SSHORT help (TEXT *);static SSHORT input (TEXT *, ULONG *, ULONG *);static BOOLEAN isyesno (TEXT *);static SSHORT newdb (TEXT *, TEXT *, TEXT *, TEXT *, TEXT *, BOOLEAN);static SSHORT newoutput (TEXT *);static SSHORT newsize (TEXT *, TEXT *);static SSHORT newtrans (TEXT *);static SSHORT parse_arg (int, SCHAR **, SCHAR *, IB_FILE **);static SSHORT print_item (TEXT **, XSQLVAR *, SLONG);static int print_item_blob (IB_FILE *, XSQLVAR *, void *);static void print_item_numeric (SINT64, SSHORT, SSHORT, TEXT *);static int print_line (XSQLDA *, SLONG *, TEXT *);static int process_statement (TEXT *, XSQLDA **, ULONG *);static void CLIB_ROUTINE query_abort (void);static void strip_quotes (TEXT *, TEXT *);static SSHORT do_set_command (TEXT *, SSHORT *);#ifdef DEV_BUILDstatic UCHAR *sqltype_to_string (USHORT);#endifXSQLDA *sqlda;XSQLDA **sqldap;USHORT dialect_spoken = 0;USHORT requested_SQL_dialect = SQL_DIALECT_V6;BOOLEAN connecting_to_pre_v6_server = FALSE;SSHORT V45 = FALSE;SSHORT V4 = FALSE;SSHORT V33 = FALSE;USHORT major_ods = 0;USHORT minor_ods = 0;SCHAR server_version [256];SSHORT Quiet;SSHORT Version_info = FALSE;#if defined (WIN95) && !defined (GUI_TOOLS)BOOL fAnsiCP;#endifstatic COLLIST *Cols = NULL;static SCHAR statistics [256];static INDEV Filelist;static TEXT Tmpfile [128];static int Abort_flag = 0;static SSHORT Echo = FALSE;static SSHORT Time_display = FALSE;static SSHORT Sqlda_display = FALSE;static SSHORT Exit_value;static BOOLEAN Continuation = FALSE;static BOOLEAN Interactive = TRUE;static BOOLEAN Input_file = FALSE;static SSHORT Pagelength = 20;static SSHORT Stats = FALSE;static SSHORT Autocommit = TRUE; /* Commit ddl */static SSHORT Warnings = TRUE; /* Print warnings */static SSHORT Autofetch = TRUE; /* automatically fetch all records */static USHORT fetch_direction = 0;static SLONG fetch_offset = 1; static SSHORT Doblob = 1; /* Default to printing only text types */static SSHORT List = FALSE; static SSHORT Docount = FALSE;static SSHORT Plan = FALSE;static SSHORT Planonly = FALSE;static int Termlen = 0;static SCHAR ISQL_charset[MAXCHARSET_LENGTH] = {0};static IB_FILE *Diag;static IB_FILE *Help;static TEXT *sql_prompt = "SQL> ";static TEXT *fetch_prompt = "FETCH> ";#ifdef GUI_TOOLSstatic IB_FILE *Session; /* WISQL session file */static TEXT *SaveOutfileName; /* WISQL output file name */#elsestatic TEXT *CurrentInputFileName = 0;#endif static BOOLEAN global_psw = FALSE;static BOOLEAN global_usr = FALSE;static BOOLEAN global_role = FALSE;static BOOLEAN global_numbufs = FALSE;static BOOLEAN have_trans = FALSE; /* translation of word "Yes" */static TEXT yesword [MSG_LENGTH]; static TEXT Print_buffer [PRINT_BUFFER_LENGTH];static UCHAR db_version_info [] = { isc_info_ods_version, isc_info_ods_minor_version, isc_info_db_sql_dialect };static UCHAR blr_bpb [] = { isc_bpb_version1, isc_bpb_source_type, 1, BLOB_blr, isc_bpb_target_type, 1, BLOB_text }, text_bpb [] = { isc_bpb_version1, isc_bpb_source_type, 1, BLOB_text, isc_bpb_target_type, 1, BLOB_text }, acl_bpb [] = { isc_bpb_version1, isc_bpb_source_type, 1, BLOB_acl, isc_bpb_target_type, 1, BLOB_text };/* Note that these transaction options aren't understood in Version 3.3 */static UCHAR default_tpb [] = {isc_tpb_version1, isc_tpb_write, isc_tpb_read_committed, isc_tpb_wait, isc_tpb_no_rec_version};/* CVC: Just in case we need it for R/O operations in the future. */static UCHAR batch_tpb [] = {isc_tpb_version3, isc_tpb_read, isc_tpb_read_committed, isc_tpb_nowait, isc_tpb_rec_version};/* InterBase Performance Statistic format Variables */static struct perf perf_before, perf_after;static BOOLEAN have_report = FALSE; /* translation of report strings */static TEXT report_1 [MSG_LENGTH + MSG_LENGTH];static TEXT report_2 [MSG_LENGTH];static TEXT rec_count [MSG_LENGTH];/* if the action is rrstrict, do not print anything at all */static RI_ACTIONS ri_actions_all [] = { RI_ACTION_CASCADE, RI_ACTION_CASCADE, "Cascade", RI_ACTION_NULL, RI_ACTION_NULL, "Set Null", RI_ACTION_DEFAULT, RI_ACTION_DEFAULT, "Set Default", RI_ACTION_NONE, RI_ACTION_NONE, "No Action", RI_RESTRICT, "", "", "", "", "", 0, 0, 0 }; typedef struct tok_name {/* USHORT tok_ident;*/ CONST SCHAR *tok_string;/* CONST USHORT tok_version;*/} TOK_NAME;#define DSQL_KEYWORD(tok_nr, tok_str, tok_ver) tok_str,static CONST TOK_NAME tokens [] = {#include "../dsql/keywords.h" 0 };#undef DSQL_KEYWORD#ifndef GUI_TOOLSint CLIB_ROUTINE main ( int argc, char *argv[]){/************************************** * * m a i n * ************************************** * * Functional description * This calls ISQL_main, and exists to * isolate main which does not exist under * MS Windows. * **************************************/#if defined (WIN95) && !defined (GUI_TOOLS){ULONG ulConsoleCP;ulConsoleCP = GetConsoleCP();if (ulConsoleCP == GetACP()) fAnsiCP = TRUE;else { fAnsiCP = FALSE; if (ulConsoleCP != GetOEMCP() && Warnings) { ISQL_printf(Out, "WARNING: The current codepage is not supported. Any use of any\n" " extended characters may result in incorrect file names.\n"); } }}#endifExit_value = ISQL_main (argc, argv);exit (Exit_value);}#endifSSHORT ISQL_main ( int argc, char *argv[]){/************************************** * * I S Q L _ m a i n * ************************************** * * Functional description * Choose between reading and executing or generating SQL * ISQL_main isolates this from main for PC Clients. * **************************************/SSHORT ret;TEXT helpstring[155]; TEXT tabname [WORDLENGTH];#ifdef MU_ISQL/*** This is code for QA Test bed Multiuser environment.**** Setup multi-user test environment.*/if (qa_mu_environment()) { /* ** Initialize multi-user test manager only if in that ** environment. */ if (!qa_mu_init(argc, argv, 1)) { /* ** Some problem in initializing multi-user test ** environment. */ qa_mu_cleanup(); exit(1); } else { /* ** When invoked by MU, additional command-line argument ** was added at tail. ISQL is not interested in it so ** remove it. */ argv[argc - 1] = NULL; argc--; } }#endif MU_ISQLtabname [0] = '\0';db_SQL_dialect = 0;#ifdef GUI_TOOLS/* * Since there is no concept of stdout & stderr, we set Out and Errfp to * NULL initially.*/Out = NULL;Errfp = NULL;ret = parse_arg (argc, argv, tabname, &Session);/* Init the diagnostics and help files */Echo = TRUE;Diag = Out;Help = Out;#else/* Output goes to ib_stdout by default */Out = ib_stdout;Errfp = ib_stderr;ret = parse_arg (argc, argv, tabname, NULL);/* Init the diagnostics and help files */Diag = ib_stdout;Help = ib_stdout;#endifif (Merge_stderr) Errfp = Out;ISQL_make_upper (tabname);switch (ret) { case EXTRACT: /* This is a call to do extractions */ if (*Db_name) { Interactive = FALSE; #ifndef GUI_TOOLS /* Let's use user and password if provided. This should solve bug #112263 FSG 28.Jan.2001 */ (void) newdb (Db_name, User, Password, Numbufs, Role, FALSE); #endif Exit_value = EXTRACT_ddl (SQL_objects, tabname); #ifndef GUI_TOOLS ISQL_disconnect_database (TRUE); /* isc_detach_database(isc_status, &DB); */ #endif } break; case EXTRACTALL: if (*Db_name) { Interactive = FALSE; #ifndef GUI_TOOLS /* Let's use user and password if provided. This should solve bug #112263 FSG 28.Jan.2001 */ (void) newdb (Db_name, User, Password, Numbufs, Role, FALSE); #endif Exit_value = EXTRACT_ddl (ALL_objects, tabname); #ifndef GUI_TOOLS ISQL_disconnect_database (TRUE); /* isc_detach_database(isc_status, &DB); */ #endif } break; case ERR: gds__msg_format (NULL_PTR, ISQL_MSG_FAC, USAGE1, sizeof (helpstring), helpstring, NULL_PTR, NULL_PTR, NULL_PTR, NULL_PTR, NULL_PTR); STDERROUT (helpstring, 1); gds__msg_format (NULL_PTR, ISQL_MSG_FAC, USAGE2, sizeof (helpstring), helpstring, NULL_PTR, NULL_PTR, NULL_PTR, NULL_PTR, NULL_PTR); STDERROUT (helpstring, 1); gds__msg_format (NULL_PTR, ISQL_MSG_FAC, USAGE3, sizeof (helpstring), helpstring, NULL_PTR, NULL_PTR, NULL_PTR, NULL_PTR, NULL_PTR); STDERROUT (helpstring, 1); Exit_value = FINI_ERROR; break; default: do_isql(); Exit_value = FINI_OK; break; }#ifdef MU_ISQL/*** This is code for QA Test bed Multiuser environment.**** Do multi-user cleanup if running in multi-user domain.** qa_mu_cleanup() is NOP in non-multi-user domain.*/qa_mu_cleanup();#endif MU_ISQL#ifdef DEBUG_GDS_ALLOC/* As ISQL can run under windows, all memory should be freed before * returning. In debug mode this call will report unfreed blocks. */gds_alloc_report (0, __FILE__, __LINE__);#endif#ifdef GUI_TOOLS/* Free the original WISQL output file name */if (SaveOutfileName) { ISQL_FREE (SaveOutfileName); SaveOutfileName = NULL; }#endifreturn Exit_value;}void ISQL_array_dimensions ( TEXT *fieldname){/************************************** * * I S Q L _ a r r a y _ d i m e n s i o n s * ************************************** * * Functional description * Retrieves the dimensions of arrays and prints them. * * Parameters: fieldname -- the actual name of the array field * **************************************/ISQL_printf (Out, "[");/* Transaction for all frontend commands */if (DB && !gds__trans) if (isc_start_transaction (isc_status, &gds__trans, 1, &DB, 0, (SCHAR*) 0)) { ISQL_errmsg (isc_status); return; };FOR FDIM IN RDB$FIELD_DIMENSIONS WITH FDIM.RDB$FIELD_NAME EQ fieldname SORTED BY FDIM.RDB$DIMENSION /* Format is [lower:upper, lower:upper,..] */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -