2001-05-23 15:26:42 +02:00
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// PROGRAM: PASCAL preprocesser
|
|
|
|
// MODULE: pas.cpp
|
|
|
|
// DESCRIPTION: Inserted text generator for Domain Pascal
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// 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
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// 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.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// The Original Code was created by Inprise Corporation
|
|
|
|
// and its predecessors. Portions created by Inprise Corporation are
|
|
|
|
// Copyright (C) Inprise Corporation.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// All Rights Reserved.
|
|
|
|
// Contributor(s): ______________________________________.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
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 "../jrd/common.h"
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include <string.h>
|
2003-11-08 17:40:17 +01:00
|
|
|
#include "../jrd/ibase.h"
|
2001-05-23 15:26:42 +02:00
|
|
|
#include "../gpre/gpre.h"
|
|
|
|
#include "../gpre/pat.h"
|
|
|
|
#include "../gpre/cmp_proto.h"
|
|
|
|
#include "../gpre/lang_proto.h"
|
|
|
|
#include "../gpre/pat_proto.h"
|
|
|
|
#include "../gpre/gpre_proto.h"
|
|
|
|
#include "../gpre/prett_proto.h"
|
|
|
|
#include "../jrd/gds_proto.h"
|
2005-01-03 09:07:41 +01:00
|
|
|
#include "../common/utils_proto.h"
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
#pragma FB_COMPILER_MESSAGE("This file is not fit for public consumption")
|
2002-12-03 11:52:41 +01:00
|
|
|
// #error compiler halted, 'rogue' not found...
|
2001-05-23 15:26:42 +02:00
|
|
|
// TMN: Upon converting this file to C++, it has been noted
|
|
|
|
// that this code would never have worked because of (SEGV) bug(s),
|
|
|
|
// why I rather than trying to use it currently remove it from compilation.
|
|
|
|
|
|
|
|
|
2003-09-25 13:49:12 +02:00
|
|
|
static void align(const int);
|
2003-10-07 11:58:26 +02:00
|
|
|
static void asgn_from(const act*, const ref*, int);
|
|
|
|
static void asgn_sqlda_from(const ref*, int, TEXT*, int);
|
|
|
|
static void asgn_to(const act*, const ref*, int);
|
|
|
|
static void asgn_to_proc(const ref*, int);
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_at_end(const act*, int);
|
|
|
|
static void gen_based(const act*, int);
|
|
|
|
static void gen_blob_close(const act*, USHORT);
|
|
|
|
static void gen_blob_end(const act*, USHORT);
|
|
|
|
static void gen_blob_for(const act*, USHORT);
|
|
|
|
static void gen_blob_open(const act*, USHORT);
|
2003-09-28 23:36:05 +02:00
|
|
|
static void gen_blr(void*, SSHORT, const char*);
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_compile(const act*, int);
|
|
|
|
static void gen_create_database(const act*, int);
|
2003-10-07 11:58:26 +02:00
|
|
|
static int gen_cursor_close(const act*, const gpre_req*, int);
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_cursor_init(const act*, int);
|
2003-10-07 11:58:26 +02:00
|
|
|
static int gen_cursor_open(const act*, const gpre_req*, int);
|
2009-05-01 19:21:36 +02:00
|
|
|
static void gen_database(/*const act*,*/ int);
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_ddl(const act*, int);
|
|
|
|
static void gen_drop_database(const act*, int);
|
|
|
|
static void gen_dyn_close(const act*, int);
|
|
|
|
static void gen_dyn_declare(const act*, int);
|
|
|
|
static void gen_dyn_describe(const act*, int, bool);
|
|
|
|
static void gen_dyn_execute(const act*, int);
|
|
|
|
static void gen_dyn_fetch(const act*, int);
|
|
|
|
static void gen_dyn_immediate(const act*, int);
|
|
|
|
static void gen_dyn_insert(const act*, int);
|
|
|
|
static void gen_dyn_open(const act*, int);
|
|
|
|
static void gen_dyn_prepare(const act*, int);
|
|
|
|
static void gen_emodify(const act*, int);
|
|
|
|
static void gen_estore(const act*, int);
|
|
|
|
static void gen_endfor(const act*, int);
|
|
|
|
static void gen_erase(const act*, int);
|
|
|
|
static SSHORT gen_event_block(const act*);
|
|
|
|
static void gen_event_init(const act*, int);
|
|
|
|
static void gen_event_wait(const act*, int);
|
|
|
|
static void gen_fetch(const act*, int);
|
|
|
|
static void gen_finish(const act*, int);
|
|
|
|
static void gen_for(const act*, int);
|
2003-10-07 11:58:26 +02:00
|
|
|
static void gen_get_or_put_slice(const act*, const ref*, bool, int);
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_get_segment(const act*, int);
|
|
|
|
static void gen_loop(const act*, int);
|
2005-01-05 09:25:24 +01:00
|
|
|
static TEXT* gen_name(TEXT* const, const ref*, bool);
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_on_error(const act*, USHORT);
|
|
|
|
static void gen_procedure(const act*, int);
|
|
|
|
static void gen_put_segment(const act*, int);
|
2009-05-01 19:21:36 +02:00
|
|
|
static void gen_raw(const UCHAR*, int); //, int);
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_ready(const act*, int);
|
2004-01-28 08:50:41 +01:00
|
|
|
static void gen_receive(const act*, int, const gpre_port*);
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_release(const act*, int);
|
2003-10-07 11:58:26 +02:00
|
|
|
static void gen_request(const gpre_req*, int);
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_return_value(const act*, int);
|
|
|
|
static void gen_routine(const act*, int);
|
|
|
|
static void gen_s_end(const act*, int);
|
|
|
|
static void gen_s_fetch(const act*, int);
|
|
|
|
static void gen_s_start(const act*, int);
|
|
|
|
static void gen_segment(const act*, int);
|
|
|
|
static void gen_select(const act*, int);
|
2004-01-28 08:50:41 +01:00
|
|
|
static void gen_send(const act*, const gpre_port*, int);
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_slice(const act*, int);
|
2004-01-28 08:50:41 +01:00
|
|
|
static void gen_start(const act*, const gpre_port*, int);
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_store(const act*, int);
|
|
|
|
static void gen_t_start(const act*, int);
|
2008-12-29 11:26:36 +01:00
|
|
|
static void gen_tpb(const tpb*, int);
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_trans(const act*, int);
|
|
|
|
static void gen_update(const act*, int);
|
|
|
|
static void gen_variable(const act*, int);
|
2003-10-07 11:58:26 +02:00
|
|
|
static void gen_whenever(const swe*, int);
|
|
|
|
static void make_array_declaration(const ref*);
|
2005-01-05 09:25:24 +01:00
|
|
|
static TEXT* make_name(TEXT* const, const gpre_sym*);
|
2003-10-07 11:58:26 +02:00
|
|
|
static void make_ok_test(const act*, const gpre_req*, int);
|
2004-01-28 08:50:41 +01:00
|
|
|
static void make_port(const gpre_port*, int);
|
2009-01-14 09:22:32 +01:00
|
|
|
static void make_ready(const gpre_dbb*, const TEXT*, const TEXT*, USHORT, const gpre_req*);
|
2003-09-28 23:36:05 +02:00
|
|
|
static void printa(int, const char*, ...);
|
2003-10-07 11:58:26 +02:00
|
|
|
static const TEXT* request_trans(const act*, const gpre_req*);
|
2004-06-05 11:37:18 +02:00
|
|
|
static const TEXT* status_vector(const act*);
|
|
|
|
static void t_start_auto(const act*, const gpre_req*, const TEXT*, int);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-29 11:53:47 +01:00
|
|
|
static bool global_first_flag = false;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-15 00:22:32 +02:00
|
|
|
const int INDENT = 3;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-16 10:51:06 +02:00
|
|
|
const char* const SHORT_DCL = "integer16";
|
|
|
|
const char* const LONG_DCL = "integer32";
|
|
|
|
const char* const POINTER_DCL = "UNIV_PTR";
|
|
|
|
const char* const PACKED_ARRAY = "array";
|
|
|
|
const char* const OPEN_BRACKET = "[";
|
|
|
|
const char* const CLOSE_BRACKET = "]";
|
|
|
|
const char* const REF_PAR = "";
|
|
|
|
const char* const SIZEOF = "sizeof";
|
|
|
|
const char* const STATIC_STRING = "STATIC";
|
|
|
|
const char* const ISC_BADDRESS = "ADDR";
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-16 10:51:06 +02:00
|
|
|
const char* const FB_DP_VOLATILE = "";
|
|
|
|
const char* const GDS_EVENT_COUNTS = "GDS__EVENT_COUNTS";
|
|
|
|
const char* const GDS_EVENT_WAIT = "GDS__EVENT_WAIT";
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-09-25 13:49:12 +02:00
|
|
|
static inline void begin(const int column)
|
2003-09-16 16:01:56 +02:00
|
|
|
{
|
|
|
|
printa(column, "begin");
|
|
|
|
}
|
|
|
|
|
2003-09-25 13:49:12 +02:00
|
|
|
static inline void endp(const int column)
|
2003-09-16 16:01:56 +02:00
|
|
|
{
|
|
|
|
printa(column, "end");
|
|
|
|
}
|
|
|
|
|
2003-09-25 13:49:12 +02:00
|
|
|
static inline void ends(const int column)
|
2003-09-16 16:01:56 +02:00
|
|
|
{
|
|
|
|
printa(column, "end;");
|
|
|
|
}
|
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static inline void set_sqlcode(const act* action, const int column)
|
2003-09-12 18:35:40 +02:00
|
|
|
{
|
|
|
|
if (action->act_flags & ACT_sql)
|
2003-09-25 13:49:12 +02:00
|
|
|
printa(column, "SQLCODE := gds__sqlcode (gds__status);");
|
2003-09-12 18:35:40 +02:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Code generator for Domain Pascal. Not to be confused with
|
|
|
|
// the language "Pascal".
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
void PAS_action(const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
// Put leading braces where required
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
switch (action->act_type)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
case ACT_alter_database:
|
|
|
|
case ACT_alter_domain:
|
|
|
|
case ACT_alter_table:
|
|
|
|
case ACT_alter_index:
|
|
|
|
case ACT_blob_close:
|
|
|
|
case ACT_blob_create:
|
|
|
|
case ACT_blob_for:
|
|
|
|
case ACT_blob_open:
|
|
|
|
case ACT_close:
|
|
|
|
case ACT_commit:
|
|
|
|
case ACT_commit_retain_context:
|
|
|
|
case ACT_create_database:
|
|
|
|
case ACT_create_domain:
|
|
|
|
case ACT_create_generator:
|
|
|
|
case ACT_create_index:
|
|
|
|
case ACT_create_shadow:
|
|
|
|
case ACT_create_table:
|
|
|
|
case ACT_create_view:
|
|
|
|
case ACT_declare_filter:
|
|
|
|
case ACT_declare_udf:
|
|
|
|
case ACT_disconnect:
|
|
|
|
case ACT_drop_database:
|
|
|
|
case ACT_drop_domain:
|
|
|
|
case ACT_drop_filter:
|
|
|
|
case ACT_drop_index:
|
|
|
|
case ACT_drop_shadow:
|
|
|
|
case ACT_drop_table:
|
|
|
|
case ACT_drop_udf:
|
|
|
|
case ACT_drop_view:
|
|
|
|
case ACT_dyn_close:
|
|
|
|
case ACT_dyn_cursor:
|
|
|
|
case ACT_dyn_describe:
|
|
|
|
case ACT_dyn_describe_input:
|
|
|
|
case ACT_dyn_execute:
|
|
|
|
case ACT_dyn_fetch:
|
|
|
|
case ACT_dyn_grant:
|
|
|
|
case ACT_dyn_immediate:
|
|
|
|
case ACT_dyn_insert:
|
|
|
|
case ACT_dyn_open:
|
|
|
|
case ACT_dyn_prepare:
|
|
|
|
case ACT_dyn_revoke:
|
|
|
|
case ACT_fetch:
|
|
|
|
case ACT_finish:
|
|
|
|
case ACT_for:
|
|
|
|
case ACT_get_segment:
|
|
|
|
case ACT_get_slice:
|
|
|
|
case ACT_insert:
|
|
|
|
case ACT_loop:
|
|
|
|
case ACT_modify:
|
|
|
|
case ACT_open:
|
|
|
|
case ACT_prepare:
|
|
|
|
case ACT_procedure:
|
|
|
|
case ACT_put_slice:
|
|
|
|
case ACT_ready:
|
|
|
|
case ACT_release:
|
|
|
|
case ACT_rfinish:
|
|
|
|
case ACT_rollback:
|
2008-01-16 08:15:01 +01:00
|
|
|
case ACT_rollback_retain_context:
|
2001-05-23 15:26:42 +02:00
|
|
|
case ACT_s_fetch:
|
|
|
|
case ACT_s_start:
|
|
|
|
case ACT_select:
|
|
|
|
case ACT_start:
|
|
|
|
case ACT_store:
|
|
|
|
case ACT_update:
|
|
|
|
case ACT_statistics:
|
2003-09-16 16:01:56 +02:00
|
|
|
begin(column);
|
2004-11-08 04:33:26 +01:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
switch (action->act_type)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
case ACT_alter_domain:
|
|
|
|
case ACT_create_domain:
|
|
|
|
case ACT_create_generator:
|
|
|
|
case ACT_create_shadow:
|
|
|
|
case ACT_declare_filter:
|
|
|
|
case ACT_declare_udf:
|
|
|
|
case ACT_drop_domain:
|
|
|
|
case ACT_drop_filter:
|
|
|
|
case ACT_drop_shadow:
|
|
|
|
case ACT_drop_udf:
|
|
|
|
case ACT_statistics:
|
|
|
|
case ACT_alter_index:
|
|
|
|
case ACT_alter_table:
|
|
|
|
gen_ddl(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_at_end:
|
|
|
|
gen_at_end(action, column);
|
|
|
|
return;
|
|
|
|
case ACT_b_declare:
|
2009-05-01 19:21:36 +02:00
|
|
|
gen_database(/*action,*/ column);
|
2001-05-23 15:26:42 +02:00
|
|
|
gen_routine(action, column);
|
|
|
|
return;
|
|
|
|
case ACT_basedon:
|
|
|
|
gen_based(action, column);
|
|
|
|
return;
|
|
|
|
case ACT_blob_cancel:
|
|
|
|
gen_blob_close(action, column);
|
|
|
|
return;
|
|
|
|
case ACT_blob_close:
|
|
|
|
gen_blob_close(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_blob_create:
|
|
|
|
gen_blob_open(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_blob_for:
|
|
|
|
gen_blob_for(action, column);
|
|
|
|
return;
|
|
|
|
case ACT_blob_handle:
|
|
|
|
gen_segment(action, column);
|
|
|
|
return;
|
|
|
|
case ACT_blob_open:
|
|
|
|
gen_blob_open(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_close:
|
|
|
|
gen_s_end(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_commit:
|
|
|
|
gen_trans(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_commit_retain_context:
|
|
|
|
gen_trans(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_create_database:
|
|
|
|
gen_create_database(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_create_index:
|
|
|
|
gen_ddl(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_create_table:
|
|
|
|
gen_ddl(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_create_view:
|
|
|
|
gen_ddl(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_cursor:
|
|
|
|
gen_cursor_init(action, column);
|
|
|
|
return;
|
|
|
|
case ACT_database:
|
2009-05-01 19:21:36 +02:00
|
|
|
gen_database(/*action,*/ column);
|
2001-05-23 15:26:42 +02:00
|
|
|
return;
|
|
|
|
case ACT_disconnect:
|
|
|
|
gen_finish(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_drop_database:
|
|
|
|
gen_drop_database(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_drop_index:
|
|
|
|
gen_ddl(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_drop_table:
|
|
|
|
gen_ddl(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_drop_view:
|
|
|
|
gen_ddl(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_dyn_close:
|
|
|
|
gen_dyn_close(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_dyn_cursor:
|
|
|
|
gen_dyn_declare(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_dyn_describe:
|
2003-09-10 21:48:53 +02:00
|
|
|
gen_dyn_describe(action, column, false);
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
case ACT_dyn_describe_input:
|
2003-09-10 21:48:53 +02:00
|
|
|
gen_dyn_describe(action, column, true);
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
case ACT_dyn_execute:
|
|
|
|
gen_dyn_execute(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_dyn_fetch:
|
|
|
|
gen_dyn_fetch(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_dyn_grant:
|
|
|
|
gen_ddl(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_dyn_immediate:
|
|
|
|
gen_dyn_immediate(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_dyn_insert:
|
|
|
|
gen_dyn_insert(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_dyn_open:
|
|
|
|
gen_dyn_open(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_dyn_prepare:
|
|
|
|
gen_dyn_prepare(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_dyn_revoke:
|
|
|
|
gen_ddl(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_endblob:
|
|
|
|
gen_blob_end(action, column);
|
|
|
|
return;
|
2008-12-27 08:00:40 +01:00
|
|
|
case ACT_enderror:
|
|
|
|
column += INDENT;
|
|
|
|
endp(column);
|
|
|
|
column -= INDENT;
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
case ACT_endfor:
|
|
|
|
gen_endfor(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_endmodify:
|
|
|
|
gen_emodify(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_endstore:
|
|
|
|
gen_estore(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_erase:
|
|
|
|
gen_erase(action, column);
|
|
|
|
return;
|
|
|
|
case ACT_event_init:
|
|
|
|
gen_event_init(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_event_wait:
|
|
|
|
gen_event_wait(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_fetch:
|
|
|
|
gen_fetch(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_finish:
|
|
|
|
gen_finish(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_for:
|
|
|
|
gen_for(action, column);
|
|
|
|
return;
|
|
|
|
case ACT_get_segment:
|
|
|
|
gen_get_segment(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_get_slice:
|
|
|
|
gen_slice(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_hctef:
|
2003-09-16 16:01:56 +02:00
|
|
|
ends(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
case ACT_insert:
|
|
|
|
gen_s_start(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_loop:
|
|
|
|
gen_loop(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_on_error:
|
|
|
|
gen_on_error(action, column);
|
|
|
|
return;
|
|
|
|
case ACT_open:
|
|
|
|
gen_s_start(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_ready:
|
|
|
|
gen_ready(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_put_segment:
|
|
|
|
gen_put_segment(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_put_slice:
|
|
|
|
gen_slice(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_prepare:
|
|
|
|
gen_trans(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_procedure:
|
|
|
|
gen_procedure(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_release:
|
|
|
|
gen_release(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_rfinish:
|
|
|
|
gen_finish(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_rollback:
|
|
|
|
gen_trans(action, column);
|
|
|
|
break;
|
2008-01-16 08:15:01 +01:00
|
|
|
case ACT_rollback_retain_context:
|
|
|
|
gen_trans(action, column);
|
|
|
|
break;
|
2001-05-23 15:26:42 +02:00
|
|
|
case ACT_routine:
|
|
|
|
gen_routine(action, column);
|
|
|
|
return;
|
|
|
|
case ACT_s_end:
|
|
|
|
gen_s_end(action, column);
|
|
|
|
return;
|
|
|
|
case ACT_s_fetch:
|
|
|
|
gen_s_fetch(action, column);
|
|
|
|
return;
|
|
|
|
case ACT_s_start:
|
|
|
|
gen_s_start(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_segment:
|
|
|
|
gen_segment(action, column);
|
|
|
|
return;
|
|
|
|
case ACT_segment_length:
|
|
|
|
gen_segment(action, column);
|
|
|
|
return;
|
|
|
|
case ACT_sql_dialect:
|
2008-12-27 11:04:31 +01:00
|
|
|
gpreGlob.sw_sql_dialect = ((set_dialect*) action->act_object)->sdt_dialect;
|
2001-05-23 15:26:42 +02:00
|
|
|
return;
|
|
|
|
case ACT_select:
|
|
|
|
gen_select(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_start:
|
|
|
|
gen_t_start(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_store:
|
|
|
|
gen_store(action, column);
|
|
|
|
return;
|
|
|
|
case ACT_store2:
|
|
|
|
gen_return_value(action, column);
|
|
|
|
return;
|
|
|
|
case ACT_update:
|
|
|
|
gen_update(action, column);
|
|
|
|
break;
|
|
|
|
case ACT_variable:
|
|
|
|
gen_variable(action, column);
|
|
|
|
return;
|
|
|
|
default:
|
|
|
|
return;
|
2004-11-08 04:33:26 +01:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
// Put in a trailing brace for those actions still with us
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (action->act_flags & ACT_sql)
|
|
|
|
gen_whenever(action->act_whenever, column);
|
|
|
|
|
|
|
|
if (action->act_error)
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, ";");
|
2001-05-23 15:26:42 +02:00
|
|
|
else
|
2003-09-16 16:01:56 +02:00
|
|
|
endp(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Align output to a specific column for output.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-09-25 13:49:12 +02:00
|
|
|
static void align(const int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2004-05-24 19:13:38 +02:00
|
|
|
putc('\n', gpreGlob.out_file);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (column < 0)
|
|
|
|
return;
|
|
|
|
|
2009-06-27 08:23:36 +02:00
|
|
|
for (int i = column / 8; i; --i)
|
2004-05-24 19:13:38 +02:00
|
|
|
putc('\t', gpreGlob.out_file);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-06-27 08:23:36 +02:00
|
|
|
for (int i = column % 8; i; --i)
|
2004-05-24 19:13:38 +02:00
|
|
|
putc(' ', gpreGlob.out_file);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Build an assignment from a host language variable to
|
|
|
|
// a port variable.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-07 11:58:26 +02:00
|
|
|
static void asgn_from( const act* action, const ref* reference, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2005-01-03 09:07:41 +01:00
|
|
|
TEXT name[MAX_REF_SIZE], variable[MAX_REF_SIZE], temp[MAX_REF_SIZE];
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
for (; reference; reference = reference->ref_next)
|
|
|
|
{
|
2003-10-29 11:53:47 +01:00
|
|
|
const gpre_fld* field = reference->ref_field;
|
2001-05-23 15:26:42 +02:00
|
|
|
if (field->fld_array_info)
|
2009-06-28 12:26:25 +02:00
|
|
|
if (!(reference->ref_flags & REF_array_elem))
|
|
|
|
{
|
2008-12-29 11:26:36 +01:00
|
|
|
printa(column, "%s := gds__blob_null;\n", gen_name(name, reference, true));
|
2003-09-10 21:48:53 +02:00
|
|
|
gen_get_or_put_slice(action, reference, false, column);
|
2001-05-23 15:26:42 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!reference->ref_source && !reference->ref_value)
|
|
|
|
continue;
|
|
|
|
align(column);
|
2003-09-10 21:48:53 +02:00
|
|
|
gen_name(variable, reference, true);
|
2003-10-29 11:53:47 +01:00
|
|
|
const TEXT* value;
|
2001-05-23 15:26:42 +02:00
|
|
|
if (reference->ref_source)
|
2003-09-10 21:48:53 +02:00
|
|
|
value = gen_name(temp, reference->ref_source, true);
|
2001-05-23 15:26:42 +02:00
|
|
|
else
|
|
|
|
value = reference->ref_value;
|
|
|
|
if (reference->ref_value && (reference->ref_flags & REF_array_elem))
|
|
|
|
field = field->fld_array;
|
|
|
|
if (!field || (field->fld_flags & FLD_text))
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "gds__ftof (%s%s, %s (%s), %s%s, %d);",
|
2008-12-29 11:26:36 +01:00
|
|
|
REF_PAR, value, SIZEOF, value, REF_PAR, variable, field->fld_length);
|
2004-04-29 01:29:25 +02:00
|
|
|
else if (!reference->ref_master || (reference->ref_flags & REF_literal))
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "%s := %s;", variable, value);
|
2009-06-28 12:26:25 +02:00
|
|
|
else
|
|
|
|
{
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "if %s < 0 then", value);
|
2001-05-23 15:26:42 +02:00
|
|
|
align(column + 4);
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "%s := -1", variable);
|
2001-05-23 15:26:42 +02:00
|
|
|
align(column);
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "else");
|
2001-05-23 15:26:42 +02:00
|
|
|
align(column + 4);
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "%s := 0;", variable);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Build an assignment from a host language variable to
|
|
|
|
// a sqlda variable.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-29 11:53:47 +01:00
|
|
|
static void asgn_sqlda_from( const ref* reference, int number, TEXT* string, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2005-01-03 09:07:41 +01:00
|
|
|
TEXT temp[MAX_REF_SIZE];
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-06-28 12:26:25 +02:00
|
|
|
for (; reference; reference = reference->ref_next)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
align(column);
|
2003-10-29 11:53:47 +01:00
|
|
|
const TEXT* value;
|
2001-05-23 15:26:42 +02:00
|
|
|
if (reference->ref_source)
|
2003-09-10 21:48:53 +02:00
|
|
|
value = gen_name(temp, reference->ref_source, true);
|
2001-05-23 15:26:42 +02:00
|
|
|
else
|
|
|
|
value = reference->ref_value;
|
2008-12-29 11:26:36 +01:00
|
|
|
fprintf(gpreGlob.out_file, "gds__to_sqlda (gds__sqlda, %d, %s, %s(%s), %s);",
|
|
|
|
number, SIZEOF, value, value, string);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Build an assignment to a host language variable from
|
|
|
|
// a port variable.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-07 11:58:26 +02:00
|
|
|
static void asgn_to(const act* action, const ref* reference, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2005-01-03 09:07:41 +01:00
|
|
|
TEXT s[MAX_REF_SIZE];
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-07 11:58:26 +02:00
|
|
|
ref* source = reference->ref_friend;
|
2003-10-29 11:53:47 +01:00
|
|
|
const gpre_fld* field = source->ref_field;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-06-28 12:26:25 +02:00
|
|
|
if (field && field->fld_array_info)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
source->ref_value = reference->ref_value;
|
2003-09-10 21:48:53 +02:00
|
|
|
gen_get_or_put_slice(action, source, true, column);
|
2001-05-23 15:26:42 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (field && (field->fld_flags & FLD_text))
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "gds__ftof (%s%s, %d, %s%s, %s (%s));",
|
2008-12-29 11:26:36 +01:00
|
|
|
REF_PAR, gen_name(s, source, true), field->fld_length,
|
|
|
|
REF_PAR, reference->ref_value, SIZEOF, reference->ref_value);
|
2001-05-23 15:26:42 +02:00
|
|
|
else
|
2008-12-29 11:26:36 +01:00
|
|
|
fprintf(gpreGlob.out_file, "%s := %s;", reference->ref_value, gen_name(s, source, true));
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
// Pick up NULL value if one is there
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (reference = reference->ref_null)
|
2008-12-29 11:26:36 +01:00
|
|
|
fprintf(gpreGlob.out_file, "%s := %s;", reference->ref_value, gen_name(s, reference, true));
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Build an assignment to a host language variable from
|
|
|
|
// a port variable.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-07 11:58:26 +02:00
|
|
|
static void asgn_to_proc(const ref* reference, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2005-01-03 09:07:41 +01:00
|
|
|
TEXT s[MAX_REF_SIZE];
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
for (; reference; reference = reference->ref_next)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
if (!reference->ref_value)
|
|
|
|
continue;
|
2003-10-29 11:53:47 +01:00
|
|
|
const gpre_fld* field = reference->ref_field;
|
2003-09-10 21:48:53 +02:00
|
|
|
gen_name(s, reference, true);
|
2001-05-23 15:26:42 +02:00
|
|
|
align(column);
|
|
|
|
if (field && (field->fld_flags & FLD_text))
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "gds__ftof (%s%s, %d, %s%s, %s (%s));",
|
2008-12-29 11:26:36 +01:00
|
|
|
REF_PAR, gen_name(s, reference, true), field->fld_length,
|
|
|
|
REF_PAR, reference->ref_value, SIZEOF, reference->ref_value);
|
2001-05-23 15:26:42 +02:00
|
|
|
else
|
2008-12-29 11:26:36 +01:00
|
|
|
fprintf(gpreGlob.out_file, "%s := %s;", reference->ref_value, gen_name(s, reference, true));
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate code for AT END clause of FETCH.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_at_end( const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2005-01-03 09:07:41 +01:00
|
|
|
TEXT s[MAX_REF_SIZE];
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-29 11:53:47 +01:00
|
|
|
const gpre_req* request = action->act_request;
|
2008-12-29 11:26:36 +01:00
|
|
|
printa(column, "if %s = 0 then begin", gen_name(s, request->req_eof, true));
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Substitute for a BASED ON <field name> clause.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_based( const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
SSHORT datatype;
|
|
|
|
|
|
|
|
align(column);
|
2004-01-28 08:50:41 +01:00
|
|
|
bas* based_on = (bas*) action->act_object;
|
2008-12-29 11:26:36 +01:00
|
|
|
gpre_fld* field = based_on->bas_field;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
if (based_on->bas_flags & BAS_segment)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
datatype = dtype_text;
|
2008-12-29 11:26:36 +01:00
|
|
|
SLONG length = field->fld_seg_length;
|
|
|
|
if (!length)
|
2001-05-23 15:26:42 +02:00
|
|
|
length = 256;
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "%s [1..%"SLONGFORMAT"] of ", PACKED_ARRAY, length);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
2009-04-22 13:44:39 +02:00
|
|
|
else if (field->fld_array_info)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
datatype = field->fld_array_info->ary_dtype;
|
|
|
|
if (datatype <= dtype_varying)
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "%s [", PACKED_ARRAY);
|
2001-05-23 15:26:42 +02:00
|
|
|
else
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "array [");
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
for (dim* dimension = field->fld_array_info->ary_dimension; dimension;
|
|
|
|
dimension = dimension->dim_next)
|
2004-12-24 09:52:39 +01:00
|
|
|
{
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "%"SLONGFORMAT"..%"SLONGFORMAT, dimension->dim_lower,
|
2001-05-23 15:26:42 +02:00
|
|
|
dimension->dim_upper);
|
|
|
|
if (dimension->dim_next)
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, ", ");
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
if (datatype <= dtype_varying)
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, ", 1..%d", field->fld_array->fld_length);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "] of ");
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
2009-04-22 13:44:39 +02:00
|
|
|
else
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
datatype = field->fld_dtype;
|
|
|
|
if (datatype <= dtype_varying)
|
2008-12-29 11:26:36 +01:00
|
|
|
fprintf(gpreGlob.out_file, "%s [1..%d] of ", PACKED_ARRAY, field->fld_length);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
TEXT s[64];
|
|
|
|
|
2009-01-14 09:22:32 +01:00
|
|
|
switch (datatype)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
case dtype_short:
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "%s;", SHORT_DCL);
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case dtype_long:
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "%s;", LONG_DCL);
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case dtype_date:
|
|
|
|
case dtype_blob:
|
|
|
|
case dtype_quad:
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "gds__quad;");
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case dtype_text:
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "char;");
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
2003-10-15 00:22:32 +02:00
|
|
|
case dtype_real:
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "real;");
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case dtype_double:
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "double;");
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
sprintf(s, "datatype %d unknown\n", field->fld_dtype);
|
|
|
|
CPR_error(s);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Make a blob FOR loop.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_blob_close( const act* action, USHORT column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
if (action->act_error || (action->act_flags & ACT_sql))
|
2003-09-16 16:01:56 +02:00
|
|
|
begin(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-29 11:53:47 +01:00
|
|
|
const blb* blob;
|
2009-06-28 12:26:25 +02:00
|
|
|
if (action->act_flags & ACT_sql)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
column = gen_cursor_close(action, action->act_request, column);
|
2004-01-28 08:50:41 +01:00
|
|
|
blob = (blb*) action->act_request->req_blobs;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
else
|
2004-01-28 08:50:41 +01:00
|
|
|
blob = (blb*) action->act_object;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-27 08:00:40 +01:00
|
|
|
const TEXT* command = (action->act_type == ACT_blob_cancel) ? "CANCEL" : "CLOSE";
|
|
|
|
printa(column, "GDS__%s_BLOB (%s, gds__%d);", command, status_vector(action), blob->blb_ident);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-06-28 12:26:25 +02:00
|
|
|
if (action->act_flags & ACT_sql)
|
|
|
|
{
|
2003-09-16 16:01:56 +02:00
|
|
|
endp(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
column -= INDENT;
|
2003-09-16 16:01:56 +02:00
|
|
|
ends(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
column -= INDENT;
|
2003-09-12 18:35:40 +02:00
|
|
|
set_sqlcode(action, column);
|
2003-09-16 16:01:56 +02:00
|
|
|
endp(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// End a blob FOR loop.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_blob_end(const act* action, USHORT column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2004-01-28 08:50:41 +01:00
|
|
|
const blb* blob = (blb*) action->act_object;
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(column + INDENT, "end;");
|
|
|
|
if (action->act_error)
|
2008-12-29 11:26:36 +01:00
|
|
|
printa(column, "GDS__CLOSE_BLOB (gds__status2, gds__%d);", blob->blb_ident);
|
2001-05-23 15:26:42 +02:00
|
|
|
else
|
2008-12-29 11:26:36 +01:00
|
|
|
printa(column, "GDS__CLOSE_BLOB (%s, gds__%d);", status_vector(0), blob->blb_ident);
|
2001-05-23 15:26:42 +02:00
|
|
|
if (action->act_error)
|
2003-09-16 16:01:56 +02:00
|
|
|
ends(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
else
|
2003-09-16 16:01:56 +02:00
|
|
|
endp(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Make a blob FOR loop.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_blob_for( const act* action, USHORT column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
|
|
|
|
gen_blob_open(action, column);
|
|
|
|
if (action->act_error)
|
|
|
|
printa(column, "if (gds__status[2] = 0) then begin");
|
|
|
|
printa(column, "while (true) do begin");
|
|
|
|
gen_get_segment(action, column + INDENT);
|
2008-12-29 11:26:36 +01:00
|
|
|
printa(column + INDENT, "if ((gds__status[2] <> 0) and (gds__status[2] <> gds__segment)) then");
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(column + 2 * INDENT, "exit;");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate the call to open (or create) a blob.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_blob_open( const act* action, USHORT column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-29 11:53:47 +01:00
|
|
|
const TEXT* pattern1 =
|
|
|
|
"GDS__%IFCREATE%ELOPEN%EN_BLOB2 (%V1, %RF%DH, %RF%RT, %RF%BH, %RF%FR, %N1, %RF%I1);";
|
|
|
|
const TEXT* pattern2 =
|
2001-05-23 15:26:42 +02:00
|
|
|
"GDS__%IFCREATE%ELOPEN%EN_BLOB2 (%V1, %RF%DH, %RF%RT, %RF%BH, %RF%FR, 0, 0);";
|
|
|
|
|
2009-06-28 12:26:25 +02:00
|
|
|
if (gpreGlob.sw_auto && (action->act_flags & ACT_sql))
|
|
|
|
{
|
2008-12-29 11:26:36 +01:00
|
|
|
t_start_auto(action, action->act_request, status_vector(action), column);
|
|
|
|
printa(column, "if %s <> nil then", request_trans(action, action->act_request));
|
2001-05-23 15:26:42 +02:00
|
|
|
column += INDENT;
|
|
|
|
}
|
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
if ((action->act_error && (action->act_type != ACT_blob_for)) || action->act_flags & ACT_sql)
|
2008-06-05 13:02:42 +02:00
|
|
|
{
|
2003-09-16 16:01:56 +02:00
|
|
|
begin(column);
|
2008-06-05 13:02:42 +02:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2005-01-03 09:07:41 +01:00
|
|
|
TEXT s[MAX_REF_SIZE];
|
2003-10-29 11:53:47 +01:00
|
|
|
const blb* blob;
|
|
|
|
const ref* reference;
|
2009-06-28 12:26:25 +02:00
|
|
|
if (action->act_flags & ACT_sql)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
column = gen_cursor_open(action, action->act_request, column);
|
2004-01-28 08:50:41 +01:00
|
|
|
blob = (blb*) action->act_request->req_blobs;
|
|
|
|
reference = ((open_cursor*) action->act_object)->opn_using;
|
2003-09-10 21:48:53 +02:00
|
|
|
gen_name(s, reference, true);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
2009-06-28 12:26:25 +02:00
|
|
|
else
|
|
|
|
{
|
2004-01-28 08:50:41 +01:00
|
|
|
blob = (blb*) action->act_object;
|
2001-05-23 15:26:42 +02:00
|
|
|
reference = blob->blb_reference;
|
|
|
|
}
|
|
|
|
|
2003-10-29 11:53:47 +01:00
|
|
|
PAT args;
|
2003-09-11 04:13:46 +02:00
|
|
|
args.pat_condition = (action->act_type == ACT_blob_create); // open or create blob
|
|
|
|
args.pat_vector1 = status_vector(action); // status vector
|
2009-04-22 13:44:39 +02:00
|
|
|
args.pat_database = blob->blb_request->req_database; // database handle
|
|
|
|
args.pat_request = blob->blb_request; // transaction handle
|
|
|
|
args.pat_blob = blob; // blob handle
|
2003-09-11 04:13:46 +02:00
|
|
|
args.pat_reference = reference; // blob identifier
|
2001-05-23 15:26:42 +02:00
|
|
|
args.pat_ident1 = blob->blb_bpb_ident;
|
|
|
|
|
|
|
|
if ((action->act_flags & ACT_sql) && action->act_type == ACT_blob_open)
|
|
|
|
printa(column, "%s := %s;", s, reference->ref_value);
|
|
|
|
|
|
|
|
if (args.pat_value1 = blob->blb_bpb_length)
|
|
|
|
PATTERN_expand(column, pattern1, &args);
|
|
|
|
else
|
|
|
|
PATTERN_expand(column, pattern2, &args);
|
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
if (action->act_flags & ACT_sql)
|
|
|
|
{
|
2003-09-16 16:01:56 +02:00
|
|
|
endp(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
column -= INDENT;
|
2003-09-16 16:01:56 +02:00
|
|
|
endp(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
column -= INDENT;
|
2003-09-16 16:01:56 +02:00
|
|
|
ends(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
column -= INDENT;
|
2009-06-28 12:26:25 +02:00
|
|
|
if (gpreGlob.sw_auto)
|
|
|
|
{
|
2003-09-16 16:01:56 +02:00
|
|
|
endp(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
column -= INDENT;
|
|
|
|
}
|
2003-09-12 18:35:40 +02:00
|
|
|
set_sqlcode(action, column);
|
2009-06-28 12:26:25 +02:00
|
|
|
if (action->act_type == ACT_blob_create)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(column, "if SQLCODE = 0 then");
|
|
|
|
align(column + INDENT);
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "%s := %s;", reference->ref_value, s);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Callback routine for BLR pretty printer.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-05-01 19:21:36 +02:00
|
|
|
static void gen_blr(void* /*user_arg*/, SSHORT /*offset*/, const char* string)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-09-10 21:48:53 +02:00
|
|
|
bool first_line = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-29 11:53:47 +01:00
|
|
|
int indent = 2 * INDENT;
|
|
|
|
const char* p = string;
|
2009-06-28 12:26:25 +02:00
|
|
|
while (*p == ' ')
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
p++;
|
|
|
|
indent++;
|
|
|
|
}
|
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
// Limit indentation to 192 characters
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
indent = MIN(indent, 192);
|
|
|
|
|
2003-10-29 11:53:47 +01:00
|
|
|
int length = strlen(p);
|
2009-04-22 13:44:39 +02:00
|
|
|
while (length + indent > 255)
|
|
|
|
{
|
|
|
|
// if we did not find somewhere to break between the 200th and 256th character
|
|
|
|
// just print out 256 characters
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-29 11:53:47 +01:00
|
|
|
const char* q = p;
|
2009-06-28 12:26:25 +02:00
|
|
|
for (bool open_quote = false; (q - p + indent) < 255; q++)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
if ((q - p + indent) > 220 && *q == ',' && !open_quote)
|
|
|
|
break;
|
|
|
|
if (*q == '\'' && *(q - 1) != '\\')
|
|
|
|
open_quote = !open_quote;
|
|
|
|
}
|
2003-09-28 23:36:05 +02:00
|
|
|
q++;
|
|
|
|
char buffer[256];
|
2003-09-29 14:43:14 +02:00
|
|
|
strncpy(buffer, p, q - p);
|
|
|
|
buffer[q - p] = 0;
|
2003-09-28 23:36:05 +02:00
|
|
|
printa(indent, buffer);
|
2001-05-23 15:26:42 +02:00
|
|
|
length = length - (q - p);
|
|
|
|
p = q;
|
2009-06-28 12:26:25 +02:00
|
|
|
if (first_line)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
indent = MIN(indent + INDENT, 192);
|
2003-09-10 21:48:53 +02:00
|
|
|
first_line = false;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
printa(indent, p);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate text to compile a request.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_compile( const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-29 11:53:47 +01:00
|
|
|
const gpre_req* request = action->act_request;
|
2009-01-14 09:22:32 +01:00
|
|
|
const gpre_dbb* db = request->req_database;
|
2004-01-28 08:50:41 +01:00
|
|
|
const gpre_sym* symbol = db->dbb_name;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
if (gpreGlob.sw_auto)
|
|
|
|
{
|
2003-10-29 11:53:47 +01:00
|
|
|
const TEXT* filename = db->dbb_runtime;
|
2009-06-28 12:26:25 +02:00
|
|
|
if (filename || !(db->dbb_flags & DBB_sqlca))
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(column, "if %s = nil then", symbol->sym_string);
|
2008-12-29 11:26:36 +01:00
|
|
|
make_ready(db, filename, status_vector(action), column + INDENT, 0);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
if (action->act_error || (action->act_flags & ACT_sql))
|
|
|
|
printa(column, "if (%s = nil) and (%s <> nil) then",
|
|
|
|
request_trans(action, request), symbol->sym_string);
|
|
|
|
else
|
2008-12-29 11:26:36 +01:00
|
|
|
printa(column, "if %s = nil then", request_trans(action, request));
|
2001-05-23 15:26:42 +02:00
|
|
|
t_start_auto(action, request, status_vector(action), column + INDENT);
|
|
|
|
}
|
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
if ((action->act_error || (action->act_flags & ACT_sql)) && gpreGlob.sw_auto)
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(column, "if (%s = nil) and (%s <> nil) then",
|
|
|
|
request->req_handle, request_trans(action, request));
|
|
|
|
else
|
|
|
|
printa(column, "if %s = nil then", request->req_handle);
|
|
|
|
|
|
|
|
align(column + INDENT);
|
2008-12-29 11:26:36 +01:00
|
|
|
fprintf(gpreGlob.out_file, "GDS__COMPILE_REQUEST%s (%s, %s, %s, %d, gds__%d);\n",
|
2001-05-23 15:26:42 +02:00
|
|
|
(request->req_flags & REQ_exp_hand) ? "" : "2",
|
|
|
|
status_vector(action), symbol->sym_string, request->req_handle,
|
|
|
|
request->req_length, request->req_ident);
|
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
// If blobs are present, zero out all of the blob handles. After this
|
|
|
|
// point, the handles are the user's responsibility
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-29 11:53:47 +01:00
|
|
|
for (const blb* blob = request->req_blobs; blob; blob = blob->blb_next)
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(column - INDENT, "gds__%d := nil;", blob->blb_ident);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate a call to create a database.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_create_database( const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2008-12-29 11:26:36 +01:00
|
|
|
const gpre_req* request = ((mdbb*) action->act_object)->mdbb_dpb_request;
|
2009-04-22 13:44:39 +02:00
|
|
|
const gpre_dbb* db = (gpre_dbb*) request->req_database;
|
2001-05-23 15:26:42 +02:00
|
|
|
align(column);
|
|
|
|
|
|
|
|
if (request->req_length)
|
2008-12-29 11:26:36 +01:00
|
|
|
fprintf(gpreGlob.out_file, "GDS__CREATE_DATABASE (%s, %d, '%s', %s, %d, gds__%d, 0);",
|
2003-09-10 21:48:53 +02:00
|
|
|
status_vector(action), strlen(db->dbb_filename),
|
|
|
|
db->dbb_filename, db->dbb_name->sym_string,
|
2001-05-23 15:26:42 +02:00
|
|
|
request->req_length, request->req_ident);
|
|
|
|
else
|
2008-12-29 11:26:36 +01:00
|
|
|
fprintf(gpreGlob.out_file, "GDS__CREATE_DATABASE (%s, %d, '%s', %s, 0, 0, 0);",
|
2003-09-10 21:48:53 +02:00
|
|
|
status_vector(action), strlen(db->dbb_filename),
|
2001-05-23 15:26:42 +02:00
|
|
|
db->dbb_filename, db->dbb_name->sym_string);
|
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
const bool save_sw_auto = gpreGlob.sw_auto;
|
2004-05-24 19:13:38 +02:00
|
|
|
gpreGlob.sw_auto = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(column, "if (gds__status [2] = 0) then");
|
2003-09-16 16:01:56 +02:00
|
|
|
begin(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
gen_ddl(action, column);
|
2003-09-16 16:01:56 +02:00
|
|
|
ends(column);
|
2004-05-24 19:13:38 +02:00
|
|
|
gpreGlob.sw_auto = save_sw_auto;
|
2001-05-23 15:26:42 +02:00
|
|
|
column -= INDENT;
|
2003-09-12 18:35:40 +02:00
|
|
|
set_sqlcode(action, column);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate substitution text for END_STREAM.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-07 11:58:26 +02:00
|
|
|
static int gen_cursor_close( const act* action, const gpre_req* request, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2004-06-05 11:37:18 +02:00
|
|
|
const TEXT* pattern1 = "if %RIs <> nil then";
|
|
|
|
const TEXT* pattern2 = "isc_dsql_free_statement (%V1, %RF%RIs, %N1);";
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
PAT args;
|
2001-05-23 15:26:42 +02:00
|
|
|
args.pat_request = request;
|
|
|
|
args.pat_vector1 = status_vector(action);
|
|
|
|
args.pat_value1 = 1;
|
|
|
|
|
|
|
|
PATTERN_expand(column, pattern1, &args);
|
|
|
|
column += INDENT;
|
2003-09-16 16:01:56 +02:00
|
|
|
begin(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
PATTERN_expand(column, pattern2, &args);
|
|
|
|
printa(column, "if (gds__status[2] = 0) then");
|
|
|
|
column += INDENT;
|
2003-09-16 16:01:56 +02:00
|
|
|
begin(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
return column;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate text to initialize a cursor.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_cursor_init( const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
// If blobs are present, zero out all of the blob handles. After this
|
|
|
|
// point, the handles are the user's responsibility
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
if (action->act_request->req_flags & (REQ_sql_blob_open | REQ_sql_blob_create))
|
|
|
|
printa(column, "gds__%d := nil;", action->act_request->req_blobs->blb_ident);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate text to open an embedded SQL cursor.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-07 11:58:26 +02:00
|
|
|
static int gen_cursor_open( const act* action, const gpre_req* request, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2005-01-03 09:07:41 +01:00
|
|
|
TEXT s[MAX_CURSOR_SIZE];
|
2004-06-05 11:37:18 +02:00
|
|
|
const TEXT *pattern1 =
|
2001-05-23 15:26:42 +02:00
|
|
|
"if (%RIs = nil) and (%RH <> nil)%IF and (%DH <> nil)%EN then",
|
2004-06-05 11:37:18 +02:00
|
|
|
*pattern2 = "if (%RIs = nil)%IF and (%DH <> nil)%EN then",
|
|
|
|
*pattern3 = "isc_dsql_alloc_statement2 (%V1, %RF%DH, %RF%RIs);",
|
|
|
|
*pattern4 = "if (%RIs <> nil)%IF and (%S3 <> nil)%EN then",
|
|
|
|
*pattern5 = "isc_dsql_set_cursor_name (%V1, %RF%RIs, %S1, 0);",
|
|
|
|
*pattern6 = "isc_dsql_execute_m (%V1, %RF%S3, %RF%RIs, 0, gds__null, %N2, 0, gds__null);";
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
PAT args;
|
2001-05-23 15:26:42 +02:00
|
|
|
args.pat_request = request;
|
|
|
|
args.pat_database = request->req_database;
|
|
|
|
args.pat_vector1 = status_vector(action);
|
2004-05-24 19:13:38 +02:00
|
|
|
args.pat_condition = gpreGlob.sw_auto;
|
2004-01-28 08:50:41 +01:00
|
|
|
args.pat_string1 = make_name(s, ((open_cursor*) action->act_object)->opn_cursor);
|
2001-05-23 15:26:42 +02:00
|
|
|
args.pat_string3 = request_trans(action, request);
|
|
|
|
args.pat_value2 = -1;
|
|
|
|
|
2008-12-27 08:00:40 +01:00
|
|
|
PATTERN_expand(column, (action->act_type == ACT_open) ? pattern1 : pattern2, &args);
|
2001-05-23 15:26:42 +02:00
|
|
|
PATTERN_expand(column + INDENT, pattern3, &args);
|
|
|
|
PATTERN_expand(column, pattern4, &args);
|
|
|
|
column += INDENT;
|
2003-09-16 16:01:56 +02:00
|
|
|
begin(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
PATTERN_expand(column, pattern5, &args);
|
|
|
|
printa(column, "if (gds__status[2] = 0) then");
|
|
|
|
column += INDENT;
|
2003-09-16 16:01:56 +02:00
|
|
|
begin(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
PATTERN_expand(column, pattern6, &args);
|
|
|
|
printa(column, "if (gds__status[2] = 0) then");
|
|
|
|
column += INDENT;
|
2003-09-16 16:01:56 +02:00
|
|
|
begin(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
return column;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate insertion text for the database statement,
|
2004-05-24 19:13:38 +02:00
|
|
|
// including the definitions of all gpreGlob.requests, and blob
|
|
|
|
// ans port declarations for gpreGlob.requests in the main routine.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-05-01 19:21:36 +02:00
|
|
|
static void gen_database(/* const act* action,*/ int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-07 11:58:26 +02:00
|
|
|
const gpre_req* request;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-29 11:53:47 +01:00
|
|
|
if (global_first_flag)
|
2001-05-23 15:26:42 +02:00
|
|
|
return;
|
2003-10-29 11:53:47 +01:00
|
|
|
global_first_flag = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "\n(**** GPRE Preprocessor Definitions ****)\n");
|
2007-02-11 10:31:45 +01:00
|
|
|
fprintf(gpreGlob.out_file, "%%include '/firebird/include/gds.ins.pas';\n");
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
int indent = column + INDENT;
|
2003-09-10 21:48:53 +02:00
|
|
|
bool flag = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
for (request = gpreGlob.requests; request; request = request->req_next)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
if (request->req_flags & REQ_local)
|
|
|
|
continue;
|
2009-06-28 12:26:25 +02:00
|
|
|
for (const gpre_port* port = request->req_ports; port; port = port->por_next)
|
|
|
|
{
|
|
|
|
if (flag)
|
|
|
|
{
|
2003-09-10 21:48:53 +02:00
|
|
|
flag = false;
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "type");
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
make_port(port, indent);
|
|
|
|
}
|
|
|
|
}
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "\nvar");
|
2009-04-22 13:44:39 +02:00
|
|
|
for (request = gpreGlob.requests; request; request = request->req_routine)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
if (request->req_flags & REQ_local)
|
|
|
|
continue;
|
2008-12-29 11:26:36 +01:00
|
|
|
for (const gpre_port* port = request->req_ports; port; port = port->por_next)
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(indent, "gds__%d\t: gds__%dt;\t\t\t(* message *)",
|
|
|
|
port->por_ident, port->por_ident);
|
|
|
|
|
2009-06-28 12:26:25 +02:00
|
|
|
for (blb* blob = request->req_blobs; blob; blob = blob->blb_next)
|
|
|
|
{
|
2008-12-29 11:26:36 +01:00
|
|
|
printa(indent, "gds__%d\t: gds__handle;\t\t\t(* blob handle *)", blob->blb_ident);
|
|
|
|
printa(indent, "gds__%d\t: %s [1 .. %d] of char;\t(* blob segment *)",
|
2001-05-23 15:26:42 +02:00
|
|
|
blob->blb_buff_ident, PACKED_ARRAY, blob->blb_seg_length);
|
2008-12-29 11:26:36 +01:00
|
|
|
printa(indent, "gds__%d\t: %s;\t\t\t(* segment length *)", blob->blb_len_ident, SHORT_DCL);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
const gpre_dbb* db;
|
2003-09-10 21:48:53 +02:00
|
|
|
bool all_static = true;
|
|
|
|
bool all_extern = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
for (db = gpreGlob.isc_databases; db; db = db->dbb_next)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
all_static = all_static && (db->dbb_scope == DBB_STATIC);
|
|
|
|
all_extern = all_extern && (db->dbb_scope == DBB_EXTERN);
|
|
|
|
if (db->dbb_scope == DBB_STATIC)
|
2008-12-29 11:26:36 +01:00
|
|
|
printa(indent, "%s\t: %s gds__handle\t:= nil; (* database handle *)",
|
2001-05-23 15:26:42 +02:00
|
|
|
db->dbb_name->sym_string, STATIC_STRING);
|
|
|
|
}
|
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
USHORT count = 0;
|
2009-06-28 12:26:25 +02:00
|
|
|
for (db = gpreGlob.isc_databases; db; db = db->dbb_next)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
count++;
|
2008-12-29 11:26:36 +01:00
|
|
|
for (const tpb* tpb_val = db->dbb_tpbs; tpb_val; tpb_val = tpb_val->tpb_dbb_next)
|
2003-09-05 16:55:59 +02:00
|
|
|
gen_tpb(tpb_val, indent);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
printa(indent, "gds__teb\t: array [1..%d] of gds__teb_t;\t(* transaction vector *)", count);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
// generate event parameter block for each event in module
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
SSHORT max_count = 0;
|
2009-06-28 12:26:25 +02:00
|
|
|
for (gpre_lls* stack_ptr = gpreGlob.events; stack_ptr; stack_ptr = stack_ptr->lls_next)
|
|
|
|
{
|
2008-12-29 11:26:36 +01:00
|
|
|
SSHORT event_count = gen_event_block(reinterpret_cast<act*>(stack_ptr->lls_object));
|
2001-05-23 15:26:42 +02:00
|
|
|
max_count = MAX(event_count, max_count);
|
|
|
|
}
|
|
|
|
|
2009-06-28 12:26:25 +02:00
|
|
|
if (max_count)
|
|
|
|
{
|
2008-12-29 11:26:36 +01:00
|
|
|
printa(indent, "gds__events\t\t: %s array [1..%d] of %s;\t\t(* event vector *)",
|
2001-05-23 15:26:42 +02:00
|
|
|
STATIC_STRING, max_count, LONG_DCL);
|
2008-12-29 11:26:36 +01:00
|
|
|
printa(indent, "gds__event_names\t\t: %s array [1..%d] of %s;\t\t(* event buffer *)",
|
2001-05-23 15:26:42 +02:00
|
|
|
STATIC_STRING, max_count, POINTER_DCL);
|
|
|
|
printa(indent,
|
|
|
|
"gds__event_names2\t\t: %s %s [1..%d, 1..31] of char;\t\t(* event string buffer *)",
|
|
|
|
STATIC_STRING, PACKED_ARRAY, max_count);
|
|
|
|
}
|
|
|
|
|
2003-09-10 21:48:53 +02:00
|
|
|
bool array_flag = false;
|
2009-04-22 13:44:39 +02:00
|
|
|
for (request = gpreGlob.requests; request; request = request->req_next)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
gen_request(request, indent);
|
2009-04-22 13:44:39 +02:00
|
|
|
// Array declarations
|
2001-05-23 15:26:42 +02:00
|
|
|
if (request->req_type == REQ_slice)
|
2003-09-10 21:48:53 +02:00
|
|
|
array_flag = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
const gpre_port* port = request->req_primary;
|
|
|
|
if (port)
|
|
|
|
for (const ref* reference = port->por_references; reference;
|
|
|
|
reference = reference->ref_next)
|
2003-09-13 14:22:11 +02:00
|
|
|
{
|
2009-06-28 12:26:25 +02:00
|
|
|
if (reference->ref_flags & REF_fetch_array)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
make_array_declaration(reference);
|
2003-09-10 21:48:53 +02:00
|
|
|
array_flag = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
2003-09-13 14:22:11 +02:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (array_flag)
|
2008-12-29 11:26:36 +01:00
|
|
|
printa(indent, "gds__array_length\t: integer32;\t\t\t(* slice return value *)");
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
printa(indent, "gds__null\t\t: ^gds__status_vector := nil;\t(* null status vector *)");
|
|
|
|
printa(indent, "gds__blob_null\t: gds__quad := %s0,0%s;\t\t(* null blob id *)",
|
2001-05-23 15:26:42 +02:00
|
|
|
OPEN_BRACKET, CLOSE_BRACKET);
|
|
|
|
|
2009-06-28 12:26:25 +02:00
|
|
|
if (all_static)
|
|
|
|
{
|
2008-12-29 11:26:36 +01:00
|
|
|
printa(indent, "gds__trans\t\t: %s gds__handle := nil;\t\t(* default transaction *)",
|
2001-05-23 15:26:42 +02:00
|
|
|
STATIC_STRING);
|
2008-12-29 11:26:36 +01:00
|
|
|
printa(indent, "gds__status\t\t: %s gds__status_vector;\t\t(* status vector *)", STATIC_STRING);
|
|
|
|
printa(indent, "gds__status2\t\t: %s gds__status_vector;\t\t(* status vector *)", STATIC_STRING);
|
|
|
|
printa(indent, "SQLCODE\t: %s integer := 0;\t\t\t(* SQL status code *)", STATIC_STRING);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
2009-06-28 12:26:25 +02:00
|
|
|
else
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(column, "\nvar (gds__trans)");
|
2008-12-29 11:26:36 +01:00
|
|
|
printa(indent, "gds__trans\t\t: gds__handle%s;\t\t(* default transaction *)",
|
2008-12-27 08:00:40 +01:00
|
|
|
all_extern ? "" : "\t:= nil");
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(column, "\nvar (gds__status)");
|
2008-12-29 11:26:36 +01:00
|
|
|
printa(indent, "gds__status\t\t: gds__status_vector;\t\t(* status vector *)");
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(column, "\nvar (gds__status2)");
|
2008-12-29 11:26:36 +01:00
|
|
|
printa(indent, "gds__status2\t\t: gds__status_vector;\t\t(* status vector *)");
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(column, "\nvar (SQLCODE)");
|
|
|
|
printa(indent, "SQLCODE\t: integer%s;\t\t\t(* SQL status code *)",
|
2008-12-27 08:00:40 +01:00
|
|
|
all_extern ? "" : "\t:= 0");
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
printa(column, "\nvar (gds__window)");
|
2008-12-29 11:26:36 +01:00
|
|
|
printa(indent, "gds__window\t\t: gds__handle := nil;\t\t(* window handle *)");
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(column, "\nvar (gds__width)");
|
2008-12-29 11:26:36 +01:00
|
|
|
printa(indent, "gds__width\t\t: %s := 80;\t(* window width *)", SHORT_DCL);
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(column, "\nvar (gds__height)");
|
2008-12-29 11:26:36 +01:00
|
|
|
printa(indent, "gds__height\t\t: %s := 24;\t(* window height *)", SHORT_DCL);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
for (db = gpreGlob.isc_databases; db; db = db->dbb_next)
|
|
|
|
{
|
2009-06-28 12:26:25 +02:00
|
|
|
if (db->dbb_scope != DBB_STATIC)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(column, "\nvar (%s)", db->dbb_name->sym_string);
|
|
|
|
printa(indent, "%s\t: gds__handle%s; (* database handle *)",
|
2008-12-29 11:26:36 +01:00
|
|
|
db->dbb_name->sym_string, (db->dbb_scope == DBB_EXTERN) ? "" : "\t:= nil");
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
printa(column, " ");
|
|
|
|
printa(column, "(**** end of GPRE definitions ****)");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate a call to update metadata.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_ddl( const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2009-06-28 12:26:25 +02:00
|
|
|
if (gpreGlob.sw_auto)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(column, "if (gds__trans = nil) then");
|
|
|
|
column += INDENT;
|
|
|
|
t_start_auto(action, 0, status_vector(action), column + INDENT);
|
|
|
|
column -= INDENT;
|
|
|
|
}
|
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
// Set up command type for call to RDB$DDL
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
const gpre_req* request = action->act_request;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-06-28 12:26:25 +02:00
|
|
|
if (gpreGlob.sw_auto)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(column, "if (gds__trans <> nil) then");
|
|
|
|
column += INDENT;
|
|
|
|
}
|
|
|
|
|
|
|
|
align(column);
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "GDS__DDL (%s, %s, gds__trans, %d, gds__%d);",
|
2001-05-23 15:26:42 +02:00
|
|
|
status_vector(action),
|
|
|
|
request->req_database->dbb_name->sym_string,
|
|
|
|
request->req_length, request->req_ident);
|
|
|
|
|
2009-06-28 12:26:25 +02:00
|
|
|
if (gpreGlob.sw_auto)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
column -= INDENT;
|
|
|
|
printa(column, "if (gds__status [2] = 0) then");
|
2008-12-29 11:26:36 +01:00
|
|
|
printa(column + INDENT, "GDS__COMMIT_TRANSACTION (%s, gds__trans);", status_vector(action));
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(column, "if (gds__status [2] <> 0) then");
|
2008-12-29 11:26:36 +01:00
|
|
|
printa(column + INDENT, "GDS__ROLLBACK_TRANSACTION (gds__null^ , gds__trans);");
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2003-09-12 18:35:40 +02:00
|
|
|
set_sqlcode(action, column);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate a call to create a database.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_drop_database( const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2009-04-22 13:44:39 +02:00
|
|
|
const gpre_dbb* db = (gpre_dbb*) action->act_object;
|
2001-05-23 15:26:42 +02:00
|
|
|
align(column);
|
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
fprintf(gpreGlob.out_file, "GDS__DROP_DATABASE (%s, %d, '%s', RDB$K_DB_TYPE_GDS);",
|
2001-05-23 15:26:42 +02:00
|
|
|
status_vector(action),
|
|
|
|
strlen(db->dbb_filename), db->dbb_filename);
|
2003-09-12 18:35:40 +02:00
|
|
|
set_sqlcode(action, column);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate a dynamic SQL statement.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_dyn_close( const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2005-01-03 09:07:41 +01:00
|
|
|
TEXT s[MAX_CURSOR_SIZE];
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
const dyn* statement = (dyn*) action->act_object;
|
|
|
|
printa(column, "isc_embed_dsql_close (gds__status, %s);", make_name(s, statement->dyn_cursor_name));
|
2003-09-12 18:35:40 +02:00
|
|
|
set_sqlcode(action, column);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate a dynamic SQL statement.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_dyn_declare( const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2005-01-03 09:07:41 +01:00
|
|
|
TEXT s1[MAX_CURSOR_SIZE], s2[MAX_CURSOR_SIZE];
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
const dyn* statement = (dyn*) action->act_object;
|
|
|
|
printa(column, "isc_embed_dsql_declare (gds__status, %s, %s);",
|
2001-05-23 15:26:42 +02:00
|
|
|
make_name(s1, statement->dyn_statement_name),
|
|
|
|
make_name(s2, statement->dyn_cursor_name));
|
2003-09-12 18:35:40 +02:00
|
|
|
set_sqlcode(action, column);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate a dynamic SQL statement.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
static void gen_dyn_describe(const act* action, int column, bool bind_flag)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2005-01-03 09:07:41 +01:00
|
|
|
TEXT s[MAX_CURSOR_SIZE];
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
const dyn* statement = (dyn*) action->act_object;
|
|
|
|
printa(column, "isc_embed_dsql_describe%s (gds__status, %s, %d, %s %s);",
|
2001-05-23 15:26:42 +02:00
|
|
|
bind_flag ? "_bind" : "",
|
|
|
|
make_name(s, statement->dyn_statement_name),
|
2004-05-24 19:13:38 +02:00
|
|
|
gpreGlob.sw_sql_dialect, REF_PAR, statement->dyn_sqlda);
|
2003-09-12 18:35:40 +02:00
|
|
|
set_sqlcode(action, column);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate a dynamic SQL statement.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_dyn_execute( const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-09-05 12:14:08 +02:00
|
|
|
gpre_req* request;
|
|
|
|
gpre_req req_const;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
const dyn* statement = (dyn*) action->act_object;
|
2003-10-06 11:48:44 +02:00
|
|
|
const TEXT* transaction;
|
2009-06-28 12:26:25 +02:00
|
|
|
if (statement->dyn_trans)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
transaction = statement->dyn_trans;
|
|
|
|
request = &req_const;
|
|
|
|
request->req_trans = transaction;
|
|
|
|
}
|
2009-06-28 12:26:25 +02:00
|
|
|
else
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
transaction = "gds__trans";
|
|
|
|
request = NULL;
|
|
|
|
}
|
|
|
|
|
2009-06-28 12:26:25 +02:00
|
|
|
if (gpreGlob.sw_auto)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(column, "if (%s = nil) then", transaction);
|
|
|
|
column += INDENT;
|
|
|
|
t_start_auto(action, request, status_vector(action), column + INDENT);
|
|
|
|
column -= INDENT;
|
|
|
|
}
|
|
|
|
|
2005-01-03 09:07:41 +01:00
|
|
|
TEXT s[MAX_CURSOR_SIZE];
|
2001-05-23 15:26:42 +02:00
|
|
|
make_name(s, statement->dyn_cursor_name);
|
|
|
|
|
2008-12-25 08:46:53 +01:00
|
|
|
gpre_nod* var_list;
|
2009-06-28 12:26:25 +02:00
|
|
|
if (var_list = statement->dyn_using)
|
|
|
|
{
|
2004-05-24 19:13:38 +02:00
|
|
|
printa(column, "gds__sqlda.sqln = %s;", gpreGlob.sw_dyn_using);
|
|
|
|
printa(column, "gds__sqlda.sqld = %s;", gpreGlob.sw_dyn_using);
|
2008-12-29 11:26:36 +01:00
|
|
|
for (int i = 0; i < var_list->nod_count; i++)
|
2001-05-23 15:26:42 +02:00
|
|
|
asgn_sqlda_from(reinterpret_cast<ref*>(var_list->nod_arg[i]), i, s, column);
|
|
|
|
}
|
|
|
|
|
|
|
|
printa(column,
|
2008-12-27 08:00:40 +01:00
|
|
|
statement->dyn_sqlda2 ?
|
2008-12-29 11:26:36 +01:00
|
|
|
"isc_embed_dsql_execute2 (gds__status, %s, %s, %d, %s %s, %s %s);" :
|
|
|
|
"isc_embed_dsql_execute (gds__status, %s, %s, %d, %s %s);",
|
2001-05-23 15:26:42 +02:00
|
|
|
transaction, make_name(s, statement->dyn_statement_name),
|
2004-05-24 19:13:38 +02:00
|
|
|
gpreGlob.sw_sql_dialect, REF_PAR,
|
2008-12-27 08:00:40 +01:00
|
|
|
statement->dyn_sqlda ? statement->dyn_sqlda : "gds__null^",
|
2001-05-23 15:26:42 +02:00
|
|
|
REF_PAR,
|
2008-12-27 08:00:40 +01:00
|
|
|
statement->dyn_sqlda2 ? statement->dyn_sqlda2 : "gds__null^");
|
2003-09-12 18:35:40 +02:00
|
|
|
set_sqlcode(action, column);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate a dynamic SQL statement.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_dyn_fetch( const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2005-01-03 09:07:41 +01:00
|
|
|
TEXT s[MAX_CURSOR_SIZE];
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
const dyn* statement = (dyn*) action->act_object;
|
|
|
|
printa(column, "SQLCODE := isc_embed_dsql_fetch (gds__status, %s, %d, %s %s);",
|
2001-05-23 15:26:42 +02:00
|
|
|
make_name(s, statement->dyn_cursor_name),
|
2004-05-24 19:13:38 +02:00
|
|
|
gpreGlob.sw_sql_dialect,
|
2001-05-23 15:26:42 +02:00
|
|
|
REF_PAR,
|
2008-12-27 08:00:40 +01:00
|
|
|
statement->dyn_sqlda ? statement->dyn_sqlda : "gds__null^");
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(column,
|
|
|
|
"if sqlcode <> 100 then sqlcode := gds__sqlcode (gds__status);");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate code for an EXECUTE IMMEDIATE dynamic SQL statement.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_dyn_immediate( const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-09-05 12:14:08 +02:00
|
|
|
gpre_req* request;
|
|
|
|
gpre_req req_const;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
const dyn* statement = (dyn*) action->act_object;
|
2003-10-06 11:48:44 +02:00
|
|
|
const TEXT* transaction;
|
2009-06-28 12:26:25 +02:00
|
|
|
if (statement->dyn_trans)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
transaction = statement->dyn_trans;
|
|
|
|
request = &req_const;
|
|
|
|
request->req_trans = transaction;
|
|
|
|
}
|
2009-06-28 12:26:25 +02:00
|
|
|
else
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
transaction = "gds__trans";
|
|
|
|
request = NULL;
|
|
|
|
}
|
|
|
|
|
2009-06-28 12:26:25 +02:00
|
|
|
if (gpreGlob.sw_auto)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(column, "if (%s = nil) then", transaction);
|
|
|
|
column += INDENT;
|
|
|
|
t_start_auto(action, request, status_vector(action), column + INDENT);
|
|
|
|
column -= INDENT;
|
|
|
|
}
|
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
const gpre_dbb* database = statement->dyn_database;
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(column,
|
2008-12-27 08:00:40 +01:00
|
|
|
statement->dyn_sqlda2 ?
|
2008-12-29 11:26:36 +01:00
|
|
|
"isc_embed_dsql_execute_immed2 (gds__status, %s, %s, %s(%s), %s, %d, %s %s, %s %s);" :
|
|
|
|
"isc_embed_dsql_execute_immed (gds__status, %s, %s, %s(%s), %s, %d, %s %s);",
|
2001-05-23 15:26:42 +02:00
|
|
|
database->dbb_name->sym_string, transaction, SIZEOF,
|
2004-05-24 19:13:38 +02:00
|
|
|
statement->dyn_string, statement->dyn_string, gpreGlob.sw_sql_dialect,
|
2001-05-23 15:26:42 +02:00
|
|
|
REF_PAR,
|
2008-12-27 08:00:40 +01:00
|
|
|
statement->dyn_sqlda ? statement->dyn_sqlda : "gds__null^",
|
2001-05-23 15:26:42 +02:00
|
|
|
REF_PAR,
|
2008-12-27 08:00:40 +01:00
|
|
|
statement->dyn_sqlda2 ? statement->dyn_sqlda2 : "gds__null^");
|
2003-09-12 18:35:40 +02:00
|
|
|
set_sqlcode(action, column);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate a dynamic SQL statement.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_dyn_insert( const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2005-01-03 09:07:41 +01:00
|
|
|
TEXT s[MAX_CURSOR_SIZE];
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
const dyn* statement = (dyn*) action->act_object;
|
|
|
|
printa(column, "isc_embed_dsql_insert (gds__status, %s, %d, %s %s);",
|
2001-05-23 15:26:42 +02:00
|
|
|
make_name(s, statement->dyn_cursor_name),
|
2004-05-24 19:13:38 +02:00
|
|
|
gpreGlob.sw_sql_dialect,
|
2001-05-23 15:26:42 +02:00
|
|
|
REF_PAR,
|
2008-12-27 08:00:40 +01:00
|
|
|
statement->dyn_sqlda ? statement->dyn_sqlda : "gds__null^");
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-09-12 18:35:40 +02:00
|
|
|
set_sqlcode(action, column);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate a dynamic SQL statement.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_dyn_open( const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-09-05 12:14:08 +02:00
|
|
|
gpre_req* request;
|
|
|
|
gpre_req req_const;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
const dyn* statement = (dyn*) action->act_object;
|
2003-10-06 11:48:44 +02:00
|
|
|
const TEXT* transaction;
|
2009-06-28 12:26:25 +02:00
|
|
|
if (statement->dyn_trans)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
transaction = statement->dyn_trans;
|
|
|
|
request = &req_const;
|
|
|
|
request->req_trans = transaction;
|
|
|
|
}
|
2009-06-28 12:26:25 +02:00
|
|
|
else
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
transaction = "gds__trans";
|
|
|
|
request = NULL;
|
|
|
|
}
|
|
|
|
|
2009-06-28 12:26:25 +02:00
|
|
|
if (gpreGlob.sw_auto)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(column, "if (%s = nil) then", transaction);
|
|
|
|
column += INDENT;
|
|
|
|
t_start_auto(action, request, status_vector(action), column + INDENT);
|
|
|
|
column -= INDENT;
|
|
|
|
}
|
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
TEXT s[MAX_CURSOR_SIZE];
|
2001-05-23 15:26:42 +02:00
|
|
|
make_name(s, statement->dyn_cursor_name);
|
|
|
|
|
2009-06-28 12:26:25 +02:00
|
|
|
if (const gpre_nod* var_list = statement->dyn_using)
|
|
|
|
{
|
2004-05-24 19:13:38 +02:00
|
|
|
printa(column, "gds__sqlda.sqln = %d;", gpreGlob.sw_dyn_using);
|
|
|
|
printa(column, "gds__sqlda.sqld = %d;", gpreGlob.sw_dyn_using);
|
2008-12-29 11:26:36 +01:00
|
|
|
for (int i = 0; i < var_list->nod_count; i++)
|
|
|
|
asgn_sqlda_from(reinterpret_cast<const ref*>(var_list->nod_arg[i]), i, s, column);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
printa(column,
|
2008-12-27 08:00:40 +01:00
|
|
|
statement->dyn_sqlda2 ?
|
2008-12-29 11:26:36 +01:00
|
|
|
"isc_embed_dsql_open2 (gds__status, %s, %s, %d, %s %s, %s %s);" :
|
|
|
|
"isc_embed_dsql_open (gds__status, %s, %s, %d, %s %s);",
|
2001-05-23 15:26:42 +02:00
|
|
|
s,
|
|
|
|
transaction,
|
2004-05-24 19:13:38 +02:00
|
|
|
gpreGlob.sw_sql_dialect,
|
2001-05-23 15:26:42 +02:00
|
|
|
REF_PAR,
|
2008-12-27 08:00:40 +01:00
|
|
|
statement->dyn_sqlda ? statement->dyn_sqlda : "gds__null^",
|
2001-05-23 15:26:42 +02:00
|
|
|
REF_PAR,
|
2008-12-27 08:00:40 +01:00
|
|
|
statement->dyn_sqlda2 ? statement->dyn_sqlda2 : "gds__null^");
|
2003-09-12 18:35:40 +02:00
|
|
|
set_sqlcode(action, column);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate a dynamic SQL statement.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_dyn_prepare( const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-09-05 12:14:08 +02:00
|
|
|
gpre_req* request;
|
|
|
|
gpre_req req_const;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
const dyn* statement = (dyn*) action->act_object;
|
2003-10-06 11:48:44 +02:00
|
|
|
const TEXT* transaction;
|
2009-06-28 12:26:25 +02:00
|
|
|
if (statement->dyn_trans)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
transaction = statement->dyn_trans;
|
|
|
|
request = &req_const;
|
|
|
|
request->req_trans = transaction;
|
|
|
|
}
|
2009-06-28 12:26:25 +02:00
|
|
|
else
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
transaction = "gds__trans";
|
|
|
|
request = NULL;
|
|
|
|
}
|
|
|
|
|
2009-06-28 12:26:25 +02:00
|
|
|
if (gpreGlob.sw_auto)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(column, "if (%s = nil) then", transaction);
|
|
|
|
column += INDENT;
|
|
|
|
t_start_auto(action, request, status_vector(action), column + INDENT);
|
|
|
|
column -= INDENT;
|
|
|
|
}
|
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
const gpre_dbb* database = statement->dyn_database;
|
2008-12-29 11:26:36 +01:00
|
|
|
TEXT s[MAX_CURSOR_SIZE];
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(column,
|
|
|
|
"isc_embed_dsql_prepare (gds__status, %s, transaction, %s, %s(%s), %s, %d, %s %s);",
|
2004-12-16 04:03:13 +01:00
|
|
|
database->dbb_name->sym_string, transaction,
|
|
|
|
make_name(s, statement->dyn_statement_name),
|
2001-05-23 15:26:42 +02:00
|
|
|
SIZEOF, statement->dyn_string, statement->dyn_string,
|
2004-05-24 19:13:38 +02:00
|
|
|
gpreGlob.sw_sql_dialect, REF_PAR,
|
2008-12-27 08:00:40 +01:00
|
|
|
statement->dyn_sqlda ? statement->dyn_sqlda : "gds__null^");
|
2003-09-12 18:35:40 +02:00
|
|
|
set_sqlcode(action, column);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate substitution text for END_MODIFY.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_emodify( const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2005-01-03 09:07:41 +01:00
|
|
|
TEXT s1[MAX_REF_SIZE], s2[MAX_REF_SIZE];
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
const upd* modify = (upd*) action->act_object;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-07 11:58:26 +02:00
|
|
|
for (const ref* reference = modify->upd_port->por_references; reference;
|
2008-12-05 02:20:14 +01:00
|
|
|
reference = reference->ref_next)
|
2003-10-07 11:58:26 +02:00
|
|
|
{
|
|
|
|
const ref* source = reference->ref_source;
|
|
|
|
if (!source)
|
2001-05-23 15:26:42 +02:00
|
|
|
continue;
|
2008-12-29 11:26:36 +01:00
|
|
|
gpre_fld* field = reference->ref_field;
|
2001-05-23 15:26:42 +02:00
|
|
|
align(column);
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "%s := %s;",
|
2003-09-10 21:48:53 +02:00
|
|
|
gen_name(s1, reference, true), gen_name(s2, source, true));
|
2001-05-23 15:26:42 +02:00
|
|
|
if (field->fld_array_info)
|
2003-09-10 21:48:53 +02:00
|
|
|
gen_get_or_put_slice(action, reference, false, column);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
gen_send(action, modify->upd_port, column);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate substitution text for END_STORE.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_estore( const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2008-12-29 11:26:36 +01:00
|
|
|
const gpre_req* request = action->act_request;
|
2009-04-22 13:44:39 +02:00
|
|
|
// if we did a store ... returning_values aka store2
|
|
|
|
// just wrap up pending error
|
2009-06-28 12:26:25 +02:00
|
|
|
if (request->req_type == REQ_store2)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
if (action->act_error || (action->act_flags & ACT_sql))
|
2003-09-16 16:01:56 +02:00
|
|
|
endp(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
return;
|
|
|
|
}
|
2008-12-29 11:26:36 +01:00
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
if (action->act_error)
|
|
|
|
column += INDENT;
|
|
|
|
gen_start(action, request->req_primary, column);
|
|
|
|
if (action->act_error || (action->act_flags & ACT_sql))
|
2003-09-16 16:01:56 +02:00
|
|
|
endp(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate definitions associated with a single request.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_endfor( const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2008-12-29 11:26:36 +01:00
|
|
|
const gpre_req* request = action->act_request;
|
2001-05-23 15:26:42 +02:00
|
|
|
column += INDENT;
|
|
|
|
|
|
|
|
if (request->req_sync)
|
|
|
|
gen_send(action, request->req_sync, column);
|
|
|
|
|
|
|
|
gen_receive(action, column, request->req_primary);
|
|
|
|
|
2003-09-16 16:01:56 +02:00
|
|
|
endp(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
if (action->act_error || (action->act_flags & ACT_sql))
|
2003-09-16 16:01:56 +02:00
|
|
|
endp(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate substitution text for ERASE.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_erase( const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
if (action->act_error || (action->act_flags & ACT_sql))
|
2003-09-16 16:01:56 +02:00
|
|
|
begin(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
const upd* erase = (upd*) action->act_object;
|
2001-05-23 15:26:42 +02:00
|
|
|
gen_send(action, erase->upd_port, column);
|
|
|
|
|
|
|
|
if (action->act_flags & ACT_sql)
|
2003-09-16 16:01:56 +02:00
|
|
|
endp(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate event parameter blocks for use
|
|
|
|
// with a particular call to gds__event_wait.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static SSHORT gen_event_block( const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2008-12-29 11:26:36 +01:00
|
|
|
gpre_nod* init = (gpre_nod*) action->act_object;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
int ident = CMP_next_ident();
|
2008-12-25 08:46:53 +01:00
|
|
|
init->nod_arg[2] = (gpre_nod*) ident;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
printa(INDENT, "gds__%da\t\t: ^char;\t\t(* event parameter block *)", ident);
|
|
|
|
printa(INDENT, "gds__%db\t\t: ^char;\t\t(* result parameter block *)", ident);
|
|
|
|
printa(INDENT, "gds__%dl\t\t: %s;\t\t(* length of event parameter block *)", ident, SHORT_DCL);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
gpre_nod* list = init->nod_arg[1];
|
2001-05-23 15:26:42 +02:00
|
|
|
return list->nod_count;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate substitution text for EVENT_INIT.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_event_init( const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2004-06-05 11:37:18 +02:00
|
|
|
const TEXT* pattern1 =
|
2001-05-23 15:26:42 +02:00
|
|
|
"gds__%N1l := GDS__EVENT_BLOCK_A (%RFgds__%N1a, %RFgds__%N1b, %N2, %RFgds__event_names%RE);";
|
2004-06-05 11:37:18 +02:00
|
|
|
const TEXT* pattern2 = "%S1 (%V1, %RF%DH, gds__%N1l, gds__%N1a, gds__%N1b);";
|
|
|
|
const TEXT* pattern3 = "%S2 (gds__events, gds__%N1l, gds__%N1a, gds__%N1b);";
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (action->act_error)
|
2003-09-16 16:01:56 +02:00
|
|
|
begin(column);
|
|
|
|
begin(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
gpre_nod* init = (gpre_nod*) action->act_object;
|
|
|
|
gpre_nod* event_list = init->nod_arg[1];
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
PAT args;
|
2009-01-14 09:22:32 +01:00
|
|
|
args.pat_database = (gpre_dbb*) init->nod_arg[3];
|
2001-05-23 15:26:42 +02:00
|
|
|
args.pat_vector1 = status_vector(action);
|
|
|
|
args.pat_value1 = (int) init->nod_arg[2];
|
|
|
|
args.pat_value2 = (int) event_list->nod_count;
|
2003-10-16 10:51:06 +02:00
|
|
|
args.pat_string1 = GDS_EVENT_WAIT;
|
|
|
|
args.pat_string2 = GDS_EVENT_COUNTS;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
// generate call to dynamically generate event blocks
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2005-01-03 09:07:41 +01:00
|
|
|
TEXT variable[MAX_REF_SIZE];
|
2008-12-29 11:26:36 +01:00
|
|
|
gpre_nod** ptr;
|
|
|
|
gpre_nod** end;
|
|
|
|
SSHORT count;
|
|
|
|
for (ptr = event_list->nod_arg, count = 0, end = ptr + event_list->nod_count; ptr < end; ptr++)
|
2004-12-24 09:52:39 +01:00
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
count++;
|
2008-12-29 11:26:36 +01:00
|
|
|
const gpre_nod* node = *ptr;
|
2009-06-28 12:26:25 +02:00
|
|
|
if (node->nod_type == nod_field)
|
|
|
|
{
|
2008-12-29 11:26:36 +01:00
|
|
|
const ref* reference = (const ref*) node->nod_arg[0];
|
2003-09-10 21:48:53 +02:00
|
|
|
gen_name(variable, reference, true);
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(column, "gds__event_names2[%d] := %s;", count, variable);
|
|
|
|
}
|
|
|
|
else
|
2008-12-29 11:26:36 +01:00
|
|
|
printa(column, "gds__event_names2[%d] := %s;", count, node->nod_arg[0]);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
printa(column, "gds__event_names[%d] := %s (gds__event_names2[%d]);",
|
|
|
|
count, ISC_BADDRESS, count);
|
|
|
|
}
|
|
|
|
|
|
|
|
PATTERN_expand(column, pattern1, &args);
|
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
// generate actual call to event_wait
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
PATTERN_expand(column, pattern2, &args);
|
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
// get change in event counts, copying event parameter block for reuse
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
PATTERN_expand(column, pattern3, &args);
|
|
|
|
|
|
|
|
if (action->act_error)
|
2003-09-16 16:01:56 +02:00
|
|
|
endp(column);
|
2003-09-12 18:35:40 +02:00
|
|
|
set_sqlcode(action, column);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate substitution text for EVENT_WAIT.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_event_wait( const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2004-06-05 11:37:18 +02:00
|
|
|
const TEXT* pattern1 = "%S1 (%V1, %RF%DH, gds__%N1l, gds__%N1a, gds__%N1b);";
|
|
|
|
const TEXT* pattern2 = "%S2 (gds__events, gds__%N1l, gds__%N1a, gds__%N1b);";
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (action->act_error)
|
2003-09-16 16:01:56 +02:00
|
|
|
begin(column);
|
|
|
|
begin(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
gpre_sym* event_name = (gpre_sym*) action->act_object;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
// go through the stack of gpreGlob.events, checking to see if the
|
|
|
|
// event has been initialized and getting the event identifier
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
const gpre_dbb* database = NULL;
|
2008-12-29 11:26:36 +01:00
|
|
|
int ident = -1;
|
2009-04-22 13:44:39 +02:00
|
|
|
for (gpre_lls* stack_ptr = gpreGlob.events; stack_ptr; stack_ptr = stack_ptr->lls_next)
|
|
|
|
{
|
2008-12-29 11:26:36 +01:00
|
|
|
const act* event_action = (const act*) stack_ptr->lls_object;
|
|
|
|
gpre_nod* event_init = (gpre_nod*) event_action->act_object;
|
|
|
|
gpre_sym* stack_name = (gpre_sym*) event_init->nod_arg[0];
|
2009-06-28 12:26:25 +02:00
|
|
|
if (!strcmp(event_name->sym_string, stack_name->sym_string))
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
ident = (int) event_init->nod_arg[2];
|
2009-01-14 09:22:32 +01:00
|
|
|
database = (gpre_dbb*) event_init->nod_arg[3];
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-06-28 12:26:25 +02:00
|
|
|
if (ident < 0)
|
|
|
|
{
|
2008-12-29 11:26:36 +01:00
|
|
|
TEXT s[64];
|
2001-05-23 15:26:42 +02:00
|
|
|
sprintf(s, "event handle \"%s\" not found", event_name->sym_string);
|
2003-10-15 00:22:32 +02:00
|
|
|
CPR_error(s);
|
2001-05-23 15:26:42 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
PAT args;
|
2001-05-23 15:26:42 +02:00
|
|
|
args.pat_database = database;
|
|
|
|
args.pat_vector1 = status_vector(action);
|
2005-11-30 07:12:53 +01:00
|
|
|
args.pat_value1 = ident;
|
2003-10-16 10:51:06 +02:00
|
|
|
args.pat_string1 = GDS_EVENT_WAIT;
|
|
|
|
args.pat_string2 = GDS_EVENT_COUNTS;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
// generate calls to wait on the event and to fill out the gpreGlob.events array
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
PATTERN_expand(column, pattern1, &args);
|
|
|
|
PATTERN_expand(column, pattern2, &args);
|
|
|
|
|
|
|
|
if (action->act_error)
|
2003-09-16 16:01:56 +02:00
|
|
|
endp(column);
|
2003-09-12 18:35:40 +02:00
|
|
|
set_sqlcode(action, column);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate replacement text for the SQL FETCH statement. The
|
|
|
|
// epilog FETCH statement is handled by GEN_S_FETCH (generate
|
|
|
|
// stream fetch).
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_fetch( const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2008-12-29 11:26:36 +01:00
|
|
|
const gpre_req* request = action->act_request;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-06-28 12:26:25 +02:00
|
|
|
if (request->req_sync)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
gen_send(action, request->req_sync, column);
|
|
|
|
printa(column, "if SQLCODE = 0 then");
|
|
|
|
column += INDENT;
|
2003-09-16 16:01:56 +02:00
|
|
|
begin(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2005-01-03 09:07:41 +01:00
|
|
|
TEXT s[MAX_REF_SIZE];
|
2001-05-23 15:26:42 +02:00
|
|
|
gen_receive(action, column, request->req_primary);
|
|
|
|
printa(column, "if SQLCODE = 0 then");
|
|
|
|
column += INDENT;
|
2003-09-10 21:48:53 +02:00
|
|
|
printa(column, "if %s <> 0 then", gen_name(s, request->req_eof, true));
|
2001-05-23 15:26:42 +02:00
|
|
|
column += INDENT;
|
2003-09-16 16:01:56 +02:00
|
|
|
begin(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
if (gpre_nod* var_list = (gpre_nod*) action->act_object)
|
2009-06-28 12:26:25 +02:00
|
|
|
for (int i = 0; i < var_list->nod_count; i++)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
align(column);
|
|
|
|
asgn_to(action, reinterpret_cast<ref*>(var_list->nod_arg[i]), column);
|
|
|
|
}
|
|
|
|
|
2003-09-16 16:01:56 +02:00
|
|
|
endp(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(column - INDENT, "else");
|
|
|
|
printa(column, "SQLCODE := 100;");
|
2009-06-28 12:26:25 +02:00
|
|
|
if (request->req_sync)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
column -= INDENT;
|
2003-09-16 16:01:56 +02:00
|
|
|
endp(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate substitution text for FINISH
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_finish( const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2009-04-22 13:44:39 +02:00
|
|
|
const gpre_dbb* db = NULL;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
if (gpreGlob.sw_auto || ((action->act_flags & ACT_sql) && (action->act_type != ACT_disconnect)))
|
2008-06-05 13:02:42 +02:00
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(column, "if gds__trans <> nil");
|
|
|
|
printa(column + 4, "then GDS__%s_TRANSACTION (%s, gds__trans);",
|
|
|
|
(action->act_type != ACT_rfinish) ? "COMMIT" : "ROLLBACK",
|
|
|
|
status_vector(action));
|
|
|
|
}
|
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
// Got rid of tests of gds__trans <> nil which were causing the skipping
|
|
|
|
// of trying to detach the databases. Related to bug#935. mao 6/22/89
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-06-28 12:26:25 +02:00
|
|
|
for (rdy* ready = (rdy*) action->act_object; ready; ready = ready->rdy_next)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
db = ready->rdy_database;
|
|
|
|
printa(column, "GDS__DETACH_DATABASE (%s, %s);",
|
|
|
|
status_vector(action), db->dbb_name->sym_string);
|
|
|
|
}
|
2008-12-31 21:22:10 +01:00
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
if (!db)
|
2008-12-31 21:22:10 +01:00
|
|
|
{
|
|
|
|
for (db = gpreGlob.isc_databases; db; db = db->dbb_next)
|
|
|
|
{
|
2008-12-31 10:35:52 +01:00
|
|
|
if ((action->act_error || (action->act_flags & ACT_sql)) &&
|
|
|
|
(db != gpreGlob.isc_databases))
|
|
|
|
{
|
|
|
|
printa(column, "if (%s <> nil) and (gds__status[2] = 0) then", db->dbb_name->sym_string);
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
else
|
|
|
|
printa(column, "if %s <> nil then", db->dbb_name->sym_string);
|
|
|
|
printa(column + INDENT, "GDS__DETACH_DATABASE (%s, %s);",
|
|
|
|
status_vector(action), db->dbb_name->sym_string);
|
|
|
|
}
|
2008-12-31 21:22:10 +01:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-09-12 18:35:40 +02:00
|
|
|
set_sqlcode(action, column);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate substitution text for FOR statement.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_for( const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2004-01-28 08:50:41 +01:00
|
|
|
gpre_port* port;
|
2003-10-07 11:58:26 +02:00
|
|
|
const gpre_req* request;
|
|
|
|
const ref* reference;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
gen_s_start(action, column);
|
|
|
|
request = action->act_request;
|
|
|
|
|
|
|
|
if (action->act_error || (action->act_flags & ACT_sql))
|
|
|
|
printa(column, "if gds__status[2] = 0 then begin");
|
|
|
|
|
2005-01-03 09:07:41 +01:00
|
|
|
TEXT s[MAX_REF_SIZE];
|
2001-05-23 15:26:42 +02:00
|
|
|
gen_receive(action, column, request->req_primary);
|
|
|
|
if (action->act_error || (action->act_flags & ACT_sql))
|
|
|
|
printa(column, "while (%s <> 0) and (gds__status[2] = 0) do",
|
2003-09-10 21:48:53 +02:00
|
|
|
gen_name(s, request->req_eof, true));
|
2001-05-23 15:26:42 +02:00
|
|
|
else
|
|
|
|
printa(column, "while %s <> 0 do",
|
2003-09-10 21:48:53 +02:00
|
|
|
gen_name(s, request->req_eof, true));
|
2001-05-23 15:26:42 +02:00
|
|
|
column += INDENT;
|
2003-09-16 16:01:56 +02:00
|
|
|
begin(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (port = action->act_request->req_primary)
|
2009-04-22 13:44:39 +02:00
|
|
|
for (reference = port->por_references; reference; reference = reference->ref_next)
|
2003-09-13 14:22:11 +02:00
|
|
|
{
|
|
|
|
if (reference->ref_field->fld_array_info)
|
|
|
|
gen_get_or_put_slice(action, reference, true, column);
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate a call to gds__get_slice
|
|
|
|
// or gds__put_slice for an array.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_get_or_put_slice(const act* action,
|
2003-10-07 11:58:26 +02:00
|
|
|
const ref* reference,
|
2003-09-10 21:48:53 +02:00
|
|
|
bool get,
|
|
|
|
int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
PAT args;
|
2004-10-30 07:30:08 +02:00
|
|
|
const TEXT *pattern1 =
|
2001-05-23 15:26:42 +02:00
|
|
|
"GDS__GET_SLICE (%V1, %RF%DH%RE, %RF%S1%RE, %S2, %N1, %S3, %N2, %S4, %L1, %S5, %S6);\n";
|
2004-10-30 07:30:08 +02:00
|
|
|
const TEXT *pattern2 =
|
2001-05-23 15:26:42 +02:00
|
|
|
"GDS__PUT_SLICE (%V1, %RF%DH%RE, %RF%S1%RE, %S2, %N1, %S3, %N2, %S4, %L1, %S5);\n";
|
|
|
|
|
|
|
|
if (!(reference->ref_flags & REF_fetch_array))
|
|
|
|
return;
|
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
args.pat_vector1 = status_vector(action); // status vector
|
|
|
|
args.pat_database = action->act_request->req_database; // database handle
|
|
|
|
args.pat_string1 = action->act_request->req_trans; // transaction handle
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2005-01-03 09:07:41 +01:00
|
|
|
TEXT s1[MAX_REF_SIZE], s2[MAX_REF_SIZE], s3[MAX_REF_SIZE], s4[MAX_REF_SIZE];
|
2009-04-22 13:44:39 +02:00
|
|
|
gen_name(s1, reference, true); // blob handle
|
2001-05-23 15:26:42 +02:00
|
|
|
args.pat_string2 = s1;
|
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
args.pat_value1 = reference->ref_sdl_length; // slice descr. length
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
sprintf(s2, "gds__%d", reference->ref_sdl_ident); // slice description
|
2001-05-23 15:26:42 +02:00
|
|
|
args.pat_string3 = s2;
|
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
args.pat_value2 = 0; // parameter length
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
sprintf(s3, "0"); // parameter
|
2001-05-23 15:26:42 +02:00
|
|
|
args.pat_string4 = s3;
|
|
|
|
|
|
|
|
args.pat_long1 = reference->ref_field->fld_array_info->ary_size;
|
2009-04-22 13:44:39 +02:00
|
|
|
// slice size
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (action->act_flags & ACT_sql) {
|
|
|
|
args.pat_string5 = reference->ref_value;
|
|
|
|
}
|
2009-06-28 12:26:25 +02:00
|
|
|
else
|
|
|
|
{
|
2008-12-31 10:35:52 +01:00
|
|
|
sprintf(s4, "gds__%d", reference->ref_field->fld_array_info->ary_ident);
|
2009-04-22 13:44:39 +02:00
|
|
|
args.pat_string5 = s4; // array name
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
args.pat_string6 = "gds__array_length"; // return length
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (get)
|
|
|
|
PATTERN_expand(column, pattern1, &args);
|
|
|
|
else
|
|
|
|
PATTERN_expand(column, pattern2, &args);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate the code to do a get segment.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_get_segment( const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2004-01-28 08:50:41 +01:00
|
|
|
blb* blob;
|
2001-05-23 15:26:42 +02:00
|
|
|
PAT args;
|
2003-10-07 11:58:26 +02:00
|
|
|
const ref* into;
|
2004-10-30 07:30:08 +02:00
|
|
|
const TEXT *pattern1 =
|
2001-05-23 15:26:42 +02:00
|
|
|
"%IFgds__status[2] := %ENGDS__GET_SEGMENT (%V1, %BH, %I1, %S1 (%I2), %RF%I2);";
|
|
|
|
|
|
|
|
if (action->act_error && (action->act_type != ACT_blob_for))
|
2003-09-16 16:01:56 +02:00
|
|
|
begin(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (action->act_flags & ACT_sql)
|
2004-01-28 08:50:41 +01:00
|
|
|
blob = (blb*) action->act_request->req_blobs;
|
2001-05-23 15:26:42 +02:00
|
|
|
else
|
2004-01-28 08:50:41 +01:00
|
|
|
blob = (blb*) action->act_object;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
args.pat_blob = blob;
|
|
|
|
args.pat_vector1 = status_vector(action);
|
2003-09-11 04:13:46 +02:00
|
|
|
args.pat_condition = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
args.pat_ident1 = blob->blb_len_ident;
|
|
|
|
args.pat_ident2 = blob->blb_buff_ident;
|
2003-10-16 10:51:06 +02:00
|
|
|
args.pat_string1 = SIZEOF;
|
2001-05-23 15:26:42 +02:00
|
|
|
PATTERN_expand(column, pattern1, &args);
|
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
if (action->act_flags & ACT_sql)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
into = action->act_object;
|
2003-09-12 18:35:40 +02:00
|
|
|
set_sqlcode(action, column);
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(column, "if (SQLCODE = 0) or (SQLCODE = 101) then");
|
|
|
|
column += INDENT;
|
2003-09-16 16:01:56 +02:00
|
|
|
begin(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
align(column);
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "gds__ftof (gds__%d, gds__%d, %s, gds__%d);",
|
2001-05-23 15:26:42 +02:00
|
|
|
blob->blb_buff_ident, blob->blb_len_ident,
|
|
|
|
into->ref_value, blob->blb_len_ident);
|
2009-06-28 12:26:25 +02:00
|
|
|
if (into->ref_null_value)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
align(column);
|
2009-06-28 12:26:25 +02:00
|
|
|
fprintf(gpreGlob.out_file, "%s := gds__%d;", into->ref_null_value, blob->blb_len_ident);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
2003-09-16 16:01:56 +02:00
|
|
|
endp(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
column -= INDENT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate text to compile and start a stream. This is
|
|
|
|
// used both by START_STREAM and FOR
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_loop( const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-07 11:58:26 +02:00
|
|
|
const gpre_req* request;
|
2004-01-28 08:50:41 +01:00
|
|
|
gpre_port* port;
|
2005-01-03 09:07:41 +01:00
|
|
|
TEXT name[MAX_REF_SIZE];
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
gen_s_start(action, column);
|
|
|
|
request = action->act_request;
|
|
|
|
port = request->req_primary;
|
|
|
|
printa(column, "if SQLCODE = 0 then");
|
|
|
|
column += INDENT;
|
2003-09-16 16:01:56 +02:00
|
|
|
begin(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
gen_receive(action, column, port);
|
2003-09-10 21:48:53 +02:00
|
|
|
gen_name(name, port->por_references, true);
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(column, "if (SQLCODE = 0) and (%s = 0)", name);
|
|
|
|
printa(column + INDENT, "then SQLCODE := 100;");
|
2003-09-16 16:01:56 +02:00
|
|
|
endp(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
column -= INDENT;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate a name for a reference. Name is constructed from
|
|
|
|
// port and parameter idents.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
static TEXT *gen_name(TEXT* const string, const ref* reference, bool as_blob)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
if (reference->ref_field->fld_array_info && !as_blob)
|
2005-01-03 09:07:41 +01:00
|
|
|
fb_utils::snprintf(string, MAX_REF_SIZE, "gds__%d",
|
2001-05-23 15:26:42 +02:00
|
|
|
reference->ref_field->fld_array_info->ary_ident);
|
|
|
|
else
|
2005-01-03 09:07:41 +01:00
|
|
|
fb_utils::snprintf(string, MAX_REF_SIZE, "gds__%d.gds__%d",
|
2001-05-23 15:26:42 +02:00
|
|
|
reference->ref_port->por_ident, reference->ref_ident);
|
|
|
|
|
|
|
|
return string;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate a block to handle errors.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_on_error( const act* action, USHORT column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-06 11:48:44 +02:00
|
|
|
const act* err_action = (const act*) action->act_object;
|
2001-05-23 15:26:42 +02:00
|
|
|
if ((err_action->act_type == ACT_get_segment) ||
|
|
|
|
(err_action->act_type == ACT_put_segment) ||
|
|
|
|
(err_action->act_type == ACT_endblob))
|
|
|
|
printa(column,
|
|
|
|
"if (gds__status [2] <> 0) and (gds__status[2] <> gds__segment) and (gds__status[2] <> gds__segstr_eof) then");
|
|
|
|
else
|
|
|
|
printa(column, "if (gds__status [2] <> 0) then");
|
|
|
|
column += INDENT;
|
2003-09-16 16:01:56 +02:00
|
|
|
begin(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate code for an EXECUTE PROCEDURE.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_procedure( const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
column += INDENT;
|
2004-01-28 08:50:41 +01:00
|
|
|
const gpre_req* request = action->act_request;
|
|
|
|
gpre_port* in_port = request->req_vport;
|
|
|
|
gpre_port* out_port = request->req_primary;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-01-28 08:50:41 +01:00
|
|
|
PAT args;
|
2003-09-11 12:36:45 +02:00
|
|
|
args.pat_database = request->req_database;
|
2001-05-23 15:26:42 +02:00
|
|
|
args.pat_request = action->act_request;
|
|
|
|
args.pat_vector1 = status_vector(action);
|
|
|
|
args.pat_request = request;
|
|
|
|
args.pat_port = in_port;
|
|
|
|
args.pat_port2 = out_port;
|
2008-12-05 02:20:14 +01:00
|
|
|
|
2004-01-28 08:50:41 +01:00
|
|
|
const TEXT* pattern;
|
2001-05-23 15:26:42 +02:00
|
|
|
if (in_port && in_port->por_length)
|
|
|
|
pattern =
|
|
|
|
"isc_transact_request (%V1, %RF%DH%RE, %RF%RT%RE, %VF%RS%VE, %RI, %VF%PL%VE, %RF%PI%RE, %VF%QL%VE, %RF%QI%RE);";
|
|
|
|
else
|
|
|
|
pattern =
|
|
|
|
"isc_transact_request (%V1, %RF%DH%RE, %RF%RT%RE, %VF%RS%VE, %RI, %VF0%VE, 0, %VF%QL%VE, %RF%QI%RE);";
|
|
|
|
|
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
// Get database attach and transaction started
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
if (gpreGlob.sw_auto)
|
2001-05-23 15:26:42 +02:00
|
|
|
t_start_auto(action, 0, status_vector(action), column);
|
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
// Move in input values
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
asgn_from(action, request->req_values, column);
|
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
// Execute the procedure
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
PATTERN_expand(column, pattern, &args);
|
|
|
|
|
2003-09-12 18:35:40 +02:00
|
|
|
set_sqlcode(action, column);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
printa(column, "if SQLCODE = 0 then");
|
|
|
|
column += INDENT;
|
2003-09-16 16:01:56 +02:00
|
|
|
begin(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
// Move out output values
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
asgn_to_proc(request->req_references, column);
|
2003-09-16 16:01:56 +02:00
|
|
|
endp(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate the code to do a put segment.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_put_segment( const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2004-01-28 08:50:41 +01:00
|
|
|
blb* blob;
|
2001-05-23 15:26:42 +02:00
|
|
|
PAT args;
|
2003-10-07 11:58:26 +02:00
|
|
|
const ref* from;
|
2004-10-30 07:30:08 +02:00
|
|
|
const TEXT *pattern1 =
|
2001-05-23 15:26:42 +02:00
|
|
|
"%IFgds__status[2] := %ENGDS__PUT_SEGMENT (%V1, %BH, %I1, %I2);";
|
|
|
|
|
|
|
|
if (!action->act_error)
|
2003-09-16 16:01:56 +02:00
|
|
|
begin(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
if (action->act_error || (action->act_flags & ACT_sql))
|
2003-09-16 16:01:56 +02:00
|
|
|
begin(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
if (action->act_flags & ACT_sql)
|
|
|
|
{
|
2004-01-28 08:50:41 +01:00
|
|
|
blob = (blb*) action->act_request->req_blobs;
|
2001-05-23 15:26:42 +02:00
|
|
|
from = action->act_object;
|
|
|
|
align(column);
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "gds__%d := %s;",
|
2001-05-23 15:26:42 +02:00
|
|
|
blob->blb_len_ident, from->ref_null_value);
|
|
|
|
align(column);
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "gds__ftof (%s, gds__%d, gds__%d, gds__%d);",
|
2001-05-23 15:26:42 +02:00
|
|
|
from->ref_value, blob->blb_len_ident,
|
|
|
|
blob->blb_buff_ident, blob->blb_len_ident);
|
|
|
|
}
|
|
|
|
else
|
2004-01-28 08:50:41 +01:00
|
|
|
blob = (blb*) action->act_object;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
args.pat_blob = blob;
|
|
|
|
args.pat_vector1 = status_vector(action);
|
2003-09-11 04:13:46 +02:00
|
|
|
args.pat_condition = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
args.pat_ident1 = blob->blb_len_ident;
|
|
|
|
args.pat_ident2 = blob->blb_buff_ident;
|
|
|
|
PATTERN_expand(column, pattern1, &args);
|
|
|
|
|
2003-09-12 18:35:40 +02:00
|
|
|
set_sqlcode(action, column);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (action->act_flags & ACT_sql)
|
2003-09-16 16:01:56 +02:00
|
|
|
endp(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate BLR in raw, numeric form. Ughly but dense.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-05-01 19:21:36 +02:00
|
|
|
static void gen_raw(const UCHAR* blr, int request_length) //, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-29 11:53:47 +01:00
|
|
|
TEXT buffer[80];
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-29 11:53:47 +01:00
|
|
|
TEXT* p = buffer;
|
|
|
|
const TEXT* const limit = buffer + 60;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
for (const UCHAR* const end = blr + request_length - 1; blr <= end; blr++)
|
|
|
|
{
|
2003-10-29 11:53:47 +01:00
|
|
|
const UCHAR c = *blr;
|
2001-05-23 15:26:42 +02:00
|
|
|
if ((c >= 'A' && c <= 'Z') || c == '$' || c == '_')
|
|
|
|
sprintf(p, "'%c'", c);
|
|
|
|
else
|
|
|
|
sprintf(p, "chr(%d)", c);
|
|
|
|
while (*p)
|
|
|
|
p++;
|
|
|
|
if (blr != end)
|
|
|
|
*p++ = ',';
|
|
|
|
if (p < limit)
|
|
|
|
continue;
|
|
|
|
*p = 0;
|
|
|
|
printa(INDENT, buffer);
|
|
|
|
p = buffer;
|
|
|
|
}
|
|
|
|
|
|
|
|
*p = 0;
|
|
|
|
printa(INDENT, buffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate substitution text for READY
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_ready( const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2004-06-05 11:37:18 +02:00
|
|
|
const TEXT* vector = status_vector(action);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-06-05 11:37:18 +02:00
|
|
|
for (rdy* ready = (rdy*) action->act_object; ready; ready = ready->rdy_next)
|
|
|
|
{
|
2009-04-22 13:44:39 +02:00
|
|
|
const gpre_dbb* db = ready->rdy_database;
|
2004-06-05 11:37:18 +02:00
|
|
|
const TEXT* filename = ready->rdy_filename;
|
|
|
|
if (!filename)
|
2001-05-23 15:26:42 +02:00
|
|
|
filename = db->dbb_runtime;
|
2008-12-29 11:26:36 +01:00
|
|
|
if ((action->act_error || (action->act_flags & ACT_sql)) && ready != (rdy*) action->act_object)
|
2004-06-05 11:37:18 +02:00
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(column, "if (gds__status[2] = 0) then begin");
|
2004-06-05 11:37:18 +02:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
make_ready(db, filename, vector, column, ready->rdy_request);
|
|
|
|
if ((action->act_error || (action->act_flags & ACT_sql)) &&
|
2004-01-28 08:50:41 +01:00
|
|
|
ready != (rdy*) action->act_object)
|
2004-06-05 11:37:18 +02:00
|
|
|
{
|
2003-09-16 16:01:56 +02:00
|
|
|
endp(column);
|
2004-06-05 11:37:18 +02:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
2003-09-12 18:35:40 +02:00
|
|
|
set_sqlcode(action, column);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate receive call for a port.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-01-28 08:50:41 +01:00
|
|
|
static void gen_receive( const act* action, int column, const gpre_port* port)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
align(column);
|
|
|
|
|
2003-10-29 11:53:47 +01:00
|
|
|
const gpre_req* request = action->act_request;
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "GDS__RECEIVE (%s, %s, %d, %d, %sgds__%d, %s);",
|
2001-05-23 15:26:42 +02:00
|
|
|
status_vector(action),
|
|
|
|
request->req_handle,
|
|
|
|
port->por_msg_number,
|
|
|
|
port->por_length,
|
|
|
|
REF_PAR, port->por_ident, request->req_request_level);
|
|
|
|
|
2003-09-12 18:35:40 +02:00
|
|
|
set_sqlcode(action, column);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate substitution text for RELEASE_REQUESTS
|
|
|
|
// For active databases, call gds__release_request.
|
|
|
|
// for all others, just zero the handle. For the
|
|
|
|
// release request calls, ignore error returns, which
|
|
|
|
// are likely if the request was compiled on a database
|
|
|
|
// which has been released and re-readied. If there is
|
|
|
|
// a serious error, it will be caught on the next statement.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_release( const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2009-01-14 09:22:32 +01:00
|
|
|
const gpre_dbb* exp_db = (gpre_dbb*) action->act_object;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
for (const gpre_req* request = gpreGlob.requests; request; request = request->req_next)
|
|
|
|
{
|
2009-01-14 09:22:32 +01:00
|
|
|
const gpre_dbb* db = request->req_database;
|
2001-05-23 15:26:42 +02:00
|
|
|
if (exp_db && db != exp_db)
|
|
|
|
continue;
|
2009-06-28 12:26:25 +02:00
|
|
|
if (!(request->req_flags & REQ_exp_hand))
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(column, "if %s <> NIL then", db->dbb_name->sym_string);
|
|
|
|
printa(column + INDENT, "gds__release_request (gds__status, %s);",
|
|
|
|
request->req_handle);
|
|
|
|
printa(column, "%s := NIL;", request->req_handle);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate definitions associated with a single request.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-07 11:58:26 +02:00
|
|
|
static void gen_request( const gpre_req* request, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2009-04-22 13:44:39 +02:00
|
|
|
// generate request handle, blob handles, and ports
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-16 10:51:06 +02:00
|
|
|
const TEXT* sw_volatile = FB_DP_VOLATILE;
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(column, " ");
|
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
if (!(request->req_flags & (REQ_exp_hand | REQ_sql_blob_open | REQ_sql_blob_create)) &&
|
|
|
|
request->req_type != REQ_slice && request->req_type != REQ_procedure)
|
2003-09-11 04:13:46 +02:00
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(column, "%s\t: %s gds__handle := nil;\t\t(* request handle *)",
|
|
|
|
request->req_handle, sw_volatile);
|
2003-09-11 04:13:46 +02:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (request->req_flags & (REQ_sql_blob_open | REQ_sql_blob_create))
|
2008-12-29 11:26:36 +01:00
|
|
|
printa(column, "gds__%ds\t: %s gds__handle := nil;\t\t(* SQL statement handle *)",
|
2001-05-23 15:26:42 +02:00
|
|
|
request->req_ident, sw_volatile);
|
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
// generate actual BLR string
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
if (request->req_length)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(column, " ");
|
|
|
|
if (request->req_flags & REQ_sql_cursor)
|
2008-12-29 11:26:36 +01:00
|
|
|
printa(column, "gds__%ds\t: %s gds__handle := nil;\t\t(* SQL statement handle *)",
|
2001-05-23 15:26:42 +02:00
|
|
|
request->req_ident, sw_volatile);
|
|
|
|
printa(column, "gds__%dl\t: %s := %d;\t\t(* request length *)",
|
|
|
|
request->req_ident, SHORT_DCL, request->req_length);
|
|
|
|
printa(column, "gds__%d\t: %s [1..%d] of char := %s",
|
2008-12-29 11:26:36 +01:00
|
|
|
request->req_ident, PACKED_ARRAY, request->req_length, OPEN_BRACKET);
|
2003-10-29 11:53:47 +01:00
|
|
|
const TEXT* string_type = "BLR";
|
2008-12-29 11:26:36 +01:00
|
|
|
if (gpreGlob.sw_raw)
|
|
|
|
{
|
2009-05-01 19:21:36 +02:00
|
|
|
gen_raw(request->req_blr, request->req_length); //, column);
|
2008-12-29 11:26:36 +01:00
|
|
|
switch (request->req_type)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
case REQ_create_database:
|
|
|
|
case REQ_ready:
|
|
|
|
string_type = "DPB";
|
|
|
|
break;
|
|
|
|
|
|
|
|
case REQ_ddl:
|
|
|
|
string_type = "DYN";
|
|
|
|
break;
|
|
|
|
case REQ_slice:
|
|
|
|
string_type = "SDL";
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
string_type = "BLR";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2009-01-14 09:22:32 +01:00
|
|
|
switch (request->req_type)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
case REQ_create_database:
|
|
|
|
case REQ_ready:
|
|
|
|
string_type = "DPB";
|
2003-09-28 23:36:05 +02:00
|
|
|
if (PRETTY_print_cdb(request->req_blr, gen_blr, 0, 1))
|
2003-10-15 00:22:32 +02:00
|
|
|
CPR_error("internal error during parameter generation");
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case REQ_ddl:
|
|
|
|
string_type = "DYN";
|
2003-09-28 23:36:05 +02:00
|
|
|
if (PRETTY_print_dyn(request->req_blr, gen_blr, 0, 1))
|
2003-10-15 00:22:32 +02:00
|
|
|
CPR_error("internal error during dynamic DDL generation");
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
case REQ_slice:
|
|
|
|
string_type = "SDL";
|
2003-09-28 23:36:05 +02:00
|
|
|
if (PRETTY_print_sdl(request->req_blr, gen_blr, 0, 1))
|
2003-10-15 00:22:32 +02:00
|
|
|
CPR_error("internal error during SDL generation");
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
string_type = "BLR";
|
2009-08-03 17:52:48 +02:00
|
|
|
if (fb_print_blr(request->req_blr, request->req_length, gen_blr, 0, 1))
|
2003-10-15 00:22:32 +02:00
|
|
|
CPR_error("internal error during BLR generation");
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
printa(column, "%s;\t(* end of %s string for request gds__%d *)\n",
|
|
|
|
CLOSE_BRACKET, string_type, request->req_ident);
|
|
|
|
}
|
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
// Print out slice description language if there are arrays associated with request
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-01-28 08:50:41 +01:00
|
|
|
for (const gpre_port* port = request->req_ports; port; port = port->por_next)
|
2008-12-29 11:26:36 +01:00
|
|
|
for (const ref* reference = port->por_references; reference; reference = reference->ref_next)
|
2003-09-13 14:22:11 +02:00
|
|
|
{
|
2009-06-28 12:26:25 +02:00
|
|
|
if (reference->ref_sdl)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(column, "gds__%d\t: %s [1..%d] of char := %s",
|
|
|
|
reference->ref_sdl_ident, PACKED_ARRAY,
|
|
|
|
reference->ref_sdl_length, OPEN_BRACKET);
|
2004-05-24 19:13:38 +02:00
|
|
|
if (gpreGlob.sw_raw)
|
2009-05-01 19:21:36 +02:00
|
|
|
gen_raw(reference->ref_sdl, reference->ref_sdl_length); //, column);
|
2003-09-28 23:36:05 +02:00
|
|
|
else if (PRETTY_print_sdl(reference->ref_sdl, gen_blr, 0, 1))
|
2003-10-15 00:22:32 +02:00
|
|
|
CPR_error("internal error during SDL generation");
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(column, "%s; \t(* end of SDL string for gds__%d *)\n",
|
|
|
|
CLOSE_BRACKET, reference->ref_sdl_ident);
|
|
|
|
}
|
2003-09-13 14:22:11 +02:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
// Print out any blob parameter blocks required
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-29 11:53:47 +01:00
|
|
|
for (const blb* blob = request->req_blobs; blob; blob = blob->blb_next)
|
2009-06-28 12:26:25 +02:00
|
|
|
if (blob->blb_bpb_length)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(column, "gds__%d\t: %s [1..%d] of char := %s",
|
2008-12-29 11:26:36 +01:00
|
|
|
blob->blb_bpb_ident, PACKED_ARRAY, blob->blb_bpb_length, OPEN_BRACKET);
|
2009-05-01 19:21:36 +02:00
|
|
|
gen_raw(blob->blb_bpb, blob->blb_bpb_length); //, column);
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(column, "%s;\n", CLOSE_BRACKET);
|
|
|
|
}
|
2009-04-22 13:44:39 +02:00
|
|
|
// If this is GET_SLICE/PUT_SLICE, allocate some variables
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-06-28 12:26:25 +02:00
|
|
|
if (request->req_type == REQ_slice)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(column, "gds__%dv\t: array [1..%d] of %s;",
|
2008-12-29 11:26:36 +01:00
|
|
|
request->req_ident, MAX(request->req_slice->slc_parameters, 1), LONG_DCL);
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(column, "gds__%ds\t: %s;", request->req_ident, LONG_DCL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate receive call for a port
|
|
|
|
// in a store2 statement.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_return_value( const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2008-12-29 11:26:36 +01:00
|
|
|
const gpre_req* request = action->act_request;
|
2001-05-23 15:26:42 +02:00
|
|
|
if (action->act_pair->act_error)
|
|
|
|
column += INDENT;
|
|
|
|
gen_start(action, request->req_primary, column);
|
2008-12-29 11:26:36 +01:00
|
|
|
const upd* update = (upd*) action->act_object;
|
|
|
|
const ref* reference = update->upd_references;
|
2001-05-23 15:26:42 +02:00
|
|
|
gen_receive(action, column, reference->ref_port);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2004-05-24 19:13:38 +02:00
|
|
|
// Process routine head. If there are gpreGlob.requests in the
|
2001-05-23 15:26:42 +02:00
|
|
|
// routine, insert local definitions.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_routine( const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
column += INDENT;
|
|
|
|
|
2003-10-29 11:53:47 +01:00
|
|
|
for (const gpre_req* request = (const gpre_req*) action->act_object; request;
|
2008-12-05 02:20:14 +01:00
|
|
|
request = request->req_routine)
|
2003-10-29 11:53:47 +01:00
|
|
|
{
|
2008-12-29 11:26:36 +01:00
|
|
|
gpre_port* port;
|
|
|
|
|
2009-06-28 12:26:25 +02:00
|
|
|
for (port = request->req_ports; port; port = port->por_next)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(column - INDENT, "type");
|
|
|
|
make_port(port, column);
|
|
|
|
}
|
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
// Only write a var reserved word if there are variables which will be
|
|
|
|
// associated with a var section. Fix for bug#809. mao 03/22/89
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (request->req_ports) {
|
|
|
|
printa(column - INDENT, "var");
|
|
|
|
}
|
|
|
|
|
|
|
|
for (port = request->req_ports; port; port = port->por_next)
|
2008-12-29 11:26:36 +01:00
|
|
|
printa(column, "gds__%d\t: gds__%dt;\t\t\t(* message *)", port->por_ident, port->por_ident);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-06-28 12:26:25 +02:00
|
|
|
for (const blb* blob = request->req_blobs; blob; blob = blob->blb_next)
|
|
|
|
{
|
2008-12-29 11:26:36 +01:00
|
|
|
printa(column, "gds__%d\t: gds__handle;\t\t\t(* blob handle *)", blob->blb_ident);
|
|
|
|
printa(column, "gds__%d\t: %s [1 .. %d] of char;\t(* blob segment *)",
|
2001-05-23 15:26:42 +02:00
|
|
|
blob->blb_buff_ident, PACKED_ARRAY, blob->blb_seg_length);
|
2008-12-29 11:26:36 +01:00
|
|
|
printa(column, "gds__%d\t: %s;\t\t\t(* segment length *)", blob->blb_len_ident, SHORT_DCL);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
column -= INDENT;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate substitution text for END_STREAM.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_s_end( const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
if (action->act_error)
|
2003-09-16 16:01:56 +02:00
|
|
|
begin(column);
|
2003-10-29 11:53:47 +01:00
|
|
|
|
|
|
|
const gpre_req* request = action->act_request;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (action->act_type == ACT_close)
|
|
|
|
column = gen_cursor_close(action, request, column);
|
|
|
|
|
|
|
|
printa(column, "GDS__UNWIND_REQUEST (%s, %s, %s);",
|
2008-12-29 11:26:36 +01:00
|
|
|
status_vector(action), request->req_handle, request->req_request_level);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-06-28 12:26:25 +02:00
|
|
|
if (action->act_type == ACT_close)
|
|
|
|
{
|
2003-09-16 16:01:56 +02:00
|
|
|
endp(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
column -= INDENT;
|
2003-09-16 16:01:56 +02:00
|
|
|
ends(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
column -= INDENT;
|
|
|
|
}
|
|
|
|
|
2003-09-12 18:35:40 +02:00
|
|
|
set_sqlcode(action, column);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate substitution text for FETCH.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_s_fetch( const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-29 11:53:47 +01:00
|
|
|
const gpre_req* request = action->act_request;
|
2001-05-23 15:26:42 +02:00
|
|
|
if (request->req_sync)
|
|
|
|
gen_send(action, request->req_sync, column);
|
|
|
|
|
|
|
|
gen_receive(action, column, request->req_primary);
|
|
|
|
if (!action->act_pair && !action->act_error)
|
2003-09-16 16:01:56 +02:00
|
|
|
endp(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate text to compile and start a stream. This is
|
|
|
|
// used both by START_STREAM and FOR
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_s_start( const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-29 11:53:47 +01:00
|
|
|
const gpre_req* request = action->act_request;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
gen_compile(action, column);
|
|
|
|
|
|
|
|
if (action->act_type == ACT_open)
|
|
|
|
column = gen_cursor_open(action, request, column);
|
|
|
|
|
2004-01-28 08:50:41 +01:00
|
|
|
const gpre_port* port = request->req_vport;
|
2003-10-29 11:53:47 +01:00
|
|
|
if (port)
|
2001-05-23 15:26:42 +02:00
|
|
|
asgn_from(action, port->por_references, column);
|
|
|
|
|
2009-06-28 12:26:25 +02:00
|
|
|
if (action->act_error || (action->act_flags & ACT_sql))
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
make_ok_test(action, request, column);
|
|
|
|
column += INDENT;
|
|
|
|
}
|
|
|
|
|
|
|
|
gen_start(action, port, column);
|
|
|
|
|
|
|
|
if (action->act_error || (action->act_flags & ACT_sql))
|
|
|
|
column -= INDENT;
|
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
if (action->act_type == ACT_open)
|
|
|
|
{
|
2003-09-16 16:01:56 +02:00
|
|
|
endp(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
column -= INDENT;
|
2003-09-16 16:01:56 +02:00
|
|
|
endp(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
column -= INDENT;
|
2003-09-16 16:01:56 +02:00
|
|
|
ends(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
column -= INDENT;
|
|
|
|
}
|
|
|
|
|
2003-09-12 18:35:40 +02:00
|
|
|
set_sqlcode(action, column);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Substitute for a segment, segment length, or blob handle.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_segment( const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2004-01-28 08:50:41 +01:00
|
|
|
const blb* blob = (blb*) action->act_object;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
printa(column, "gds__%d",
|
2008-12-27 08:00:40 +01:00
|
|
|
(action->act_type == ACT_segment) ?
|
|
|
|
blob->blb_buff_ident : (action->act_type == ACT_segment_length) ?
|
|
|
|
blob->blb_len_ident : blob->blb_ident);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_select( const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2005-01-03 09:07:41 +01:00
|
|
|
TEXT name[MAX_REF_SIZE];
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-29 11:53:47 +01:00
|
|
|
const gpre_req* request = action->act_request;
|
2004-01-28 08:50:41 +01:00
|
|
|
const gpre_port* port = request->req_primary;
|
2003-09-10 21:48:53 +02:00
|
|
|
gen_name(name, request->req_eof, true);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
gen_s_start(action, column);
|
2003-09-16 16:01:56 +02:00
|
|
|
begin(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
gen_receive(action, column, port);
|
|
|
|
printa(column, "if SQLCODE = 0 then", name);
|
|
|
|
column += INDENT;
|
|
|
|
printa(column, "if %s <> 0 then", name);
|
|
|
|
column += INDENT;
|
|
|
|
|
2003-09-16 16:01:56 +02:00
|
|
|
begin(column);
|
2008-12-25 08:46:53 +01:00
|
|
|
const gpre_nod* var_list = (gpre_nod*) action->act_object;
|
2009-06-28 12:26:25 +02:00
|
|
|
if (var_list)
|
|
|
|
{
|
|
|
|
for (int i = 0; i < var_list->nod_count; i++)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
align(column);
|
2003-10-07 11:58:26 +02:00
|
|
|
asgn_to(action, reinterpret_cast<const ref*>(var_list->nod_arg[i]), column);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
2003-10-29 11:53:47 +01:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
printa(column - INDENT, "else");
|
|
|
|
printa(column, "SQLCODE := 100;");
|
|
|
|
column -= INDENT;
|
2003-09-16 16:01:56 +02:00
|
|
|
ends(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate a send or receive call for a port.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-01-28 08:50:41 +01:00
|
|
|
static void gen_send( const act* action, const gpre_port* port, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-29 11:53:47 +01:00
|
|
|
const gpre_req* request = action->act_request;
|
2001-05-23 15:26:42 +02:00
|
|
|
align(column);
|
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "GDS__SEND (%s, %s, %d, %d, gds__%d, %s);",
|
2001-05-23 15:26:42 +02:00
|
|
|
status_vector(action),
|
2008-12-29 11:26:36 +01:00
|
|
|
request->req_handle, port->por_msg_number,
|
2001-05-23 15:26:42 +02:00
|
|
|
port->por_length, port->por_ident, request->req_request_level);
|
|
|
|
|
2003-09-12 18:35:40 +02:00
|
|
|
set_sqlcode(action, column);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate support for get/put slice statement.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_slice( const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-07 11:58:26 +02:00
|
|
|
const TEXT* pattern1 =
|
2001-05-23 15:26:42 +02:00
|
|
|
"GDS__GET_SLICE (%V1, %RF%DH%RE, %RF%RT%RE, %RF%FR%RE, %N1, \
|
|
|
|
%I1, %N2, %I1v, %I1s, %RF%S5%RE, %RF%S6%RE);";
|
2003-10-07 11:58:26 +02:00
|
|
|
const TEXT* pattern2 =
|
2001-05-23 15:26:42 +02:00
|
|
|
"GDS__PUT_SLICE (%V1, %RF%DH%RE, %RF%RT%RE, %RF%FR%RE, %N1, \
|
|
|
|
%I1, %N2, %I1v, %I1s, %RF%S5%RE);";
|
|
|
|
|
2003-10-07 11:58:26 +02:00
|
|
|
const gpre_req* request = action->act_request;
|
2009-04-24 17:26:46 +02:00
|
|
|
const slc* slice = (slc*) action->act_object;
|
2003-10-07 11:58:26 +02:00
|
|
|
const gpre_req* parent_request = slice->slc_parent_request;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
// Compute array size
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
printa(column, "gds__%ds := %d", request->req_ident,
|
|
|
|
slice->slc_field->fld_array->fld_length);
|
|
|
|
|
2009-04-24 17:26:46 +02:00
|
|
|
const slc::slc_repeat *tail, *end;
|
2008-12-29 11:26:36 +01:00
|
|
|
for (tail = slice->slc_rpt, end = tail + slice->slc_dimensions; tail < end; ++tail)
|
2008-12-31 21:22:10 +01:00
|
|
|
{
|
2009-06-28 12:26:25 +02:00
|
|
|
if (tail->slc_upper != tail->slc_lower)
|
|
|
|
{
|
2003-10-07 11:58:26 +02:00
|
|
|
const ref* lower = (const ref*) tail->slc_lower->nod_arg[0];
|
|
|
|
const ref* upper = (const ref*) tail->slc_upper->nod_arg[0];
|
2001-05-23 15:26:42 +02:00
|
|
|
if (lower->ref_value)
|
2008-12-29 11:26:36 +01:00
|
|
|
fprintf(gpreGlob.out_file, " * ( %s - %s + 1)", upper->ref_value, lower->ref_value);
|
2001-05-23 15:26:42 +02:00
|
|
|
else
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, " * ( %s + 1)", upper->ref_value);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
2008-12-31 21:22:10 +01:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, ";");
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
// Make assignments to variable vector
|
2003-10-07 11:58:26 +02:00
|
|
|
const ref* reference;
|
2008-12-29 11:26:36 +01:00
|
|
|
for (reference = request->req_values; reference; reference = reference->ref_next)
|
2003-10-07 11:58:26 +02:00
|
|
|
{
|
|
|
|
printa(column, "gds__%dv [%d] := %s;",
|
2008-12-29 11:26:36 +01:00
|
|
|
request->req_ident, reference->ref_id, reference->ref_value);
|
2003-10-07 11:58:26 +02:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
PAT args;
|
2001-05-23 15:26:42 +02:00
|
|
|
args.pat_reference = slice->slc_field_ref;
|
2008-12-05 02:20:14 +01:00
|
|
|
args.pat_request = parent_request; // blob id request
|
|
|
|
args.pat_vector1 = status_vector(action); // status vector
|
|
|
|
args.pat_database = parent_request->req_database; // database handle
|
|
|
|
args.pat_string1 = action->act_request->req_trans; // transaction handle
|
|
|
|
args.pat_value1 = request->req_length; // slice descr. length
|
|
|
|
args.pat_ident1 = request->req_ident; // request name
|
|
|
|
args.pat_value2 = slice->slc_parameters * sizeof(SLONG); // parameter length
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-07 11:58:26 +02:00
|
|
|
reference = (const ref*) slice->slc_array->nod_arg[0];
|
2008-12-05 02:20:14 +01:00
|
|
|
args.pat_string5 = reference->ref_value; // array name
|
2001-05-23 15:26:42 +02:00
|
|
|
args.pat_string6 = "gds__array_length";
|
|
|
|
|
2008-12-27 08:00:40 +01:00
|
|
|
PATTERN_expand(column, (action->act_type == ACT_get_slice) ? pattern1 : pattern2, &args);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate either a START or START_AND_SEND depending
|
|
|
|
// on whether or a not a port is present.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-01-28 08:50:41 +01:00
|
|
|
static void gen_start( const act* action, const gpre_port* port, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-10-29 11:53:47 +01:00
|
|
|
const gpre_req* request = action->act_request;
|
|
|
|
const TEXT* vector = status_vector(action);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
align(column);
|
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
if (port)
|
|
|
|
{
|
2008-12-29 11:26:36 +01:00
|
|
|
for (const ref* reference = port->por_references; reference; reference = reference->ref_next)
|
2003-09-13 14:22:11 +02:00
|
|
|
{
|
|
|
|
if (reference->ref_field->fld_array_info)
|
2008-12-29 11:26:36 +01:00
|
|
|
gen_get_or_put_slice(action, reference, false, column);
|
2003-09-13 14:22:11 +02:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
fprintf(gpreGlob.out_file, "GDS__START_AND_SEND (%s, %s, %s, %d, %d, gds__%d, %s);",
|
|
|
|
vector, request->req_handle, request_trans(action, request),
|
2001-05-23 15:26:42 +02:00
|
|
|
port->por_msg_number, port->por_length, port->por_ident,
|
|
|
|
request->req_request_level);
|
|
|
|
}
|
|
|
|
else
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "GDS__START_REQUEST (%s, %s, %s, %s);",
|
2008-12-29 11:26:36 +01:00
|
|
|
vector, request->req_handle, request_trans(action, request),
|
2001-05-23 15:26:42 +02:00
|
|
|
request->req_request_level);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate text for STORE statement. This includes the compile
|
|
|
|
// call and any variable initialization required.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_store( const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2008-12-29 11:26:36 +01:00
|
|
|
const gpre_req* request = action->act_request;
|
2001-05-23 15:26:42 +02:00
|
|
|
gen_compile(action, column);
|
2009-06-28 12:26:25 +02:00
|
|
|
if (action->act_error || (action->act_flags & ACT_sql))
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
make_ok_test(action, request, column);
|
|
|
|
column += INDENT;
|
|
|
|
if (action->act_error)
|
2003-09-16 16:01:56 +02:00
|
|
|
begin(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
// Initialize any blob fields
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2005-01-03 09:07:41 +01:00
|
|
|
TEXT name[MAX_REF_SIZE];
|
2008-12-29 11:26:36 +01:00
|
|
|
const gpre_port* port = request->req_primary;
|
|
|
|
for (const ref* reference = port->por_references; reference; reference = reference->ref_next)
|
2004-12-24 09:52:39 +01:00
|
|
|
{
|
2008-12-29 11:26:36 +01:00
|
|
|
const gpre_fld* field = reference->ref_field;
|
2001-05-23 15:26:42 +02:00
|
|
|
if (field->fld_flags & FLD_blob)
|
2008-12-29 11:26:36 +01:00
|
|
|
printa(column, "%s := gds__blob_null;\n", gen_name(name, reference, true));
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate substitution text for START_TRANSACTION.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_t_start( const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2009-04-22 13:44:39 +02:00
|
|
|
// for automatically generated transactions, and transactions that are
|
|
|
|
// explicitly started, but don't have any arguments so don't get a TPB,
|
|
|
|
// generate something plausible.
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
gpre_tra* trans;
|
2009-06-28 12:26:25 +02:00
|
|
|
if (!action || !(trans = (gpre_tra*) action->act_object))
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
t_start_auto(action, 0, status_vector(action), column);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
// build a complete statement, including tpb's.
|
|
|
|
// first generate any appropriate ready statements,
|
|
|
|
// On non-VMS machines, fill in the tpb vector (aka TEB).
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
int count = 0;
|
2009-04-22 13:44:39 +02:00
|
|
|
for (const tpb* tpb_val = trans->tra_tpb; tpb_val; tpb_val = tpb_val->tpb_tra_next)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
count++;
|
2009-04-22 13:44:39 +02:00
|
|
|
const gpre_dbb* db = tpb_val->tpb_database;
|
2004-05-24 19:13:38 +02:00
|
|
|
if (gpreGlob.sw_auto)
|
2004-11-08 04:33:26 +01:00
|
|
|
{
|
|
|
|
const TEXT* filename = db->dbb_runtime;
|
2009-06-28 12:26:25 +02:00
|
|
|
if (filename || !(db->dbb_flags & DBB_sqlca))
|
|
|
|
{
|
2008-12-29 11:26:36 +01:00
|
|
|
printa(column, "if (%s = nil) then", db->dbb_name->sym_string);
|
|
|
|
make_ready(db, filename, status_vector(action), column + INDENT, 0);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
2004-11-08 04:33:26 +01:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-09-05 16:55:59 +02:00
|
|
|
printa(column, "gds__teb[%d].tpb_len := %d;", count, tpb_val->tpb_length);
|
2008-12-29 11:26:36 +01:00
|
|
|
printa(column, "gds__teb[%d].tpb_ptr := ADDR(gds__tpb_%d);", count, tpb_val->tpb_ident);
|
|
|
|
printa(column, "gds__teb[%d].dbb_ptr := ADDR(%s);", count, db->dbb_name->sym_string);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
printa(column, "GDS__START_MULTIPLE (%s, %s, %d, gds__teb);",
|
2008-12-29 11:26:36 +01:00
|
|
|
status_vector(action), trans->tra_handle ? trans->tra_handle : "gds__trans",
|
2001-05-23 15:26:42 +02:00
|
|
|
trans->tra_db_count);
|
|
|
|
|
2003-09-12 18:35:40 +02:00
|
|
|
set_sqlcode(action, column);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate a TPB in the output file
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
static void gen_tpb( const tpb* tpb_val, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2008-12-29 11:26:36 +01:00
|
|
|
TEXT buffer[80];
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
printa(column, "gds__tpb_%d\t: %s [1..%d] of char := %s",
|
2003-09-05 16:55:59 +02:00
|
|
|
tpb_val->tpb_ident, PACKED_ARRAY, tpb_val->tpb_length, OPEN_BRACKET);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-01-28 08:50:41 +01:00
|
|
|
int length = tpb_val->tpb_length;
|
2004-11-10 05:26:45 +01:00
|
|
|
const TEXT* text = (TEXT *) tpb_val->tpb_string;
|
2004-01-28 08:50:41 +01:00
|
|
|
TEXT* p = buffer;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
while (--length)
|
|
|
|
{
|
2008-12-29 11:26:36 +01:00
|
|
|
const TEXT c = *text++;
|
2001-05-23 15:26:42 +02:00
|
|
|
if ((c >= 'A' && c <= 'Z') || c == '$' || c == '_')
|
|
|
|
sprintf(p, "'%c', ", c);
|
|
|
|
else
|
|
|
|
sprintf(p, "chr(%d), ", c);
|
|
|
|
while (*p)
|
|
|
|
p++;
|
2009-06-28 12:26:25 +02:00
|
|
|
if (p - buffer > 60)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
align(column + INDENT);
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, " %s", buffer);
|
2001-05-23 15:26:42 +02:00
|
|
|
p = buffer;
|
|
|
|
*p = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
// handle the last character
|
2008-12-29 11:26:36 +01:00
|
|
|
TEXT c = *text++;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if ((c >= 'A' && c <= 'Z') || c == '$' || c == '_')
|
|
|
|
sprintf(p, "'%c',", c);
|
|
|
|
else
|
|
|
|
sprintf(p, "chr(%d)", c);
|
|
|
|
|
|
|
|
align(column + INDENT);
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "%s", buffer);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
printa(column, "%s;\n", CLOSE_BRACKET);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate substitution text for COMMIT, ROLLBACK, PREPARE, and SAVE
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_trans( const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
align(column);
|
|
|
|
|
2008-12-27 08:00:40 +01:00
|
|
|
const char* tranText = action->act_object ? (const TEXT*) action->act_object : "gds__trans";
|
|
|
|
|
|
|
|
switch (action->act_type)
|
|
|
|
{
|
|
|
|
case ACT_commit_retain_context:
|
|
|
|
fprintf(gpreGlob.out_file, "GDS__COMMIT_RETAINING (%s, %s);", status_vector(action), tranText);
|
|
|
|
break;
|
|
|
|
case ACT_rollback_retain_context:
|
|
|
|
fprintf(gpreGlob.out_file, "GDS__ROLLBACK_RETAINING (%s, %s);", status_vector(action), tranText);
|
|
|
|
break;
|
|
|
|
default:
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "GDS__%s_TRANSACTION (%s, %s);",
|
2004-12-16 04:03:13 +01:00
|
|
|
(action->act_type == ACT_commit) ?
|
2008-12-27 08:00:40 +01:00
|
|
|
"COMMIT" : (action->act_type == ACT_rollback) ? "ROLLBACK" : "PREPARE",
|
|
|
|
status_vector(action), tranText);
|
2008-01-16 08:15:01 +01:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-09-12 18:35:40 +02:00
|
|
|
set_sqlcode(action, column);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate substitution text for UPDATE ... WHERE CURRENT OF ...
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_update( const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2008-12-29 11:26:36 +01:00
|
|
|
const upd* modify = (upd*) action->act_object;
|
|
|
|
const gpre_port* port = modify->upd_port;
|
2001-05-23 15:26:42 +02:00
|
|
|
asgn_from(action, port->por_references, column);
|
|
|
|
gen_send(action, port, column);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Substitute for a variable reference.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-06 11:48:44 +02:00
|
|
|
static void gen_variable( const act* action, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2005-01-03 09:07:41 +01:00
|
|
|
TEXT s[MAX_REF_SIZE];
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-09-10 21:48:53 +02:00
|
|
|
printa(column, gen_name(s, action->act_object, false));
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate tests for any WHENEVER clauses that may have been declared.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-07 11:58:26 +02:00
|
|
|
static void gen_whenever( const swe* label, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2008-12-31 10:35:52 +01:00
|
|
|
const TEXT* condition = NULL;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (label)
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, ";");
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-31 10:35:52 +01:00
|
|
|
while (label)
|
|
|
|
{
|
|
|
|
switch (label->swe_condition)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
case SWE_error:
|
|
|
|
condition = "SQLCODE < 0";
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SWE_warning:
|
|
|
|
condition = "(SQLCODE > 0) AND (SQLCODE <> 100)";
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SWE_not_found:
|
|
|
|
condition = "SQLCODE = 100";
|
|
|
|
break;
|
2008-12-31 10:35:52 +01:00
|
|
|
|
|
|
|
default:
|
|
|
|
// condition undefined
|
|
|
|
fb_assert(false);
|
|
|
|
return;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
align(column);
|
2008-12-29 11:26:36 +01:00
|
|
|
fprintf(gpreGlob.out_file, "if %s then goto %s;", condition, label->swe_label);
|
2001-05-23 15:26:42 +02:00
|
|
|
label = label->swe_next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate a declaration of an array in the
|
|
|
|
// output file.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-07 11:58:26 +02:00
|
|
|
static void make_array_declaration( const ref* reference)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2008-12-29 11:26:36 +01:00
|
|
|
const gpre_fld* field = reference->ref_field;
|
2003-10-06 11:48:44 +02:00
|
|
|
const TEXT* name = field->fld_symbol->sym_string;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
// Don't generate multiple declarations for the array. V3 Bug 569.
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (field->fld_array_info->ary_declared)
|
|
|
|
return;
|
|
|
|
|
2003-09-11 04:13:46 +02:00
|
|
|
field->fld_array_info->ary_declared = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (field->fld_array_info->ary_dtype <= dtype_varying)
|
2008-12-29 11:26:36 +01:00
|
|
|
fprintf(gpreGlob.out_file, "gds__%d : %s [", field->fld_array_info->ary_ident, PACKED_ARRAY);
|
2001-05-23 15:26:42 +02:00
|
|
|
else
|
2008-12-29 11:26:36 +01:00
|
|
|
fprintf(gpreGlob.out_file, "gds__%d : array [", field->fld_array_info->ary_ident);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
// Print out the dimension part of the declaration
|
2008-12-29 11:26:36 +01:00
|
|
|
for (const dim* dimension = field->fld_array_info->ary_dimension; dimension;
|
|
|
|
dimension = dimension->dim_next)
|
2004-12-24 09:52:39 +01:00
|
|
|
{
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "%"SLONGFORMAT"..%"SLONGFORMAT, dimension->dim_lower,
|
2001-05-23 15:26:42 +02:00
|
|
|
dimension->dim_upper);
|
|
|
|
if (dimension->dim_next)
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, ", ");
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (field->fld_array_info->ary_dtype <= dtype_varying)
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, ", 1..%d", field->fld_array->fld_length);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "] of ");
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
switch (field->fld_array_info->ary_dtype)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
case dtype_short:
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, SHORT_DCL);
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case dtype_long:
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, LONG_DCL);
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case dtype_cstring:
|
|
|
|
case dtype_text:
|
|
|
|
case dtype_varying:
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "char");
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case dtype_date:
|
|
|
|
case dtype_quad:
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "ISC_QUAD");
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
2003-10-15 00:22:32 +02:00
|
|
|
case dtype_real:
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "real");
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case dtype_double:
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "double");
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2005-01-03 09:07:41 +01:00
|
|
|
{
|
|
|
|
TEXT s[ERROR_LENGTH];
|
2008-12-29 11:26:36 +01:00
|
|
|
fb_utils::snprintf(s, sizeof(s), "datatype %d unknown for field %s",
|
2005-01-03 09:07:41 +01:00
|
|
|
field->fld_array_info->ary_dtype, name);
|
|
|
|
CPR_error(s);
|
|
|
|
return;
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
// Print out the database field
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, ";\t(* %s *)\n", name);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Turn a symbol into a varying string.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2005-01-05 09:25:24 +01:00
|
|
|
static TEXT* make_name( TEXT* const string, const gpre_sym* symbol)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2005-01-03 09:07:41 +01:00
|
|
|
fb_utils::snprintf(string, MAX_CURSOR_SIZE, "'%s '", symbol->sym_string);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
return string;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate code to test existence of compiled request with
|
|
|
|
// active transaction
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-07 11:58:26 +02:00
|
|
|
static void make_ok_test( const act* action, const gpre_req* request, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
if (gpreGlob.sw_auto)
|
2001-05-23 15:26:42 +02:00
|
|
|
printa(column, "if (%s <> nil) and (%s <> nil) then",
|
|
|
|
request_trans(action, request), request->req_handle);
|
|
|
|
else
|
|
|
|
printa(column, "if (%s <> nil) then", request->req_handle);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Insert a port record description in output.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-01-28 08:50:41 +01:00
|
|
|
static void make_port( const gpre_port* port, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2003-09-10 21:48:53 +02:00
|
|
|
bool flag = false;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
printa(column, "gds__%dt = record", port->por_ident);
|
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
for (const ref* reference = port->por_references; reference; reference = reference->ref_next)
|
2003-09-10 21:48:53 +02:00
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
if (flag)
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, ";");
|
2003-09-10 21:48:53 +02:00
|
|
|
flag = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
align(column + INDENT);
|
2003-10-29 11:53:47 +01:00
|
|
|
const gpre_fld* field = reference->ref_field;
|
2003-10-06 11:48:44 +02:00
|
|
|
const TEXT* name;
|
2004-01-28 08:50:41 +01:00
|
|
|
const gpre_sym* symbol = field->fld_symbol;
|
2003-10-29 11:53:47 +01:00
|
|
|
if (symbol)
|
2001-05-23 15:26:42 +02:00
|
|
|
name = symbol->sym_string;
|
|
|
|
else
|
|
|
|
name = "<expression>";
|
|
|
|
if (reference->ref_value && (reference->ref_flags & REF_array_elem))
|
|
|
|
field = field->fld_array;
|
2003-10-06 11:48:44 +02:00
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
switch (field->fld_dtype)
|
|
|
|
{
|
2003-10-15 00:22:32 +02:00
|
|
|
case dtype_real:
|
2008-12-29 11:26:36 +01:00
|
|
|
fprintf(gpreGlob.out_file, "gds__%d\t: real\t(* %s *)", reference->ref_ident, name);
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case dtype_double:
|
2008-12-29 11:26:36 +01:00
|
|
|
fprintf(gpreGlob.out_file, "gds__%d\t: double\t(* %s *)", reference->ref_ident, name);
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case dtype_short:
|
2008-12-29 11:26:36 +01:00
|
|
|
fprintf(gpreGlob.out_file, "gds__%d\t: %s\t(* %s *)", reference->ref_ident, SHORT_DCL, name);
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case dtype_long:
|
2008-12-29 11:26:36 +01:00
|
|
|
fprintf(gpreGlob.out_file, "gds__%d\t: %s\t(* %s *)", reference->ref_ident, LONG_DCL, name);
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case dtype_date:
|
|
|
|
case dtype_quad:
|
|
|
|
case dtype_blob:
|
2008-12-29 11:26:36 +01:00
|
|
|
fprintf(gpreGlob.out_file, "gds__%d\t: gds__quad\t(* %s *)", reference->ref_ident, name);
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case dtype_text:
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, "gds__%d\t: %s [1..%d] of char\t(* %s *)",
|
2008-12-29 11:26:36 +01:00
|
|
|
reference->ref_ident, PACKED_ARRAY, field->fld_length, name);
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2003-10-29 11:53:47 +01:00
|
|
|
{
|
2005-01-03 09:07:41 +01:00
|
|
|
TEXT s[ERROR_LENGTH];
|
2008-12-29 11:26:36 +01:00
|
|
|
fb_utils::snprintf(s, sizeof(s), "datatype %d unknown for field %s, msg %d",
|
2003-10-29 11:53:47 +01:00
|
|
|
field->fld_dtype, name, port->por_msg_number);
|
|
|
|
CPR_error(s);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
printa(column, "end;\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate the actual insertion text for a
|
|
|
|
// ready;
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-01-14 09:22:32 +01:00
|
|
|
static void make_ready(const gpre_dbb* db,
|
2008-12-29 11:26:36 +01:00
|
|
|
const TEXT* filename, const TEXT* vector, USHORT column,
|
|
|
|
const gpre_req* request)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
TEXT s1[32], s2[32];
|
|
|
|
|
2009-06-28 12:26:25 +02:00
|
|
|
if (request)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
sprintf(s1, "gds__%dL", request->req_ident);
|
|
|
|
sprintf(s2, "gds__%d", request->req_ident);
|
|
|
|
}
|
|
|
|
|
|
|
|
align(column);
|
|
|
|
if (filename)
|
2008-01-16 08:15:01 +01:00
|
|
|
{
|
2008-12-29 11:26:36 +01:00
|
|
|
fprintf(gpreGlob.out_file, "GDS__ATTACH_DATABASE (%s, %s (%s), %s, %s, %s, %s);",
|
2001-05-23 15:26:42 +02:00
|
|
|
vector, SIZEOF, filename, filename,
|
|
|
|
db->dbb_name->sym_string, (request ? s1 : "0"),
|
|
|
|
(request ? s2 : "0"));
|
2008-01-16 08:15:01 +01:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
else
|
2008-01-16 08:15:01 +01:00
|
|
|
{
|
2008-12-29 11:26:36 +01:00
|
|
|
fprintf(gpreGlob.out_file, "GDS__ATTACH_DATABASE (%s, %d, '%s', %s, %s, %s);",
|
|
|
|
vector, strlen(db->dbb_filename), db->dbb_filename,
|
2001-05-23 15:26:42 +02:00
|
|
|
db->dbb_name->sym_string, (request ? s1 : "0"),
|
|
|
|
(request ? s2 : "0"));
|
2008-01-16 08:15:01 +01:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Print a fixed string at a particular column.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-09-29 14:43:14 +02:00
|
|
|
static void printa( int column, const char* string, ...)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
va_list ptr;
|
|
|
|
|
2004-05-24 01:28:06 +02:00
|
|
|
va_start(ptr, string);
|
2001-05-23 15:26:42 +02:00
|
|
|
align(column);
|
2004-05-24 19:13:38 +02:00
|
|
|
vfprintf(gpreGlob.out_file, string, ptr);
|
2004-09-25 12:28:09 +02:00
|
|
|
va_end(ptr);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate the appropriate transaction handle.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-07 11:58:26 +02:00
|
|
|
static const TEXT* request_trans( const act* action, const gpre_req* request)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2009-06-28 12:26:25 +02:00
|
|
|
if (action->act_type == ACT_open)
|
|
|
|
{
|
2004-01-28 08:50:41 +01:00
|
|
|
const TEXT* trname = ((open_cursor*) action->act_object)->opn_trans;
|
2003-10-06 11:48:44 +02:00
|
|
|
if (!trname)
|
2004-10-30 07:30:08 +02:00
|
|
|
trname = "gds__trans";
|
2001-05-23 15:26:42 +02:00
|
|
|
return trname;
|
|
|
|
}
|
2008-06-03 08:14:59 +02:00
|
|
|
|
2008-12-27 08:00:40 +01:00
|
|
|
return request ? request->req_trans : "gds__trans";
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate the appropriate status vector parameter for a gds
|
|
|
|
// call depending on where or not the action has an error clause.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-06-05 11:37:18 +02:00
|
|
|
static const TEXT* status_vector( const act* action)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
if (action && (action->act_error || (action->act_flags & ACT_sql)))
|
|
|
|
return "gds__status";
|
|
|
|
|
|
|
|
return "gds__null^";
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
// Generate substitution text for START_TRANSACTION.
|
|
|
|
// The complications include the fact that all databases
|
|
|
|
// must be readied, and that everything should stop if
|
|
|
|
// any thing fails so we don't trash the status vector.
|
2008-12-05 02:20:14 +01:00
|
|
|
//
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-05 02:20:14 +01:00
|
|
|
static void t_start_auto( const act* action, const gpre_req* request,
|
2004-06-05 11:37:18 +02:00
|
|
|
const TEXT* vector, int column)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2008-12-29 11:26:36 +01:00
|
|
|
TEXT buffer[256];
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
buffer[0] = 0;
|
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
// find out whether we're using a status vector or not
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-06-05 11:37:18 +02:00
|
|
|
const bool stat = !strcmp(vector, "gds__status");
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-04-22 13:44:39 +02:00
|
|
|
// this is a default transaction, make sure all databases are ready
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-09-16 16:01:56 +02:00
|
|
|
begin(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-29 11:26:36 +01:00
|
|
|
int count, and_count;
|
2009-04-22 13:44:39 +02:00
|
|
|
const gpre_dbb* db;
|
2008-12-29 11:26:36 +01:00
|
|
|
for (db = gpreGlob.isc_databases, count = and_count = 0; db; db = db->dbb_next)
|
|
|
|
{
|
2004-05-24 19:13:38 +02:00
|
|
|
if (gpreGlob.sw_auto)
|
2004-11-08 04:33:26 +01:00
|
|
|
{
|
|
|
|
const TEXT* filename = db->dbb_runtime;
|
2008-12-29 11:26:36 +01:00
|
|
|
if (filename || !(db->dbb_flags & DBB_sqlca))
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
align(column);
|
2008-12-29 11:26:36 +01:00
|
|
|
fprintf(gpreGlob.out_file, "if (%s = nil", db->dbb_name->sym_string);
|
2001-05-23 15:26:42 +02:00
|
|
|
if (stat && buffer[0])
|
2004-05-24 19:13:38 +02:00
|
|
|
fprintf(gpreGlob.out_file, ") and (%s[2] = 0", vector);
|
|
|
|
fprintf(gpreGlob.out_file, ") then");
|
2001-05-23 15:26:42 +02:00
|
|
|
make_ready(db, filename, vector, column + INDENT, 0);
|
|
|
|
if (buffer[0])
|
|
|
|
if (and_count % 4)
|
|
|
|
strcat(buffer, ") and (");
|
|
|
|
else
|
|
|
|
strcat(buffer, ") and\n\t(");
|
|
|
|
and_count++;
|
2008-12-29 11:26:36 +01:00
|
|
|
TEXT temp[40];
|
2001-05-23 15:26:42 +02:00
|
|
|
sprintf(temp, "%s <> nil", db->dbb_name->sym_string);
|
|
|
|
strcat(buffer, temp);
|
|
|
|
printa(column, "if (%s) then", buffer);
|
|
|
|
align(column + INDENT);
|
|
|
|
}
|
2004-11-08 04:33:26 +01:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
count++;
|
|
|
|
printa(column, "gds__teb[%d].tpb_len:= 0;", count);
|
|
|
|
printa(column, "gds__teb[%d].tpb_ptr := ADDR(gds__null);", count);
|
2008-12-29 11:26:36 +01:00
|
|
|
printa(column, "gds__teb[%d].dbb_ptr := ADDR(%s);", count, db->dbb_name->sym_string);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
printa(column, "GDS__START_MULTIPLE (%s, %s, %d, gds__teb);",
|
|
|
|
vector, request_trans(action, request), count);
|
|
|
|
|
2004-05-24 19:13:38 +02:00
|
|
|
if (gpreGlob.sw_auto && request)
|
2001-05-23 15:26:42 +02:00
|
|
|
column -= INDENT;
|
|
|
|
|
2003-09-12 18:35:40 +02:00
|
|
|
set_sqlcode(action, column);
|
2003-09-16 16:01:56 +02:00
|
|
|
ends(column);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|