2001-05-23 15:26:42 +02:00
|
|
|
/*
|
|
|
|
* PROGRAM: JRD Data Definition Utility
|
2003-11-05 10:02:33 +01:00
|
|
|
* MODULE: dyn_define.epp
|
2001-05-23 15:26:42 +02:00
|
|
|
* DESCRIPTION: Dynamic data definition DYN_define_<x>
|
|
|
|
*
|
|
|
|
* The contents of this file are subject to the Interbase Public
|
|
|
|
* License Version 1.0 (the "License"); you may not use this file
|
|
|
|
* except in compliance with the License. You may obtain a copy
|
|
|
|
* of the License at http://www.Inprise.com/IPL.html
|
|
|
|
*
|
|
|
|
* Software distributed under the License is distributed on an
|
|
|
|
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
|
|
|
|
* or implied. See the License for the specific language governing
|
|
|
|
* rights and limitations under the License.
|
|
|
|
*
|
|
|
|
* The Original Code was created by Inprise Corporation
|
|
|
|
* and its predecessors. Portions created by Inprise Corporation are
|
|
|
|
* Copyright (C) Inprise Corporation.
|
|
|
|
*
|
|
|
|
* All Rights Reserved.
|
|
|
|
* Contributor(s): ______________________________________.
|
2002-02-24 17:39:31 +01:00
|
|
|
*
|
2002-06-30 10:46:51 +02:00
|
|
|
* 23-May-2001 Claudio Valderrama - Forbid zero length identifiers,
|
|
|
|
* they are not ANSI SQL compliant.
|
|
|
|
* 2001.10.08 Claudio Valderrama: Add case isc_dyn_system_flag to
|
|
|
|
* DYN_define_trigger() in order to receive values for special triggers
|
|
|
|
* as defined in constants.h.
|
|
|
|
* 2001.10.08 Ann Harrison: Changed dyn_create_index so it doesn't consider
|
|
|
|
* simple unique indexes when finding a "referred index", but only
|
|
|
|
* indexes that support unique constraints or primary keys.
|
2005-05-28 00:45:31 +02:00
|
|
|
* 26-Sep-2001 Paul Beach - External File Directory Config. Parameter
|
2002-02-24 17:39:31 +01:00
|
|
|
* 2002-02-24 Sean Leyne - Code Cleanup of old Win 3.1 port (WINDOWS_ONLY)
|
2002-08-11 10:04:54 +02:00
|
|
|
* 2002.08.10 Dmitry Yemanov: ALTER VIEW
|
2002-10-30 07:40:58 +01:00
|
|
|
*
|
|
|
|
* 2002.10.29 Sean Leyne - Removed obsolete "Netware" port
|
|
|
|
*
|
2005-05-28 00:45:31 +02:00
|
|
|
* 2004.01.16 Vlad Horsun: added support for default parameters
|
2001-05-23 15:26:42 +02:00
|
|
|
*/
|
|
|
|
|
2001-07-29 19:42:23 +02:00
|
|
|
#include "firebird.h"
|
2010-01-10 18:56:57 +01:00
|
|
|
#include "dyn_consts.h"
|
2004-12-17 06:41:47 +01:00
|
|
|
#include "../common/classes/fb_string.h"
|
2001-05-23 15:26:42 +02:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#include "../jrd/common.h"
|
|
|
|
#include "../jrd/jrd.h"
|
|
|
|
#include "../jrd/ods.h"
|
|
|
|
#include "../jrd/tra.h"
|
|
|
|
#include "../jrd/scl.h"
|
|
|
|
#include "../jrd/drq.h"
|
|
|
|
#include "../jrd/req.h"
|
|
|
|
#include "../jrd/flags.h"
|
2003-11-08 17:40:17 +01:00
|
|
|
#include "../jrd/ibase.h"
|
2001-05-23 15:26:42 +02:00
|
|
|
#include "../jrd/lls.h"
|
|
|
|
#include "../jrd/met.h"
|
|
|
|
#include "../jrd/btr.h"
|
2006-07-17 19:44:18 +02:00
|
|
|
#include "../jrd/ini.h"
|
2001-05-23 15:26:42 +02:00
|
|
|
#include "../jrd/intl.h"
|
|
|
|
#include "../jrd/dyn.h"
|
|
|
|
#include "../jrd/gdsassert.h"
|
|
|
|
#include "../jrd/blb_proto.h"
|
|
|
|
#include "../jrd/cmp_proto.h"
|
|
|
|
#include "../jrd/dyn_proto.h"
|
|
|
|
#include "../jrd/dyn_df_proto.h"
|
|
|
|
#include "../jrd/dyn_ut_proto.h"
|
|
|
|
#include "../jrd/err_proto.h"
|
|
|
|
#include "../jrd/exe_proto.h"
|
|
|
|
#include "../jrd/gds_proto.h"
|
|
|
|
#include "../jrd/inf_proto.h"
|
|
|
|
#include "../jrd/intl_proto.h"
|
|
|
|
#include "../jrd/isc_f_proto.h"
|
2002-07-05 17:00:26 +02:00
|
|
|
#include "../jrd/met_proto.h"
|
2001-05-23 15:26:42 +02:00
|
|
|
#include "../jrd/vio_proto.h"
|
|
|
|
#include "../jrd/scl_proto.h"
|
|
|
|
#include "../jrd/gdsassert.h"
|
2003-03-23 17:50:54 +01:00
|
|
|
#include "../jrd/os/path_utils.h"
|
2003-12-31 06:36:12 +01:00
|
|
|
#include "../common/utils_proto.h"
|
2005-05-28 00:45:31 +02:00
|
|
|
#include "../jrd/IntlManager.h"
|
2006-07-30 22:31:25 +02:00
|
|
|
#include "../jrd/IntlUtil.h"
|
2009-10-21 02:42:38 +02:00
|
|
|
#include "../dsql/DdlNodes.h"
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2007-03-28 06:20:36 +02:00
|
|
|
using MsgFormat::SafeArg;
|
|
|
|
|
2004-03-20 15:57:40 +01:00
|
|
|
using namespace Jrd;
|
2008-08-27 14:20:47 +02:00
|
|
|
using namespace Firebird;
|
2004-03-20 15:57:40 +01:00
|
|
|
|
2007-03-28 06:20:36 +02:00
|
|
|
|
2005-05-12 20:28:04 +02:00
|
|
|
typedef Firebird::ObjectsArray<Firebird::MetaName> MetaNameArray;
|
2004-04-18 16:22:27 +02:00
|
|
|
|
2004-04-29 13:16:31 +02:00
|
|
|
const int FOR_KEY_UPD_CASCADE = 0x01;
|
|
|
|
const int FOR_KEY_UPD_NULL = 0x02;
|
|
|
|
const int FOR_KEY_UPD_DEFAULT = 0x04;
|
|
|
|
const int FOR_KEY_UPD_NONE = 0x08;
|
|
|
|
const int FOR_KEY_DEL_CASCADE = 0x10;
|
|
|
|
const int FOR_KEY_DEL_NULL = 0x20;
|
|
|
|
const int FOR_KEY_DEL_DEFAULT = 0x40;
|
|
|
|
const int FOR_KEY_DEL_NONE = 0x80;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2002-12-16 17:25:10 +01:00
|
|
|
DATABASE DB = STATIC "ODS.RDB";
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2005-05-12 20:28:04 +02:00
|
|
|
static bool is_it_user_name(Global*, const Firebird::MetaName&, thread_db*);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
|
2004-03-31 19:38:53 +02:00
|
|
|
void DYN_define_file(Global* gbl,
|
2003-11-05 10:02:33 +01:00
|
|
|
const UCHAR** ptr,
|
2001-12-24 03:51:06 +01:00
|
|
|
SLONG shadow_number,
|
|
|
|
SLONG* start,
|
|
|
|
USHORT msg)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* D Y N _ d e f i n e _ f i l e
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Define a database or shadow file.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
UCHAR verb;
|
|
|
|
SLONG temp;
|
|
|
|
USHORT man_auto;
|
2004-03-01 04:35:23 +01:00
|
|
|
SSHORT id;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-22 16:28:54 +02:00
|
|
|
thread_db* tdbb = JRD_get_thread_data();
|
2007-12-03 16:46:39 +01:00
|
|
|
Database* dbb = tdbb->getDatabase();
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2007-12-03 16:46:39 +01:00
|
|
|
if (!tdbb->getAttachment()->locksmith())
|
2006-08-16 17:15:58 +02:00
|
|
|
{
|
2008-08-27 14:20:47 +02:00
|
|
|
ERR_post(Arg::Gds(isc_adm_task_denied));
|
2006-08-16 17:15:58 +02:00
|
|
|
}
|
|
|
|
|
2001-12-24 03:51:06 +01:00
|
|
|
try {
|
|
|
|
|
2009-11-25 05:06:48 +01:00
|
|
|
id = -1;
|
|
|
|
Firebird::PathName temp_f;
|
|
|
|
GET_STRING(ptr, temp_f);
|
|
|
|
if (!ISC_expand_filename(temp_f, false))
|
2009-11-26 01:20:59 +01:00
|
|
|
DYN_error_punt(false, 231); // File name is invalid.
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2010-04-18 03:10:05 +02:00
|
|
|
if (dbb->dbb_filename == temp_f)
|
2009-11-25 05:06:48 +01:00
|
|
|
DYN_error_punt(false, 166);
|
2010-04-18 03:10:05 +02:00
|
|
|
|
|
|
|
AutoCacheRequest request(tdbb, id = drq_l_files, DYN_REQUESTS);
|
2006-04-30 02:39:37 +02:00
|
|
|
|
2009-11-25 05:06:48 +01:00
|
|
|
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
|
|
|
|
FIRST 1 X IN RDB$FILES WITH X.RDB$FILE_NAME EQ temp_f.c_str()
|
2010-04-18 03:10:05 +02:00
|
|
|
{
|
2009-11-25 05:06:48 +01:00
|
|
|
DYN_error_punt(false, 166);
|
2010-04-18 03:10:05 +02:00
|
|
|
}
|
|
|
|
END_FOR
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2010-04-18 03:10:05 +02:00
|
|
|
request.reset(tdbb, id = drq_s_files, DYN_REQUESTS);
|
2006-04-30 02:39:37 +02:00
|
|
|
|
2009-11-25 05:06:48 +01:00
|
|
|
STORE(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
|
|
|
|
X IN RDB$FILES
|
2010-04-18 03:10:05 +02:00
|
|
|
{
|
2009-11-25 05:06:48 +01:00
|
|
|
temp_f.copyTo(X.RDB$FILE_NAME, sizeof(X.RDB$FILE_NAME));
|
|
|
|
X.RDB$SHADOW_NUMBER = (SSHORT)shadow_number;
|
|
|
|
X.RDB$FILE_FLAGS = 0;
|
|
|
|
X.RDB$FILE_FLAGS.NULL = FALSE;
|
|
|
|
X.RDB$FILE_START.NULL = TRUE;
|
|
|
|
X.RDB$FILE_LENGTH.NULL = TRUE;
|
|
|
|
while ((verb = *(*ptr)++) != isc_dyn_end)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2009-11-25 05:06:48 +01:00
|
|
|
switch (verb)
|
|
|
|
{
|
|
|
|
case isc_dyn_file_start:
|
|
|
|
temp = DYN_get_number(ptr);
|
|
|
|
*start = MAX(*start, temp);
|
|
|
|
X.RDB$FILE_START = *start;
|
|
|
|
X.RDB$FILE_START.NULL = FALSE;
|
|
|
|
break;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-11-25 05:06:48 +01:00
|
|
|
case isc_dyn_file_length:
|
|
|
|
X.RDB$FILE_LENGTH = DYN_get_number(ptr);
|
|
|
|
X.RDB$FILE_LENGTH.NULL = FALSE;
|
|
|
|
break;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-11-25 05:06:48 +01:00
|
|
|
case isc_dyn_shadow_man_auto:
|
|
|
|
man_auto = (USHORT)DYN_get_number(ptr);
|
|
|
|
if (man_auto)
|
|
|
|
X.RDB$FILE_FLAGS |= FILE_manual;
|
|
|
|
break;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-11-25 05:06:48 +01:00
|
|
|
case isc_dyn_shadow_conditional:
|
|
|
|
if (DYN_get_number(ptr))
|
|
|
|
X.RDB$FILE_FLAGS |= FILE_conditional;
|
|
|
|
break;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-11-25 05:06:48 +01:00
|
|
|
default:
|
|
|
|
DYN_unsupported_verb();
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
2009-11-25 05:06:48 +01:00
|
|
|
*start += X.RDB$FILE_LENGTH;
|
2010-04-18 03:10:05 +02:00
|
|
|
}
|
|
|
|
END_STORE
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2001-12-24 03:51:06 +01:00
|
|
|
}
|
2009-01-20 09:33:59 +01:00
|
|
|
catch (const Firebird::Exception& ex)
|
|
|
|
{
|
2004-03-01 04:35:23 +01:00
|
|
|
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
|
2001-12-24 03:51:06 +01:00
|
|
|
if (id == drq_l_files)
|
2007-03-28 06:20:36 +02:00
|
|
|
DYN_error_punt(false, 166);
|
2001-12-24 03:51:06 +01:00
|
|
|
else
|
2007-03-28 06:20:36 +02:00
|
|
|
DYN_error_punt(true, msg);
|
2001-12-24 03:51:06 +01:00
|
|
|
}
|
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-11-25 05:06:48 +01:00
|
|
|
void DYN_define_difference(Global* gbl, const UCHAR** ptr)
|
2003-08-06 18:30:49 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* D Y N _ d e f i n e _ d i f f e r e n c e
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Define backup difference file.
|
|
|
|
*
|
|
|
|
**************************************/
|
2004-03-01 04:35:23 +01:00
|
|
|
SSHORT id = -1;
|
2003-08-06 18:30:49 +02:00
|
|
|
|
2004-05-22 16:28:54 +02:00
|
|
|
thread_db* tdbb = JRD_get_thread_data();
|
2003-08-06 18:30:49 +02:00
|
|
|
|
2007-12-03 16:46:39 +01:00
|
|
|
if (!tdbb->getAttachment()->locksmith())
|
2006-08-16 17:15:58 +02:00
|
|
|
{
|
2008-08-27 14:20:47 +02:00
|
|
|
ERR_post(Arg::Gds(isc_adm_task_denied));
|
2006-08-16 17:15:58 +02:00
|
|
|
}
|
|
|
|
|
2009-11-26 01:20:59 +01:00
|
|
|
try
|
|
|
|
{
|
2009-11-25 05:06:48 +01:00
|
|
|
bool found = false;
|
|
|
|
id = drq_l_difference;
|
2010-04-18 03:10:05 +02:00
|
|
|
AutoCacheRequest request(tdbb, drq_l_difference, DYN_REQUESTS);
|
2009-11-25 05:06:48 +01:00
|
|
|
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
|
|
|
|
FIL IN RDB$FILES
|
2010-04-18 03:10:05 +02:00
|
|
|
{
|
2009-11-25 05:06:48 +01:00
|
|
|
if (FIL.RDB$FILE_FLAGS & FILE_difference)
|
|
|
|
found = true;
|
|
|
|
}
|
2010-04-18 03:10:05 +02:00
|
|
|
END_FOR
|
2003-08-06 18:30:49 +02:00
|
|
|
|
2010-04-18 03:10:05 +02:00
|
|
|
if (found)
|
2009-11-25 05:06:48 +01:00
|
|
|
goto dyn_punt_216;
|
2003-08-06 18:30:49 +02:00
|
|
|
|
2010-04-18 03:10:05 +02:00
|
|
|
request.reset(tdbb, drq_s_difference, DYN_REQUESTS);
|
2009-11-25 05:06:48 +01:00
|
|
|
id = drq_s_difference;
|
2010-04-18 03:10:05 +02:00
|
|
|
|
2009-11-25 05:06:48 +01:00
|
|
|
STORE(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
|
|
|
|
X IN RDB$FILES
|
2010-04-18 03:10:05 +02:00
|
|
|
{
|
2009-11-25 05:06:48 +01:00
|
|
|
GET_STRING(ptr, X.RDB$FILE_NAME);
|
|
|
|
X.RDB$FILE_FLAGS = FILE_difference;
|
|
|
|
X.RDB$FILE_FLAGS.NULL = FALSE;
|
|
|
|
X.RDB$FILE_START = 0;
|
|
|
|
X.RDB$FILE_START.NULL = FALSE;
|
|
|
|
X.RDB$FILE_LENGTH.NULL = TRUE;
|
|
|
|
X.RDB$SHADOW_NUMBER.NULL = TRUE;
|
2010-04-18 03:10:05 +02:00
|
|
|
}
|
|
|
|
END_STORE
|
2003-08-06 18:30:49 +02:00
|
|
|
}
|
2009-01-20 09:33:59 +01:00
|
|
|
catch (const Firebird::Exception& ex)
|
|
|
|
{
|
2004-03-01 04:35:23 +01:00
|
|
|
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
|
2003-08-06 18:30:49 +02:00
|
|
|
if (id == drq_s_difference)
|
|
|
|
{
|
2007-03-28 06:20:36 +02:00
|
|
|
DYN_error_punt(true, 150);
|
2009-11-21 08:38:05 +01:00
|
|
|
// msg 150: STORE RDB$FILES failed
|
2003-08-06 18:30:49 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-03-28 06:20:36 +02:00
|
|
|
DYN_error_punt(true, 156);
|
2009-11-21 08:38:05 +01:00
|
|
|
// msg 156: Difference file lookup failed
|
2003-08-06 18:30:49 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
2003-08-12 21:54:34 +02:00
|
|
|
dyn_punt_216:
|
2007-03-28 06:20:36 +02:00
|
|
|
DYN_error_punt(false, 216);
|
2009-11-21 08:38:05 +01:00
|
|
|
// msg 216: "Difference file is already defined"
|
2003-08-06 18:30:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-03-31 19:38:53 +02:00
|
|
|
void DYN_define_filter( Global* gbl, const UCHAR** ptr)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* D Y N _ d e f i n e _ f i l t e r
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Define a blob filter.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
|
2004-05-22 16:28:54 +02:00
|
|
|
thread_db* tdbb = JRD_get_thread_data();
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2005-05-17 09:17:25 +02:00
|
|
|
Firebird::MetaName filter_name;
|
2002-06-30 10:46:51 +02:00
|
|
|
GET_STRING(ptr, filter_name);
|
|
|
|
|
2010-04-18 03:10:05 +02:00
|
|
|
AutoCacheRequest request(tdbb, drq_s_filters, DYN_REQUESTS);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2001-12-25 05:10:23 +01:00
|
|
|
bool b_ending_store = false;
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
STORE(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
|
2005-05-28 00:45:31 +02:00
|
|
|
X IN RDB$FILTERS USING
|
2005-05-12 20:28:04 +02:00
|
|
|
strcpy(X.RDB$FUNCTION_NAME, filter_name.c_str());
|
2001-12-25 05:10:23 +01:00
|
|
|
X.RDB$OUTPUT_SUB_TYPE.NULL = TRUE;
|
|
|
|
X.RDB$INPUT_SUB_TYPE.NULL = TRUE;
|
|
|
|
X.RDB$MODULE_NAME.NULL = TRUE;
|
|
|
|
X.RDB$ENTRYPOINT.NULL = TRUE;
|
2005-10-30 08:44:26 +01:00
|
|
|
X.RDB$SYSTEM_FLAG = 0;
|
|
|
|
X.RDB$SYSTEM_FLAG.NULL = FALSE;
|
2010-04-18 03:10:05 +02:00
|
|
|
{
|
2004-07-06 07:59:40 +02:00
|
|
|
UCHAR verb;
|
2003-11-08 17:40:17 +01:00
|
|
|
while ((verb = *(*ptr)++) != isc_dyn_end)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2001-12-25 05:10:23 +01:00
|
|
|
switch (verb)
|
|
|
|
{
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_filter_in_subtype:
|
2001-12-25 05:10:23 +01:00
|
|
|
X.RDB$INPUT_SUB_TYPE = (SSHORT)DYN_get_number(ptr);
|
|
|
|
X.RDB$INPUT_SUB_TYPE.NULL = FALSE;
|
|
|
|
break;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_filter_out_subtype:
|
2001-12-25 05:10:23 +01:00
|
|
|
X.RDB$OUTPUT_SUB_TYPE = (SSHORT)DYN_get_number(ptr);
|
|
|
|
X.RDB$OUTPUT_SUB_TYPE.NULL = FALSE;
|
|
|
|
break;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_func_module_name:
|
2001-12-25 05:10:23 +01:00
|
|
|
GET_STRING(ptr, X.RDB$MODULE_NAME);
|
|
|
|
X.RDB$MODULE_NAME.NULL = FALSE;
|
|
|
|
break;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_func_entry_point:
|
2001-12-25 05:10:23 +01:00
|
|
|
GET_STRING(ptr, X.RDB$ENTRYPOINT);
|
|
|
|
X.RDB$ENTRYPOINT.NULL = FALSE;
|
|
|
|
break;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2001-12-25 05:10:23 +01:00
|
|
|
default:
|
|
|
|
DYN_unsupported_verb();
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
2001-12-25 05:10:23 +01:00
|
|
|
}
|
2010-04-18 03:10:05 +02:00
|
|
|
END_STORE
|
2001-12-25 05:10:23 +01:00
|
|
|
}
|
2009-11-25 05:06:48 +01:00
|
|
|
catch (const Firebird::Exception& ex)
|
|
|
|
{
|
2004-03-01 04:35:23 +01:00
|
|
|
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
|
2009-11-25 05:06:48 +01:00
|
|
|
if (b_ending_store)
|
|
|
|
{
|
2007-03-28 06:20:36 +02:00
|
|
|
DYN_error_punt(true, 7);
|
2009-11-21 08:38:05 +01:00
|
|
|
// msg 7: "DEFINE BLOB FILTER failed"
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
2001-12-25 05:10:23 +01:00
|
|
|
throw;
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-03-31 19:38:53 +02:00
|
|
|
void DYN_define_function( Global* gbl, const UCHAR** ptr)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* D Y N _ d e f i n e _ f u n c t i o n
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Define a user defined function.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
|
2004-05-22 16:28:54 +02:00
|
|
|
thread_db* tdbb = JRD_get_thread_data();
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2005-05-17 09:17:25 +02:00
|
|
|
Firebird::MetaName function_name;
|
2002-06-30 10:46:51 +02:00
|
|
|
GET_STRING(ptr, function_name);
|
|
|
|
|
2009-10-21 02:42:38 +02:00
|
|
|
DdlNode::executeDdlTrigger(tdbb, gbl->gbl_transaction, DdlNode::DTW_BEFORE,
|
|
|
|
DDL_TRIGGER_CREATE_FUNCTION, function_name, gbl->sqlText);
|
|
|
|
|
2010-04-18 03:10:05 +02:00
|
|
|
AutoCacheRequest request(tdbb, drq_s_funcs, DYN_REQUESTS);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2001-12-25 05:10:23 +01:00
|
|
|
bool b_ending_store = false;
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
STORE(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
|
2005-05-28 00:45:31 +02:00
|
|
|
X IN RDB$FUNCTIONS USING
|
2010-04-18 03:10:05 +02:00
|
|
|
{
|
2005-05-12 20:28:04 +02:00
|
|
|
strcpy(X.RDB$FUNCTION_NAME, function_name.c_str());
|
2001-12-25 05:10:23 +01:00
|
|
|
X.RDB$RETURN_ARGUMENT.NULL = TRUE;
|
|
|
|
X.RDB$QUERY_NAME.NULL = TRUE;
|
|
|
|
X.RDB$MODULE_NAME.NULL = TRUE;
|
|
|
|
X.RDB$ENTRYPOINT.NULL = TRUE;
|
2005-10-30 08:44:26 +01:00
|
|
|
X.RDB$SYSTEM_FLAG = 0;
|
|
|
|
X.RDB$SYSTEM_FLAG.NULL = FALSE;
|
2009-12-21 17:48:06 +01:00
|
|
|
X.RDB$LEGACY_FLAG = 1;
|
|
|
|
X.RDB$LEGACY_FLAG.NULL = FALSE;
|
|
|
|
X.RDB$INVARIANT_FLAG.NULL = TRUE;
|
2009-10-21 02:42:38 +02:00
|
|
|
X.RDB$ENGINE_NAME.NULL = TRUE;
|
2004-07-06 07:59:40 +02:00
|
|
|
|
|
|
|
UCHAR verb;
|
2003-11-08 17:40:17 +01:00
|
|
|
while ((verb = *(*ptr)++) != isc_dyn_end)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2001-12-25 05:10:23 +01:00
|
|
|
switch (verb)
|
|
|
|
{
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_func_return_argument:
|
2001-12-25 05:10:23 +01:00
|
|
|
X.RDB$RETURN_ARGUMENT = (SSHORT)DYN_get_number(ptr);
|
|
|
|
X.RDB$RETURN_ARGUMENT.NULL = FALSE;
|
|
|
|
if (X.RDB$RETURN_ARGUMENT > MAX_UDF_ARGUMENTS)
|
2007-03-28 06:20:36 +02:00
|
|
|
DYN_error_punt(true, 10);
|
2009-11-21 08:38:05 +01:00
|
|
|
// msg 10: "DEFINE FUNCTION failed"
|
2001-12-25 05:10:23 +01:00
|
|
|
break;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_func_module_name:
|
2001-12-25 05:10:23 +01:00
|
|
|
GET_STRING(ptr, X.RDB$MODULE_NAME);
|
|
|
|
X.RDB$MODULE_NAME.NULL = FALSE;
|
|
|
|
break;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_fld_query_name:
|
2001-12-25 05:10:23 +01:00
|
|
|
GET_STRING(ptr, X.RDB$QUERY_NAME);
|
|
|
|
X.RDB$QUERY_NAME.NULL = FALSE;
|
|
|
|
break;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_func_entry_point:
|
2001-12-25 05:10:23 +01:00
|
|
|
GET_STRING(ptr, X.RDB$ENTRYPOINT);
|
|
|
|
X.RDB$ENTRYPOINT.NULL = FALSE;
|
|
|
|
break;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2001-12-25 05:10:23 +01:00
|
|
|
default:
|
|
|
|
--(*ptr);
|
2010-01-24 16:16:23 +01:00
|
|
|
{
|
|
|
|
MetaNameProxy tmp(X.RDB$FUNCTION_NAME);
|
2005-05-12 20:28:04 +02:00
|
|
|
DYN_execute(gbl, ptr, NULL, NULL, NULL, &tmp, NULL);
|
2010-01-24 16:16:23 +01:00
|
|
|
}
|
2001-12-25 05:10:23 +01:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2001-12-25 05:10:23 +01:00
|
|
|
b_ending_store = true;
|
|
|
|
}
|
2010-04-18 03:10:05 +02:00
|
|
|
END_STORE
|
2001-12-25 05:10:23 +01:00
|
|
|
}
|
2009-11-25 05:06:48 +01:00
|
|
|
catch (const Firebird::Exception& ex)
|
|
|
|
{
|
2004-03-01 04:35:23 +01:00
|
|
|
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
|
2009-11-25 05:06:48 +01:00
|
|
|
if (b_ending_store)
|
|
|
|
{
|
2007-03-28 06:20:36 +02:00
|
|
|
DYN_error_punt(true, 10);
|
2009-11-21 08:38:05 +01:00
|
|
|
// msg 10: "DEFINE FUNCTION failed"
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
2001-12-25 05:10:23 +01:00
|
|
|
throw;
|
2001-12-24 03:51:06 +01:00
|
|
|
}
|
2009-10-21 02:42:38 +02:00
|
|
|
|
|
|
|
DdlNode::executeDdlTrigger(tdbb, gbl->gbl_transaction, DdlNode::DTW_AFTER,
|
|
|
|
DDL_TRIGGER_CREATE_FUNCTION, function_name, gbl->sqlText);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-05-12 20:28:04 +02:00
|
|
|
void DYN_define_function_arg(Global* gbl, const UCHAR** ptr, Firebird::MetaName* function_name)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* D Y N _ d e f i n e _ f u n c t i o n _ a r g
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Define a user defined function argument.
|
|
|
|
*
|
|
|
|
**************************************/
|
2004-07-06 07:59:40 +02:00
|
|
|
|
2004-05-22 16:28:54 +02:00
|
|
|
thread_db* tdbb = JRD_get_thread_data();
|
2005-05-28 00:45:31 +02:00
|
|
|
|
2009-11-26 01:20:59 +01:00
|
|
|
try
|
|
|
|
{
|
2010-04-18 03:10:05 +02:00
|
|
|
AutoCacheRequest request(tdbb, drq_s_func_args, DYN_REQUESTS);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-11-25 05:06:48 +01:00
|
|
|
STORE(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
|
|
|
|
X IN RDB$FUNCTION_ARGUMENTS
|
2010-04-18 03:10:05 +02:00
|
|
|
{
|
2009-11-25 05:06:48 +01:00
|
|
|
X.RDB$ARGUMENT_POSITION = (SSHORT)DYN_get_number(ptr);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-11-25 05:06:48 +01:00
|
|
|
if (X.RDB$ARGUMENT_POSITION > MAX_UDF_ARGUMENTS)
|
|
|
|
DYN_error_punt(true, 12); // msg 12: "DEFINE FUNCTION ARGUMENT failed"
|
2004-07-06 07:59:40 +02:00
|
|
|
|
2009-11-25 05:06:48 +01:00
|
|
|
if (function_name)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2009-11-25 05:06:48 +01:00
|
|
|
strcpy(X.RDB$FUNCTION_NAME, function_name->c_str());
|
2001-05-23 15:26:42 +02:00
|
|
|
X.RDB$FUNCTION_NAME.NULL = FALSE;
|
2009-11-25 05:06:48 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
X.RDB$FUNCTION_NAME.NULL = TRUE;
|
|
|
|
X.RDB$MECHANISM.NULL = TRUE;
|
|
|
|
X.RDB$FIELD_TYPE.NULL = TRUE;
|
|
|
|
X.RDB$FIELD_SCALE.NULL = TRUE;
|
|
|
|
X.RDB$FIELD_LENGTH.NULL = TRUE;
|
|
|
|
X.RDB$FIELD_SUB_TYPE.NULL = TRUE;
|
|
|
|
X.RDB$CHARACTER_SET_ID.NULL = TRUE;
|
|
|
|
X.RDB$FIELD_PRECISION.NULL = TRUE;
|
|
|
|
X.RDB$CHARACTER_LENGTH.NULL = TRUE;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-11-25 05:06:48 +01:00
|
|
|
UCHAR verb;
|
|
|
|
while ((verb = *(*ptr)++) != isc_dyn_end)
|
|
|
|
switch (verb)
|
|
|
|
{
|
|
|
|
case isc_dyn_function_name:
|
|
|
|
GET_STRING(ptr, X.RDB$FUNCTION_NAME);
|
|
|
|
X.RDB$FUNCTION_NAME.NULL = FALSE;
|
|
|
|
break;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-11-25 05:06:48 +01:00
|
|
|
case isc_dyn_func_mechanism:
|
|
|
|
X.RDB$MECHANISM = (SSHORT)DYN_get_number(ptr);
|
|
|
|
X.RDB$MECHANISM.NULL = FALSE;
|
|
|
|
break;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-11-25 05:06:48 +01:00
|
|
|
case isc_dyn_fld_type:
|
|
|
|
X.RDB$FIELD_TYPE = (SSHORT)DYN_get_number(ptr);
|
|
|
|
X.RDB$FIELD_TYPE.NULL = FALSE;
|
|
|
|
break;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-11-25 05:06:48 +01:00
|
|
|
case isc_dyn_fld_sub_type:
|
|
|
|
X.RDB$FIELD_SUB_TYPE = (SSHORT)DYN_get_number(ptr);
|
|
|
|
X.RDB$FIELD_SUB_TYPE.NULL = FALSE;
|
|
|
|
break;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-11-25 05:06:48 +01:00
|
|
|
case isc_dyn_fld_scale:
|
|
|
|
X.RDB$FIELD_SCALE = (SSHORT)DYN_get_number(ptr);
|
|
|
|
X.RDB$FIELD_SCALE.NULL = FALSE;
|
|
|
|
break;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-11-25 05:06:48 +01:00
|
|
|
case isc_dyn_fld_length:
|
|
|
|
X.RDB$FIELD_LENGTH = (SSHORT)DYN_get_number(ptr);
|
|
|
|
X.RDB$FIELD_LENGTH.NULL = FALSE;
|
|
|
|
break;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-11-25 05:06:48 +01:00
|
|
|
case isc_dyn_fld_character_set:
|
|
|
|
X.RDB$CHARACTER_SET_ID = (SSHORT)DYN_get_number(ptr);
|
|
|
|
X.RDB$CHARACTER_SET_ID.NULL = FALSE;
|
|
|
|
break;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-11-25 05:06:48 +01:00
|
|
|
case isc_dyn_fld_precision:
|
|
|
|
X.RDB$FIELD_PRECISION = (SSHORT)DYN_get_number(ptr);
|
|
|
|
X.RDB$FIELD_PRECISION.NULL = FALSE;
|
|
|
|
break;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-11-25 05:06:48 +01:00
|
|
|
// Ignore the field character length as the system UDF parameter
|
|
|
|
// table has no place to store the information
|
|
|
|
// But IB6/FB has the place for this information. CVC 2001.
|
|
|
|
case isc_dyn_fld_char_length:
|
|
|
|
X.RDB$CHARACTER_LENGTH = (SSHORT)DYN_get_number (ptr);
|
|
|
|
X.RDB$CHARACTER_LENGTH.NULL = FALSE;
|
|
|
|
break;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-11-25 05:06:48 +01:00
|
|
|
default:
|
|
|
|
DYN_unsupported_verb();
|
|
|
|
}
|
|
|
|
}
|
2010-04-18 03:10:05 +02:00
|
|
|
END_STORE
|
2001-12-24 03:51:06 +01:00
|
|
|
}
|
2009-11-25 05:06:48 +01:00
|
|
|
catch (const Firebird::Exception& ex)
|
|
|
|
{
|
2004-03-01 04:35:23 +01:00
|
|
|
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
|
2007-03-28 06:20:36 +02:00
|
|
|
DYN_error_punt(true, 12);
|
2009-11-21 08:38:05 +01:00
|
|
|
// msg 12: "DEFINE FUNCTION ARGUMENT failed"
|
2001-12-24 03:51:06 +01:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-03-31 19:38:53 +02:00
|
|
|
void DYN_define_index(Global* gbl,
|
2003-11-05 10:02:33 +01:00
|
|
|
const UCHAR** ptr,
|
2005-05-12 20:28:04 +02:00
|
|
|
const Firebird::MetaName* relation_name,
|
2001-05-23 15:26:42 +02:00
|
|
|
UCHAR index_type,
|
2005-05-12 20:28:04 +02:00
|
|
|
Firebird::MetaName* new_index_name,
|
|
|
|
Firebird::MetaName* referred_index_name,
|
|
|
|
Firebird::MetaName* cnst_name,
|
2001-05-23 15:26:42 +02:00
|
|
|
UCHAR* ri_actionP)
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* D Y N _ d e f i n e _ i n d e x
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
2010-07-26 04:37:57 +02:00
|
|
|
* Execute a dynamic ddl statement that creates an index.
|
2001-05-23 15:26:42 +02:00
|
|
|
*
|
|
|
|
**************************************/
|
2010-07-26 04:37:57 +02:00
|
|
|
thread_db* tdbb = JRD_get_thread_data();
|
2005-05-12 20:28:04 +02:00
|
|
|
Firebird::MetaName index_name;
|
2001-12-25 05:10:23 +01:00
|
|
|
UCHAR verb;
|
2005-05-12 20:28:04 +02:00
|
|
|
Firebird::MetaName trigger_name;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2010-07-26 04:37:57 +02:00
|
|
|
if (ri_actionP)
|
|
|
|
*ri_actionP = 0;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2002-06-30 10:46:51 +02:00
|
|
|
GET_STRING(ptr, index_name);
|
|
|
|
|
2009-11-26 01:20:59 +01:00
|
|
|
if (index_name.isEmpty())
|
2010-07-26 04:37:57 +02:00
|
|
|
DYN_UTIL_generate_index_name(tdbb, gbl->gbl_transaction, index_name, index_type);
|
2002-06-30 10:46:51 +02:00
|
|
|
|
2009-10-21 02:42:38 +02:00
|
|
|
DdlNode::executeDdlTrigger(tdbb, gbl->gbl_transaction, DdlNode::DTW_BEFORE,
|
|
|
|
DDL_TRIGGER_CREATE_INDEX, index_name, gbl->sqlText);
|
|
|
|
|
2010-07-26 04:37:57 +02:00
|
|
|
try
|
|
|
|
{
|
|
|
|
DYN_UTIL_check_unique_name(tdbb, gbl->gbl_transaction, index_name, obj_index);
|
|
|
|
}
|
|
|
|
catch (const Exception& ex)
|
|
|
|
{
|
|
|
|
stuff_exception(tdbb->tdbb_status_vector, ex);
|
|
|
|
DYN_error_punt(true, 21); // msg 21: "STORE RDB$INDICES failed"
|
|
|
|
}
|
2005-05-28 00:45:31 +02:00
|
|
|
|
2010-07-26 04:37:57 +02:00
|
|
|
try
|
2010-04-18 03:10:05 +02:00
|
|
|
{
|
2010-07-26 04:37:57 +02:00
|
|
|
CreateIndexNode::Definition definition;
|
|
|
|
definition.type = index_type;
|
|
|
|
|
2005-05-12 20:28:04 +02:00
|
|
|
if (new_index_name)
|
2010-07-26 04:37:57 +02:00
|
|
|
*new_index_name = index_name;
|
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
if (relation_name)
|
2010-07-26 04:37:57 +02:00
|
|
|
definition.relation = *relation_name;
|
2003-11-08 17:40:17 +01:00
|
|
|
else if (*(*ptr)++ == isc_dyn_rel_name)
|
2010-07-26 04:37:57 +02:00
|
|
|
GET_STRING(ptr, definition.relation);
|
2001-05-23 15:26:42 +02:00
|
|
|
else
|
2010-07-26 04:37:57 +02:00
|
|
|
DYN_error_punt(false, 14); // msg 14: "No relation specified for index"
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
while ((verb = *(*ptr)++) != isc_dyn_end)
|
2010-04-18 03:10:05 +02:00
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
switch (verb)
|
|
|
|
{
|
2010-07-26 04:37:57 +02:00
|
|
|
case isc_dyn_idx_unique:
|
|
|
|
definition.unique = bool(DYN_get_number(ptr));
|
|
|
|
break;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2010-07-26 04:37:57 +02:00
|
|
|
case isc_dyn_idx_inactive:
|
|
|
|
definition.inactive = bool(DYN_get_number(ptr));
|
|
|
|
break;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2010-07-26 04:37:57 +02:00
|
|
|
case isc_dyn_idx_type:
|
|
|
|
definition.descending = bool(DYN_get_number(ptr));
|
|
|
|
break;
|
2005-05-28 00:45:31 +02:00
|
|
|
|
2010-07-26 04:37:57 +02:00
|
|
|
case isc_dyn_fld_name:
|
2006-09-05 11:04:03 +02:00
|
|
|
{
|
2010-07-26 04:37:57 +02:00
|
|
|
MetaName& str = definition.columns.add();
|
2006-09-05 11:04:03 +02:00
|
|
|
GET_STRING(ptr, str);
|
|
|
|
break;
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2010-07-26 04:37:57 +02:00
|
|
|
case isc_dyn_fld_computed_blr:
|
|
|
|
DYN_put_blr_blob(gbl, ptr, &definition.expressionBlr);
|
|
|
|
break;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2010-07-26 04:37:57 +02:00
|
|
|
case isc_dyn_fld_computed_source:
|
|
|
|
DYN_put_text_blob(gbl, ptr, &definition.expressionSource);
|
|
|
|
break;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2010-07-26 04:37:57 +02:00
|
|
|
// for foreign keys, point to the corresponding relation
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2010-07-26 04:37:57 +02:00
|
|
|
case isc_dyn_idx_foreign_key:
|
|
|
|
GET_STRING(ptr, definition.refRelation);
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
2010-07-26 04:37:57 +02:00
|
|
|
case isc_dyn_idx_ref_column:
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2010-07-26 04:37:57 +02:00
|
|
|
MetaName& str = definition.refColumns.add();
|
|
|
|
GET_STRING(ptr, str);
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2010-07-26 04:37:57 +02:00
|
|
|
case isc_dyn_foreign_key_delete:
|
|
|
|
fb_assert(ri_actionP != NULL);
|
|
|
|
switch (verb = *(*ptr)++)
|
|
|
|
{
|
|
|
|
case isc_dyn_foreign_key_cascade:
|
|
|
|
*ri_actionP |= FOR_KEY_DEL_CASCADE;
|
|
|
|
if ((verb = *(*ptr)++) == isc_dyn_def_trigger)
|
|
|
|
{
|
|
|
|
DYN_define_trigger(gbl, ptr, relation_name, &trigger_name, true);
|
|
|
|
fb_assert(cnst_name);
|
|
|
|
DYN_UTIL_store_check_constraints(tdbb, gbl->gbl_transaction, *cnst_name, trigger_name);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
DYN_unsupported_verb();
|
|
|
|
break;
|
2010-04-18 03:10:05 +02:00
|
|
|
|
2010-07-26 04:37:57 +02:00
|
|
|
case isc_dyn_foreign_key_null:
|
|
|
|
*ri_actionP |= FOR_KEY_DEL_NULL;
|
|
|
|
if ((verb = *(*ptr)++) == isc_dyn_def_trigger)
|
|
|
|
{
|
|
|
|
DYN_define_trigger(gbl, ptr, relation_name, &trigger_name, true);
|
|
|
|
fb_assert(cnst_name);
|
|
|
|
DYN_UTIL_store_check_constraints(tdbb, gbl->gbl_transaction, *cnst_name, trigger_name);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
DYN_unsupported_verb();
|
|
|
|
break;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2010-07-26 04:37:57 +02:00
|
|
|
case isc_dyn_foreign_key_default:
|
|
|
|
*ri_actionP |= FOR_KEY_DEL_DEFAULT;
|
|
|
|
if ((verb = *(*ptr)++) == isc_dyn_def_trigger)
|
|
|
|
{
|
|
|
|
DYN_define_trigger(gbl, ptr, relation_name, &trigger_name, true);
|
|
|
|
fb_assert(cnst_name);
|
|
|
|
DYN_UTIL_store_check_constraints(tdbb, gbl->gbl_transaction, *cnst_name, trigger_name);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
DYN_unsupported_verb();
|
|
|
|
break;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2010-07-26 04:37:57 +02:00
|
|
|
case isc_dyn_foreign_key_none:
|
|
|
|
*ri_actionP |= FOR_KEY_DEL_NONE;
|
|
|
|
break;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2010-07-26 04:37:57 +02:00
|
|
|
default:
|
|
|
|
fb_assert(0); // should not come here
|
|
|
|
DYN_unsupported_verb();
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
2010-07-26 04:37:57 +02:00
|
|
|
break;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2010-07-26 04:37:57 +02:00
|
|
|
case isc_dyn_foreign_key_update:
|
|
|
|
fb_assert(ri_actionP != NULL);
|
|
|
|
switch (verb = *(*ptr)++)
|
|
|
|
{
|
|
|
|
case isc_dyn_foreign_key_cascade:
|
|
|
|
*ri_actionP |= FOR_KEY_UPD_CASCADE;
|
|
|
|
if ((verb = *(*ptr)++) == isc_dyn_def_trigger)
|
|
|
|
{
|
|
|
|
DYN_define_trigger(gbl, ptr, relation_name, &trigger_name, true);
|
|
|
|
fb_assert(cnst_name);
|
|
|
|
DYN_UTIL_store_check_constraints(tdbb, gbl->gbl_transaction, *cnst_name, trigger_name);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
DYN_unsupported_verb();
|
|
|
|
break;
|
2006-09-30 18:17:24 +02:00
|
|
|
|
2010-07-26 04:37:57 +02:00
|
|
|
case isc_dyn_foreign_key_null:
|
|
|
|
*ri_actionP |= FOR_KEY_UPD_NULL;
|
|
|
|
if ((verb = *(*ptr)++) == isc_dyn_def_trigger)
|
|
|
|
{
|
|
|
|
DYN_define_trigger(gbl, ptr, relation_name, &trigger_name, true);
|
|
|
|
fb_assert(cnst_name);
|
|
|
|
DYN_UTIL_store_check_constraints(tdbb, gbl->gbl_transaction, *cnst_name, trigger_name);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
DYN_unsupported_verb();
|
|
|
|
break;
|
2008-12-18 11:57:12 +01:00
|
|
|
|
2010-07-26 04:37:57 +02:00
|
|
|
case isc_dyn_foreign_key_default:
|
|
|
|
*ri_actionP |= FOR_KEY_UPD_DEFAULT;
|
|
|
|
if ((verb = *(*ptr)++) == isc_dyn_def_trigger)
|
|
|
|
{
|
|
|
|
DYN_define_trigger(gbl, ptr, relation_name, &trigger_name, true);
|
|
|
|
fb_assert(cnst_name);
|
|
|
|
DYN_UTIL_store_check_constraints(tdbb, gbl->gbl_transaction, *cnst_name, trigger_name);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
DYN_unsupported_verb();
|
|
|
|
break;
|
2006-10-01 11:14:38 +02:00
|
|
|
|
2010-07-26 04:37:57 +02:00
|
|
|
case isc_dyn_foreign_key_none:
|
|
|
|
*ri_actionP |= FOR_KEY_UPD_NONE;
|
|
|
|
break;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2010-07-26 04:37:57 +02:00
|
|
|
default:
|
|
|
|
fb_assert(0); // should not come here
|
|
|
|
DYN_unsupported_verb();
|
|
|
|
}
|
|
|
|
break;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2010-07-26 04:37:57 +02:00
|
|
|
default:
|
|
|
|
DYN_unsupported_verb();
|
2006-10-02 04:39:45 +02:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2010-07-26 04:37:57 +02:00
|
|
|
CreateIndexNode::store(tdbb, gbl->gbl_transaction, index_name, definition,
|
|
|
|
referred_index_name);
|
2001-12-24 03:51:06 +01:00
|
|
|
}
|
2010-07-26 04:37:57 +02:00
|
|
|
catch (const Exception& ex)
|
2009-01-14 10:19:00 +01:00
|
|
|
{
|
2010-07-26 04:37:57 +02:00
|
|
|
stuff_exception(tdbb->tdbb_status_vector, ex);
|
|
|
|
throw;
|
2001-12-24 03:51:06 +01:00
|
|
|
}
|
2009-10-21 02:42:38 +02:00
|
|
|
|
|
|
|
DdlNode::executeDdlTrigger(tdbb, gbl->gbl_transaction, DdlNode::DTW_AFTER,
|
|
|
|
DDL_TRIGGER_CREATE_INDEX, index_name, gbl->sqlText);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-03-31 19:38:53 +02:00
|
|
|
void DYN_define_local_field(Global* gbl,
|
2003-11-05 10:02:33 +01:00
|
|
|
const UCHAR** ptr,
|
2005-05-12 20:28:04 +02:00
|
|
|
const Firebird::MetaName* relation_name,
|
|
|
|
Firebird::MetaName* field_name)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* D Y N _ d e f i n e _ l o c a l _ f i e l d
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Execute a dynamic ddl statement.
|
|
|
|
*
|
|
|
|
**************************************/
|
2003-11-05 10:02:33 +01:00
|
|
|
UCHAR verb;
|
2004-03-28 11:10:30 +02:00
|
|
|
USHORT dtype, length, clength, precision;
|
2001-05-23 15:26:42 +02:00
|
|
|
SSHORT stype, scale;
|
|
|
|
SSHORT charset_id;
|
|
|
|
SLONG fld_pos;
|
|
|
|
|
2004-05-22 16:28:54 +02:00
|
|
|
thread_db* tdbb = JRD_get_thread_data();
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2005-05-17 09:17:25 +02:00
|
|
|
Firebird::MetaName local_field_name;
|
2002-06-30 10:46:51 +02:00
|
|
|
GET_STRING(ptr, local_field_name);
|
|
|
|
|
2004-07-06 07:59:40 +02:00
|
|
|
SSHORT id = -1;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2001-12-24 03:51:06 +01:00
|
|
|
try {
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2010-04-18 03:10:05 +02:00
|
|
|
AutoCacheRequest request(tdbb, drq_s_lfields, DYN_REQUESTS);
|
2001-05-23 15:26:42 +02:00
|
|
|
id = drq_s_lfields;
|
|
|
|
|
2004-03-28 11:10:30 +02:00
|
|
|
bool lflag, sflag, slflag, scflag, clflag, prflag;
|
|
|
|
scflag = lflag = sflag = slflag = clflag = prflag = false;
|
|
|
|
bool charset_id_flag = false;
|
2003-11-05 10:02:33 +01:00
|
|
|
const UCHAR* blr = NULL;
|
|
|
|
const UCHAR* source = NULL;
|
2005-05-12 20:28:04 +02:00
|
|
|
Firebird::MetaName relation_buffer;
|
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
STORE(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
|
2005-05-28 00:45:31 +02:00
|
|
|
RFR IN RDB$RELATION_FIELDS
|
2010-04-18 03:10:05 +02:00
|
|
|
{
|
2005-05-12 20:28:04 +02:00
|
|
|
strcpy(RFR.RDB$FIELD_NAME, local_field_name.c_str());
|
2001-05-23 15:26:42 +02:00
|
|
|
strcpy(RFR.RDB$FIELD_SOURCE, RFR.RDB$FIELD_NAME);
|
2005-05-12 20:28:04 +02:00
|
|
|
if (field_name) {
|
|
|
|
*field_name = RFR.RDB$FIELD_NAME;
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
RFR.RDB$RELATION_NAME.NULL = TRUE;
|
2009-11-25 05:06:48 +01:00
|
|
|
if (relation_name)
|
|
|
|
{
|
2005-05-12 20:28:04 +02:00
|
|
|
strcpy(RFR.RDB$RELATION_NAME, relation_name->c_str());
|
2001-05-23 15:26:42 +02:00
|
|
|
RFR.RDB$RELATION_NAME.NULL = FALSE;
|
|
|
|
}
|
|
|
|
RFR.RDB$SYSTEM_FLAG = 0;
|
|
|
|
RFR.RDB$SYSTEM_FLAG.NULL = FALSE;
|
|
|
|
RFR.RDB$NULL_FLAG.NULL = TRUE;
|
|
|
|
RFR.RDB$BASE_FIELD.NULL = TRUE;
|
|
|
|
RFR.RDB$UPDATE_FLAG.NULL = TRUE;
|
|
|
|
RFR.RDB$FIELD_POSITION.NULL = TRUE;
|
|
|
|
RFR.RDB$VIEW_CONTEXT.NULL = TRUE;
|
|
|
|
RFR.RDB$QUERY_NAME.NULL = TRUE;
|
|
|
|
RFR.RDB$QUERY_HEADER.NULL = TRUE;
|
|
|
|
RFR.RDB$SECURITY_CLASS.NULL = TRUE;
|
|
|
|
RFR.RDB$DEFAULT_VALUE.NULL = TRUE;
|
|
|
|
RFR.RDB$DEFAULT_SOURCE.NULL = TRUE;
|
|
|
|
RFR.RDB$EDIT_STRING.NULL = TRUE;
|
|
|
|
RFR.RDB$COLLATION_ID.NULL = TRUE;
|
2010-01-13 20:14:15 +01:00
|
|
|
RFR.RDB$GENERATOR_NAME.NULL = TRUE;
|
|
|
|
RFR.RDB$IDENTITY_TYPE.NULL = TRUE;
|
2008-12-18 11:57:12 +01:00
|
|
|
|
2005-08-14 07:48:20 +02:00
|
|
|
bool has_default = false;
|
2008-12-18 11:57:12 +01:00
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
while ((verb = *(*ptr)++) != isc_dyn_end)
|
2010-01-13 20:14:15 +01:00
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
switch (verb)
|
|
|
|
{
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_rel_name:
|
2005-05-12 20:28:04 +02:00
|
|
|
GET_STRING(ptr, relation_buffer);
|
|
|
|
relation_name = &relation_buffer;
|
|
|
|
strcpy(RFR.RDB$RELATION_NAME, relation_name->c_str());
|
2001-05-23 15:26:42 +02:00
|
|
|
RFR.RDB$RELATION_NAME.NULL = FALSE;
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_fld_source:
|
2001-05-23 15:26:42 +02:00
|
|
|
GET_STRING(ptr, RFR.RDB$FIELD_SOURCE);
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_fld_base_fld:
|
2001-05-23 15:26:42 +02:00
|
|
|
GET_STRING(ptr, RFR.RDB$BASE_FIELD);
|
|
|
|
RFR.RDB$BASE_FIELD.NULL = FALSE;
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_fld_query_name:
|
2001-05-23 15:26:42 +02:00
|
|
|
GET_STRING(ptr, RFR.RDB$QUERY_NAME);
|
|
|
|
RFR.RDB$QUERY_NAME.NULL = FALSE;
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_fld_query_header:
|
2001-05-23 15:26:42 +02:00
|
|
|
DYN_put_blr_blob(gbl, ptr, &RFR.RDB$QUERY_HEADER);
|
|
|
|
RFR.RDB$QUERY_HEADER.NULL = FALSE;
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_fld_edit_string:
|
2001-05-23 15:26:42 +02:00
|
|
|
GET_STRING(ptr, RFR.RDB$EDIT_STRING);
|
|
|
|
RFR.RDB$EDIT_STRING.NULL = FALSE;
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_fld_position:
|
2001-05-23 15:26:42 +02:00
|
|
|
RFR.RDB$FIELD_POSITION = (SSHORT)DYN_get_number(ptr);
|
|
|
|
RFR.RDB$FIELD_POSITION.NULL = FALSE;
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_system_flag:
|
2001-05-23 15:26:42 +02:00
|
|
|
RFR.RDB$SYSTEM_FLAG = (SSHORT)DYN_get_number(ptr);
|
|
|
|
RFR.RDB$SYSTEM_FLAG.NULL = FALSE;
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_fld_update_flag:
|
|
|
|
case isc_dyn_update_flag:
|
2001-05-23 15:26:42 +02:00
|
|
|
RFR.RDB$UPDATE_FLAG = (SSHORT)DYN_get_number(ptr);
|
|
|
|
RFR.RDB$UPDATE_FLAG.NULL = FALSE;
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_view_context:
|
2001-05-23 15:26:42 +02:00
|
|
|
RFR.RDB$VIEW_CONTEXT = (SSHORT)DYN_get_number(ptr);
|
|
|
|
RFR.RDB$VIEW_CONTEXT.NULL = FALSE;
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_security_class:
|
2001-05-23 15:26:42 +02:00
|
|
|
GET_STRING(ptr, RFR.RDB$SECURITY_CLASS);
|
|
|
|
RFR.RDB$SECURITY_CLASS.NULL = FALSE;
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_fld_computed_blr:
|
2001-05-23 15:26:42 +02:00
|
|
|
DYN_UTIL_generate_field_name(tdbb, gbl, RFR.RDB$FIELD_SOURCE);
|
|
|
|
blr = *ptr;
|
|
|
|
DYN_skip_attribute(ptr);
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_fld_computed_source:
|
2003-11-05 10:02:33 +01:00
|
|
|
source = *ptr;
|
2001-05-23 15:26:42 +02:00
|
|
|
DYN_skip_attribute(ptr);
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_fld_default_value:
|
2005-08-14 07:48:20 +02:00
|
|
|
has_default = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
RFR.RDB$DEFAULT_VALUE.NULL = FALSE;
|
|
|
|
DYN_put_blr_blob(gbl, ptr, &RFR.RDB$DEFAULT_VALUE);
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_fld_default_source:
|
2005-08-14 07:48:20 +02:00
|
|
|
has_default = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
RFR.RDB$DEFAULT_SOURCE.NULL = FALSE;
|
|
|
|
DYN_put_text_blob(gbl, ptr, &RFR.RDB$DEFAULT_SOURCE);
|
|
|
|
break;
|
|
|
|
|
2010-01-13 20:14:15 +01:00
|
|
|
case isc_dyn_fld_identity:
|
|
|
|
{
|
|
|
|
MetaName sequenceName;
|
|
|
|
DYN_UTIL_generate_generator_name(tdbb, sequenceName);
|
|
|
|
|
|
|
|
CreateSequenceNode::store(tdbb, gbl->gbl_transaction, sequenceName,
|
|
|
|
fb_sysflag_identity_generator);
|
|
|
|
|
|
|
|
strcpy(RFR.RDB$GENERATOR_NAME, sequenceName.c_str());
|
|
|
|
RFR.RDB$GENERATOR_NAME.NULL = FALSE;
|
|
|
|
|
|
|
|
RFR.RDB$IDENTITY_TYPE = IDENT_TYPE_BY_DEFAULT;
|
|
|
|
RFR.RDB$IDENTITY_TYPE.NULL = FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_fld_not_null:
|
2001-05-23 15:26:42 +02:00
|
|
|
RFR.RDB$NULL_FLAG.NULL = FALSE;
|
|
|
|
RFR.RDB$NULL_FLAG = TRUE;
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_fld_type:
|
2001-05-23 15:26:42 +02:00
|
|
|
dtype = (USHORT)DYN_get_number(ptr);
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_fld_length:
|
2001-05-23 15:26:42 +02:00
|
|
|
length = (USHORT)DYN_get_number(ptr);
|
2004-03-28 11:10:30 +02:00
|
|
|
lflag = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_fld_sub_type:
|
2001-05-23 15:26:42 +02:00
|
|
|
stype = (SSHORT)DYN_get_number(ptr);
|
2004-03-28 11:10:30 +02:00
|
|
|
sflag = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_fld_char_length:
|
2001-05-23 15:26:42 +02:00
|
|
|
clength = (USHORT)DYN_get_number(ptr);
|
2004-03-28 11:10:30 +02:00
|
|
|
clflag = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_fld_segment_length:
|
2001-05-23 15:26:42 +02:00
|
|
|
stype = (SSHORT)DYN_get_number(ptr);
|
2004-03-28 11:10:30 +02:00
|
|
|
slflag = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_fld_scale:
|
2001-05-23 15:26:42 +02:00
|
|
|
scale = (SSHORT)DYN_get_number(ptr);
|
2004-03-28 11:10:30 +02:00
|
|
|
scflag = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case isc_dyn_fld_precision:
|
|
|
|
precision = (USHORT)DYN_get_number(ptr);
|
2004-03-28 11:10:30 +02:00
|
|
|
prflag = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_fld_character_set:
|
2001-05-23 15:26:42 +02:00
|
|
|
charset_id = (SSHORT)DYN_get_number(ptr);
|
2004-03-28 11:10:30 +02:00
|
|
|
charset_id_flag = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_fld_collation:
|
2001-05-23 15:26:42 +02:00
|
|
|
RFR.RDB$COLLATION_ID.NULL = FALSE;
|
|
|
|
RFR.RDB$COLLATION_ID = (SSHORT)DYN_get_number(ptr);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2010-01-28 16:01:57 +01:00
|
|
|
{
|
2010-01-24 16:16:23 +01:00
|
|
|
MetaNameProxy tmp(RFR.RDB$FIELD_SOURCE);
|
2005-05-12 20:28:04 +02:00
|
|
|
DYN_execute(gbl, ptr, relation_name, &tmp, NULL, NULL, NULL);
|
2010-01-24 16:16:23 +01:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
2010-01-13 20:14:15 +01:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2005-08-14 07:48:20 +02:00
|
|
|
if (has_default && DYN_UTIL_is_array(tdbb, gbl, RFR.RDB$FIELD_SOURCE))
|
|
|
|
{
|
2007-03-28 06:20:36 +02:00
|
|
|
DYN_error_punt(false, 226, RFR.RDB$FIELD_SOURCE);
|
2005-08-14 07:48:20 +02:00
|
|
|
// msg 226: "Default value is not allowed for array type in domain %s"
|
|
|
|
}
|
|
|
|
|
2010-01-13 20:14:15 +01:00
|
|
|
if (!RFR.RDB$GENERATOR_NAME.NULL)
|
|
|
|
{
|
|
|
|
dsc desc;
|
|
|
|
MET_get_domain(tdbb, RFR.RDB$FIELD_SOURCE, &desc, NULL);
|
|
|
|
|
|
|
|
if (!desc.isExact() || desc.dsc_scale != 0)
|
|
|
|
{
|
|
|
|
// Identity column @1 of table @2 must be exact numeric with zero scale.
|
|
|
|
DYN_error_punt(false, 273,
|
|
|
|
SafeArg() << local_field_name.c_str() << relation_name->c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-11-25 05:06:48 +01:00
|
|
|
if (RFR.RDB$FIELD_POSITION.NULL == TRUE)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
fld_pos = -1;
|
2005-05-17 09:17:25 +02:00
|
|
|
fb_assert(relation_name);
|
2008-12-18 11:57:12 +01:00
|
|
|
DYN_UTIL_generate_field_position(tdbb, gbl, *relation_name, &fld_pos);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-11-25 05:06:48 +01:00
|
|
|
if (fld_pos >= 0)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
RFR.RDB$FIELD_POSITION = (SSHORT)++fld_pos;
|
|
|
|
RFR.RDB$FIELD_POSITION.NULL = FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-11-25 05:06:48 +01:00
|
|
|
if (blr)
|
|
|
|
{
|
2004-03-07 08:58:55 +01:00
|
|
|
const SSHORT old_id = id;
|
2010-04-18 03:10:05 +02:00
|
|
|
AutoCacheRequest request2(tdbb, drq_s_gfields2, DYN_REQUESTS);
|
|
|
|
id = drq_s_gfields2;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2010-04-18 03:10:05 +02:00
|
|
|
STORE(REQUEST_HANDLE request2 TRANSACTION_HANDLE gbl->gbl_transaction)
|
2001-05-23 15:26:42 +02:00
|
|
|
FLD IN RDB$FIELDS
|
2010-04-18 03:10:05 +02:00
|
|
|
{
|
2008-03-26 03:07:56 +01:00
|
|
|
FLD.RDB$SYSTEM_FLAG = 0;
|
|
|
|
FLD.RDB$SYSTEM_FLAG.NULL = FALSE;
|
2005-10-30 08:44:26 +01:00
|
|
|
strcpy(FLD.RDB$FIELD_NAME, RFR.RDB$FIELD_SOURCE);
|
2001-05-23 15:26:42 +02:00
|
|
|
DYN_put_blr_blob(gbl, &blr, &FLD.RDB$COMPUTED_BLR);
|
|
|
|
if (source) {
|
2003-11-05 10:02:33 +01:00
|
|
|
DYN_put_text_blob(gbl, &source, &FLD.RDB$COMPUTED_SOURCE);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
FLD.RDB$FIELD_TYPE = dtype;
|
2008-03-26 03:07:56 +01:00
|
|
|
FLD.RDB$FIELD_TYPE.NULL = FALSE;
|
2009-11-25 05:06:48 +01:00
|
|
|
if (lflag)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
FLD.RDB$FIELD_LENGTH = length;
|
|
|
|
FLD.RDB$FIELD_LENGTH.NULL = FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
FLD.RDB$FIELD_LENGTH.NULL = TRUE;
|
2009-11-25 05:06:48 +01:00
|
|
|
if (sflag)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
FLD.RDB$FIELD_SUB_TYPE = stype;
|
|
|
|
FLD.RDB$FIELD_SUB_TYPE.NULL = FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
FLD.RDB$FIELD_SUB_TYPE.NULL = TRUE;
|
2009-11-25 05:06:48 +01:00
|
|
|
if (clflag)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
FLD.RDB$CHARACTER_LENGTH = clength;
|
|
|
|
FLD.RDB$CHARACTER_LENGTH.NULL = FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
FLD.RDB$CHARACTER_LENGTH.NULL = TRUE;
|
2009-11-25 05:06:48 +01:00
|
|
|
if (slflag)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
FLD.RDB$SEGMENT_LENGTH = stype;
|
|
|
|
FLD.RDB$SEGMENT_LENGTH.NULL = FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
FLD.RDB$SEGMENT_LENGTH.NULL = TRUE;
|
2009-11-25 05:06:48 +01:00
|
|
|
if (scflag)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
FLD.RDB$FIELD_SCALE = scale;
|
|
|
|
FLD.RDB$FIELD_SCALE.NULL = FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
FLD.RDB$FIELD_SCALE.NULL = TRUE;
|
2009-11-25 05:06:48 +01:00
|
|
|
if (prflag)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
FLD.RDB$FIELD_PRECISION = precision;
|
|
|
|
FLD.RDB$FIELD_PRECISION.NULL = FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
FLD.RDB$FIELD_PRECISION.NULL = TRUE;
|
2009-11-25 05:06:48 +01:00
|
|
|
if (charset_id_flag)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
FLD.RDB$CHARACTER_SET_ID = charset_id;
|
|
|
|
FLD.RDB$CHARACTER_SET_ID.NULL = FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
FLD.RDB$CHARACTER_SET_ID.NULL = TRUE;
|
2010-04-18 03:10:05 +02:00
|
|
|
}
|
|
|
|
END_STORE
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
id = old_id;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!RFR.RDB$VIEW_CONTEXT.NULL)
|
2005-05-17 09:17:25 +02:00
|
|
|
{
|
|
|
|
fb_assert(relation_name);
|
2008-01-16 09:46:02 +01:00
|
|
|
DYN_UTIL_find_field_source(tdbb, gbl, *relation_name, RFR.RDB$VIEW_CONTEXT,
|
|
|
|
RFR.RDB$BASE_FIELD, RFR.RDB$FIELD_SOURCE);
|
2005-05-17 09:17:25 +02:00
|
|
|
}
|
2001-12-24 03:51:06 +01:00
|
|
|
}
|
2010-04-18 03:10:05 +02:00
|
|
|
END_STORE
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2001-12-24 03:51:06 +01:00
|
|
|
} // try
|
2009-11-25 05:06:48 +01:00
|
|
|
catch (const Firebird::Exception& ex)
|
|
|
|
{
|
2004-03-01 04:35:23 +01:00
|
|
|
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
|
2009-11-25 05:06:48 +01:00
|
|
|
if (id == drq_s_lfields)
|
|
|
|
{
|
2007-03-28 06:20:36 +02:00
|
|
|
DYN_error_punt(true, 23);
|
2009-11-21 08:38:05 +01:00
|
|
|
// msg 23: "STORE RDB$RELATION_FIELDS failed"
|
2001-12-24 03:51:06 +01:00
|
|
|
}
|
2009-11-25 05:06:48 +01:00
|
|
|
else
|
|
|
|
{
|
2007-03-28 06:20:36 +02:00
|
|
|
DYN_error_punt(true, 22);
|
2009-11-21 08:38:05 +01:00
|
|
|
// msg 22: "STORE RDB$FIELDS failed"
|
2001-12-24 03:51:06 +01:00
|
|
|
}
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-07-26 04:37:57 +02:00
|
|
|
void DYN_define_view(Global* gbl, const UCHAR** ptr)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
2010-07-26 04:37:57 +02:00
|
|
|
* D Y N _ d e f i n e _ v i e w
|
2001-05-23 15:26:42 +02:00
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Execute a dynamic ddl statement.
|
|
|
|
*
|
|
|
|
**************************************/
|
2005-05-17 09:17:25 +02:00
|
|
|
Firebird::MetaName relation_name, owner_name;
|
|
|
|
Firebird::MetaName field_name; // unused, only passed empty to DYN_execute again.
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-22 16:28:54 +02:00
|
|
|
thread_db* tdbb = JRD_get_thread_data();
|
2009-12-17 01:07:23 +01:00
|
|
|
Jrd::Attachment* attachment = tdbb->getAttachment();
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
GET_STRING(ptr, relation_name);
|
|
|
|
|
2009-10-21 02:42:38 +02:00
|
|
|
DdlNode::executeDdlTrigger(tdbb, gbl->gbl_transaction, DdlNode::DTW_BEFORE,
|
2010-07-26 04:37:57 +02:00
|
|
|
DDL_TRIGGER_CREATE_VIEW, relation_name, gbl->sqlText);
|
2009-10-21 02:42:38 +02:00
|
|
|
|
2004-07-06 07:59:40 +02:00
|
|
|
SSHORT id = -1;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-02-08 18:08:34 +01:00
|
|
|
Firebird::PathName Path, Name;
|
2003-03-23 17:50:54 +01:00
|
|
|
|
2001-12-24 03:51:06 +01:00
|
|
|
try {
|
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
id = drq_l_rel_name;
|
2009-10-21 02:42:38 +02:00
|
|
|
DYN_UTIL_check_unique_name(tdbb, gbl->gbl_transaction, relation_name, obj_relation);
|
2006-07-17 19:44:18 +02:00
|
|
|
bool sql_prot = false;
|
|
|
|
rel_t rel_type = rel_persistent;
|
2004-03-28 11:10:30 +02:00
|
|
|
|
2010-04-18 03:10:05 +02:00
|
|
|
AutoCacheRequest request(tdbb, drq_s_rels, DYN_REQUESTS);
|
2001-05-23 15:26:42 +02:00
|
|
|
id = drq_s_rels;
|
|
|
|
|
|
|
|
STORE(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
|
2005-05-28 00:45:31 +02:00
|
|
|
REL IN RDB$RELATIONS
|
2010-04-18 03:10:05 +02:00
|
|
|
{
|
2005-10-30 08:44:26 +01:00
|
|
|
strcpy(REL.RDB$RELATION_NAME, relation_name.c_str());
|
|
|
|
REL.RDB$SYSTEM_FLAG = 0;
|
|
|
|
REL.RDB$SYSTEM_FLAG.NULL = FALSE;
|
2001-05-23 15:26:42 +02:00
|
|
|
REL.RDB$VIEW_BLR.NULL = TRUE;
|
|
|
|
REL.RDB$VIEW_SOURCE.NULL = TRUE;
|
|
|
|
REL.RDB$SECURITY_CLASS.NULL = TRUE;
|
|
|
|
REL.RDB$EXTERNAL_FILE.NULL = TRUE;
|
|
|
|
REL.RDB$FLAGS = 0;
|
|
|
|
REL.RDB$FLAGS.NULL = FALSE;
|
2009-11-27 07:57:17 +01:00
|
|
|
REL.RDB$RELATION_TYPE.NULL = FALSE;
|
|
|
|
|
2004-07-06 07:59:40 +02:00
|
|
|
UCHAR verb;
|
2003-11-08 17:40:17 +01:00
|
|
|
while ((verb = *(*ptr)++) != isc_dyn_end)
|
2006-05-25 05:15:53 +02:00
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
switch (verb)
|
|
|
|
{
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_system_flag:
|
2001-05-23 15:26:42 +02:00
|
|
|
REL.RDB$SYSTEM_FLAG = DYN_get_number(ptr);
|
|
|
|
REL.RDB$SYSTEM_FLAG.NULL = FALSE;
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_sql_object:
|
2001-05-23 15:26:42 +02:00
|
|
|
REL.RDB$FLAGS |= REL_sql;
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_view_blr:
|
2001-05-23 15:26:42 +02:00
|
|
|
REL.RDB$VIEW_BLR.NULL = FALSE;
|
2006-07-17 19:44:18 +02:00
|
|
|
rel_type = rel_view;
|
2001-05-23 15:26:42 +02:00
|
|
|
DYN_put_blr_blob(gbl, ptr, &REL.RDB$VIEW_BLR);
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_view_source:
|
2001-05-23 15:26:42 +02:00
|
|
|
DYN_put_text_blob(gbl, ptr, &REL.RDB$VIEW_SOURCE);
|
|
|
|
REL.RDB$VIEW_SOURCE.NULL = FALSE;
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_security_class:
|
2001-05-23 15:26:42 +02:00
|
|
|
GET_STRING(ptr, REL.RDB$SECURITY_CLASS);
|
|
|
|
REL.RDB$SECURITY_CLASS.NULL = FALSE;
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_rel_sql_protection:
|
2001-05-23 15:26:42 +02:00
|
|
|
REL.RDB$FLAGS |= REL_sql;
|
2004-03-28 11:10:30 +02:00
|
|
|
sql_prot = (bool) DYN_get_number(ptr);
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
--(*ptr);
|
2010-01-24 16:16:23 +01:00
|
|
|
{
|
2010-01-26 09:34:13 +01:00
|
|
|
const MetaName tmp(REL.RDB$RELATION_NAME);
|
2005-05-12 20:28:04 +02:00
|
|
|
DYN_execute(gbl, ptr, &tmp, &field_name, NULL, NULL, NULL);
|
2010-01-24 16:16:23 +01:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
2009-11-27 03:33:40 +01:00
|
|
|
} // while
|
|
|
|
|
2009-11-27 07:57:17 +01:00
|
|
|
// The relation type cannot be determined definitely inside the above loop,
|
|
|
|
// because there are many DYN codes that affect it.
|
|
|
|
REL.RDB$RELATION_TYPE = rel_type;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-11-25 05:06:48 +01:00
|
|
|
if (sql_prot)
|
|
|
|
{
|
2009-12-17 01:07:23 +01:00
|
|
|
owner_name = attachment->att_user->usr_user_name;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-11-25 05:06:48 +01:00
|
|
|
if (rel_type == rel_view)
|
|
|
|
{
|
2006-09-01 12:51:57 +02:00
|
|
|
const SSHORT old_id2 = id;
|
2010-04-18 03:10:05 +02:00
|
|
|
AutoCacheRequest request2(tdbb, drq_l_view_rels, DYN_REQUESTS);
|
2001-05-23 15:26:42 +02:00
|
|
|
id = drq_l_view_rels;
|
|
|
|
|
2010-04-18 03:10:05 +02:00
|
|
|
FOR(REQUEST_HANDLE request2 TRANSACTION_HANDLE gbl->gbl_transaction)
|
2001-05-23 15:26:42 +02:00
|
|
|
VRL IN RDB$VIEW_RELATIONS CROSS
|
|
|
|
PREL IN RDB$RELATIONS OVER RDB$RELATION_NAME WITH
|
2009-12-17 16:07:02 +01:00
|
|
|
VRL.RDB$PACKAGE_NAME MISSING AND
|
2005-05-12 20:28:04 +02:00
|
|
|
VRL.RDB$VIEW_NAME EQ relation_name.c_str()
|
2010-04-18 03:10:05 +02:00
|
|
|
{
|
2009-11-21 08:38:05 +01:00
|
|
|
// CVC: This never matches so it causes unnecessary calls to verify,
|
|
|
|
// so I included a call to strip trailing blanks.
|
2004-09-26 03:49:52 +02:00
|
|
|
fb_utils::exact_name_limit(PREL.RDB$OWNER_NAME, sizeof(PREL.RDB$OWNER_NAME));
|
2009-11-25 05:06:48 +01:00
|
|
|
if (owner_name != PREL.RDB$OWNER_NAME)
|
|
|
|
{
|
2004-07-06 07:59:40 +02:00
|
|
|
SecurityClass::flags_t priv;
|
2008-12-18 11:57:12 +01:00
|
|
|
if (!DYN_UTIL_get_prot(tdbb, gbl, PREL.RDB$RELATION_NAME, "", &priv))
|
2004-07-06 07:59:40 +02:00
|
|
|
{
|
2005-01-26 09:04:50 +01:00
|
|
|
// I think this should be the responsability of DFW
|
|
|
|
// or the user will find ways to circumvent DYN.
|
2007-03-28 06:20:36 +02:00
|
|
|
DYN_error_punt(true, 115);
|
2009-11-21 08:38:05 +01:00
|
|
|
// msg 115: "CREATE VIEW failed"
|
2004-07-06 07:59:40 +02:00
|
|
|
}
|
2005-05-28 00:45:31 +02:00
|
|
|
|
2009-11-25 05:06:48 +01:00
|
|
|
if (!(priv & SCL_read))
|
|
|
|
{
|
2008-08-27 14:20:47 +02:00
|
|
|
ERR_post_nothrow(Arg::Gds(isc_no_priv) << Arg::Str("SELECT") << // Non-Translatable
|
|
|
|
// Remember, a view may be based on a view.
|
|
|
|
Arg::Str("TABLE/VIEW") << // Non-Translatable
|
|
|
|
// We want to print the name of the base table or view.
|
|
|
|
Arg::Str(PREL.RDB$RELATION_NAME));
|
2009-11-21 08:38:05 +01:00
|
|
|
// msg 32: no permission for %s access to %s %s
|
2007-03-28 06:20:36 +02:00
|
|
|
DYN_error_punt(true, 115);
|
2009-11-21 08:38:05 +01:00
|
|
|
// msg 115: "CREATE VIEW failed"
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
}
|
2010-04-18 03:10:05 +02:00
|
|
|
}
|
|
|
|
END_FOR
|
|
|
|
|
2006-09-01 12:51:57 +02:00
|
|
|
id = old_id2;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
}
|
2010-04-18 03:10:05 +02:00
|
|
|
}
|
|
|
|
END_STORE
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (sql_prot)
|
2009-10-21 02:42:38 +02:00
|
|
|
{
|
2009-11-25 05:06:48 +01:00
|
|
|
for (const TEXT* p = ALL_PRIVILEGES; *p; p++)
|
|
|
|
{
|
2010-04-18 03:10:05 +02:00
|
|
|
request.reset(tdbb, drq_s_usr_prvs, DYN_REQUESTS);
|
2001-05-23 15:26:42 +02:00
|
|
|
id = drq_s_usr_prvs;
|
|
|
|
|
|
|
|
STORE(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
|
|
|
|
X IN RDB$USER_PRIVILEGES
|
2010-04-18 03:10:05 +02:00
|
|
|
{
|
2005-10-30 08:44:26 +01:00
|
|
|
strcpy(X.RDB$RELATION_NAME, relation_name.c_str());
|
2005-05-12 20:28:04 +02:00
|
|
|
strcpy(X.RDB$USER, owner_name.c_str());
|
2001-05-23 15:26:42 +02:00
|
|
|
X.RDB$USER_TYPE = obj_user;
|
|
|
|
X.RDB$OBJECT_TYPE = obj_relation;
|
|
|
|
X.RDB$PRIVILEGE[0] = *p;
|
|
|
|
X.RDB$PRIVILEGE[1] = 0;
|
|
|
|
X.RDB$GRANT_OPTION = 1;
|
2010-04-18 03:10:05 +02:00
|
|
|
}
|
|
|
|
END_STORE
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
2009-10-21 02:42:38 +02:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2001-12-24 03:51:06 +01:00
|
|
|
}
|
2009-01-14 10:19:00 +01:00
|
|
|
catch (const Firebird::Exception& ex)
|
|
|
|
{
|
2004-03-01 04:35:23 +01:00
|
|
|
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
|
2009-11-25 05:06:48 +01:00
|
|
|
if (id == drq_s_rels)
|
|
|
|
{
|
2007-03-28 06:20:36 +02:00
|
|
|
DYN_error_punt(true, 24);
|
2009-11-21 08:38:05 +01:00
|
|
|
// msg 24: "STORE RDB$RELATIONS failed"
|
2001-12-24 03:51:06 +01:00
|
|
|
}
|
2009-11-25 05:06:48 +01:00
|
|
|
else if (id == drq_s_usr_prvs)
|
|
|
|
{
|
2007-03-28 06:20:36 +02:00
|
|
|
DYN_error_punt(true, 25);
|
2009-11-21 08:38:05 +01:00
|
|
|
// msg 25: "STORE RDB$USER_PRIVILEGES failed defining a relation"
|
2001-12-24 03:51:06 +01:00
|
|
|
}
|
|
|
|
|
2009-01-14 10:19:00 +01:00
|
|
|
switch (id)
|
|
|
|
{
|
|
|
|
case drq_l_rel_name:
|
2009-11-21 08:38:05 +01:00
|
|
|
DYN_error_punt(true, 24); // msg 24: "STORE RDB$RELATIONS failed"
|
2009-01-14 10:19:00 +01:00
|
|
|
break;
|
|
|
|
case drq_l_view_rels:
|
2009-11-21 08:38:05 +01:00
|
|
|
DYN_error_punt(true, 115); // msg 115: "CREATE VIEW failed"
|
2009-01-14 10:19:00 +01:00
|
|
|
break;
|
|
|
|
}
|
2001-12-24 03:51:06 +01:00
|
|
|
|
2009-11-21 08:38:05 +01:00
|
|
|
// Control should never reach this point, because id should
|
|
|
|
// always have one of the values test-for above.
|
2008-03-17 18:58:47 +01:00
|
|
|
fb_assert(false);
|
2007-03-28 06:20:36 +02:00
|
|
|
DYN_error_punt(true, 0);
|
2001-12-24 03:51:06 +01:00
|
|
|
}
|
2009-10-21 02:42:38 +02:00
|
|
|
|
|
|
|
DdlNode::executeDdlTrigger(tdbb, gbl->gbl_transaction, DdlNode::DTW_AFTER,
|
2010-07-26 04:37:57 +02:00
|
|
|
DDL_TRIGGER_CREATE_VIEW, relation_name, gbl->sqlText);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-03-31 19:38:53 +02:00
|
|
|
void DYN_define_role( Global* gbl, const UCHAR** ptr)
|
2002-06-30 10:46:51 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* D Y N _ d e f i n e _ r o l e
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
*
|
|
|
|
* Define a SQL role.
|
2005-05-28 00:45:31 +02:00
|
|
|
* ROLES cannot be named the same as any existing user name
|
2002-06-30 10:46:51 +02:00
|
|
|
*
|
|
|
|
**************************************/
|
2004-05-22 16:28:54 +02:00
|
|
|
thread_db* tdbb = JRD_get_thread_data();
|
2005-05-28 00:45:31 +02:00
|
|
|
|
2007-12-03 16:46:39 +01:00
|
|
|
Firebird::MetaName owner_name(tdbb->getAttachment()->att_user->usr_user_name);
|
2005-05-12 20:28:04 +02:00
|
|
|
owner_name.upper7();
|
2002-06-30 10:46:51 +02:00
|
|
|
|
2005-05-17 09:17:25 +02:00
|
|
|
Firebird::MetaName role_name;
|
2002-06-30 10:46:51 +02:00
|
|
|
GET_STRING(ptr, role_name);
|
|
|
|
|
2009-10-21 02:42:38 +02:00
|
|
|
DdlNode::executeDdlTrigger(tdbb, gbl->gbl_transaction, DdlNode::DTW_BEFORE,
|
|
|
|
DDL_TRIGGER_CREATE_ROLE, role_name, gbl->sqlText);
|
|
|
|
|
2009-11-25 05:06:48 +01:00
|
|
|
if (role_name == owner_name)
|
|
|
|
{
|
2009-11-21 08:38:05 +01:00
|
|
|
// user name could not be used for SQL role
|
2007-03-28 06:20:36 +02:00
|
|
|
DYN_error(false, 193, SafeArg() << owner_name.c_str());
|
2002-06-30 10:46:51 +02:00
|
|
|
ERR_punt();
|
|
|
|
}
|
|
|
|
|
2009-11-25 05:06:48 +01:00
|
|
|
if (role_name == NULL_ROLE)
|
|
|
|
{
|
2009-11-21 08:38:05 +01:00
|
|
|
// keyword NONE could not be used as SQL role name
|
2007-03-28 06:20:36 +02:00
|
|
|
DYN_error(false, 195, SafeArg() << role_name.c_str());
|
2002-06-30 10:46:51 +02:00
|
|
|
ERR_punt();
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
2009-11-25 05:06:48 +01:00
|
|
|
if (is_it_user_name(gbl, role_name, tdbb))
|
|
|
|
{
|
2009-11-21 08:38:05 +01:00
|
|
|
// user name could not be used for SQL role
|
2007-03-28 06:20:36 +02:00
|
|
|
DYN_error(false, 193, SafeArg() << role_name.c_str());
|
2002-06-30 10:46:51 +02:00
|
|
|
goto do_err_punt;
|
|
|
|
}
|
|
|
|
|
2005-05-17 09:17:25 +02:00
|
|
|
Firebird::MetaName dummy_name;
|
2009-11-25 05:06:48 +01:00
|
|
|
if (DYN_is_it_sql_role(gbl, role_name, dummy_name, tdbb))
|
|
|
|
{
|
2009-11-21 08:38:05 +01:00
|
|
|
// SQL role @1 already exists
|
2007-03-28 06:20:36 +02:00
|
|
|
DYN_error(false, 194, SafeArg() << role_name.c_str());
|
2002-06-30 10:46:51 +02:00
|
|
|
goto do_err_punt;
|
|
|
|
}
|
|
|
|
|
2010-04-18 03:10:05 +02:00
|
|
|
AutoCacheRequest request(tdbb, drq_role_gens, DYN_REQUESTS);
|
2002-06-30 10:46:51 +02:00
|
|
|
|
2009-11-24 12:42:56 +01:00
|
|
|
STORE(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
|
|
|
|
X IN RDB$ROLES
|
2010-04-18 03:10:05 +02:00
|
|
|
{
|
2009-11-24 12:42:56 +01:00
|
|
|
strcpy(X.RDB$ROLE_NAME, role_name.c_str());
|
|
|
|
strcpy(X.RDB$OWNER_NAME, owner_name.c_str());
|
|
|
|
X.RDB$SYSTEM_FLAG = 0;
|
|
|
|
X.RDB$SYSTEM_FLAG.NULL = FALSE;
|
2002-06-30 10:46:51 +02:00
|
|
|
}
|
2010-04-18 03:10:05 +02:00
|
|
|
END_STORE
|
2002-06-30 10:46:51 +02:00
|
|
|
|
2010-04-18 03:10:05 +02:00
|
|
|
if (*(*ptr)++ != isc_dyn_end)
|
2002-06-30 10:46:51 +02:00
|
|
|
goto do_error_punt_9;
|
|
|
|
}
|
2009-11-25 05:06:48 +01:00
|
|
|
catch (const Firebird::Exception& ex)
|
|
|
|
{
|
2004-03-01 04:35:23 +01:00
|
|
|
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
|
2007-03-28 06:20:36 +02:00
|
|
|
DYN_error_punt(true, 8);
|
2009-11-21 08:38:05 +01:00
|
|
|
// msg 8: "DEFINE ROLE failed"
|
2002-06-30 10:46:51 +02:00
|
|
|
}
|
|
|
|
|
2009-10-21 02:42:38 +02:00
|
|
|
DdlNode::executeDdlTrigger(tdbb, gbl->gbl_transaction, DdlNode::DTW_AFTER,
|
|
|
|
DDL_TRIGGER_CREATE_ROLE, role_name, gbl->sqlText);
|
|
|
|
|
2002-06-30 10:46:51 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
do_err_punt:
|
|
|
|
ERR_punt();
|
|
|
|
return;
|
|
|
|
|
|
|
|
do_error_punt_9:
|
2007-03-28 06:20:36 +02:00
|
|
|
DYN_error_punt(true, 9);
|
2009-11-21 08:38:05 +01:00
|
|
|
// msg 9: "DEFINE ROLE unexpected dyn verb"
|
2002-06-30 10:46:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-03-31 19:38:53 +02:00
|
|
|
void DYN_define_sql_field(Global* gbl,
|
2003-11-05 10:02:33 +01:00
|
|
|
const UCHAR** ptr,
|
2005-05-12 20:28:04 +02:00
|
|
|
const Firebird::MetaName* relation_name,
|
|
|
|
Firebird::MetaName* field_name)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* D Y N _ d e f i n e _ s q l _ f i e l d
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Define a local, SQL field. This will require generation of
|
|
|
|
* an global field name.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
UCHAR verb;
|
|
|
|
USHORT dtype;
|
|
|
|
SLONG fld_pos;
|
|
|
|
|
2004-05-22 16:28:54 +02:00
|
|
|
thread_db* tdbb = JRD_get_thread_data();
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2005-05-17 09:17:25 +02:00
|
|
|
Firebird::MetaName sql_field_name;
|
2002-06-30 10:46:51 +02:00
|
|
|
GET_STRING(ptr, sql_field_name);
|
|
|
|
|
2004-07-06 07:59:40 +02:00
|
|
|
SSHORT id = -1;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2001-12-24 03:51:06 +01:00
|
|
|
try {
|
|
|
|
|
2010-04-18 03:10:05 +02:00
|
|
|
AutoCacheRequest request(tdbb, drq_s_sql_lfld, DYN_REQUESTS);
|
2001-05-23 15:26:42 +02:00
|
|
|
id = drq_s_sql_lfld;
|
|
|
|
|
|
|
|
STORE(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
|
2005-05-28 00:45:31 +02:00
|
|
|
RFR IN RDB$RELATION_FIELDS
|
2010-04-18 03:10:05 +02:00
|
|
|
{
|
2005-05-12 20:28:04 +02:00
|
|
|
strcpy(RFR.RDB$FIELD_NAME, sql_field_name.c_str());
|
|
|
|
if (field_name)
|
|
|
|
*field_name = RFR.RDB$FIELD_NAME;
|
2001-05-23 15:26:42 +02:00
|
|
|
if (relation_name)
|
2005-05-12 20:28:04 +02:00
|
|
|
strcpy(RFR.RDB$RELATION_NAME, relation_name->c_str());
|
2001-05-23 15:26:42 +02:00
|
|
|
RFR.RDB$SYSTEM_FLAG = 0;
|
|
|
|
RFR.RDB$SYSTEM_FLAG.NULL = FALSE;
|
|
|
|
RFR.RDB$QUERY_NAME.NULL = TRUE;
|
|
|
|
RFR.RDB$QUERY_HEADER.NULL = TRUE;
|
|
|
|
RFR.RDB$EDIT_STRING.NULL = TRUE;
|
|
|
|
RFR.RDB$FIELD_POSITION.NULL = TRUE;
|
|
|
|
RFR.RDB$VIEW_CONTEXT.NULL = TRUE;
|
|
|
|
RFR.RDB$BASE_FIELD.NULL = TRUE;
|
|
|
|
RFR.RDB$UPDATE_FLAG.NULL = TRUE;
|
|
|
|
RFR.RDB$NULL_FLAG.NULL = TRUE;
|
|
|
|
RFR.RDB$DEFAULT_SOURCE.NULL = TRUE;
|
|
|
|
RFR.RDB$DEFAULT_VALUE.NULL = TRUE;
|
|
|
|
RFR.RDB$COLLATION_ID.NULL = TRUE;
|
2010-01-13 20:14:15 +01:00
|
|
|
RFR.RDB$GENERATOR_NAME.NULL = TRUE;
|
|
|
|
RFR.RDB$IDENTITY_TYPE.NULL = TRUE;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-03-07 08:58:55 +01:00
|
|
|
const SSHORT old_id = id;
|
2010-04-18 03:10:05 +02:00
|
|
|
AutoCacheRequest request2(tdbb, drq_s_sql_gfld, DYN_REQUESTS);
|
2001-05-23 15:26:42 +02:00
|
|
|
id = drq_s_sql_gfld;
|
|
|
|
|
2010-04-18 03:10:05 +02:00
|
|
|
STORE(REQUEST_HANDLE request2 TRANSACTION_HANDLE gbl->gbl_transaction)
|
2005-10-30 08:44:26 +01:00
|
|
|
FLD IN RDB$FIELDS
|
2010-04-18 03:10:05 +02:00
|
|
|
{
|
2005-10-30 08:44:26 +01:00
|
|
|
FLD.RDB$SYSTEM_FLAG = 0;
|
|
|
|
FLD.RDB$SYSTEM_FLAG.NULL = FALSE;
|
2001-05-23 15:26:42 +02:00
|
|
|
FLD.RDB$FIELD_SCALE.NULL = TRUE;
|
|
|
|
FLD.RDB$FIELD_PRECISION.NULL = TRUE;
|
|
|
|
FLD.RDB$FIELD_SUB_TYPE.NULL = TRUE;
|
|
|
|
FLD.RDB$SEGMENT_LENGTH.NULL = TRUE;
|
|
|
|
FLD.RDB$COMPUTED_BLR.NULL = TRUE;
|
|
|
|
FLD.RDB$COMPUTED_SOURCE.NULL = TRUE;
|
|
|
|
FLD.RDB$DEFAULT_VALUE.NULL = TRUE;
|
|
|
|
FLD.RDB$DEFAULT_SOURCE.NULL = TRUE;
|
|
|
|
FLD.RDB$VALIDATION_BLR.NULL = TRUE;
|
|
|
|
FLD.RDB$VALIDATION_SOURCE.NULL = TRUE;
|
|
|
|
FLD.RDB$NULL_FLAG.NULL = TRUE;
|
|
|
|
FLD.RDB$EDIT_STRING.NULL = TRUE;
|
|
|
|
FLD.RDB$DIMENSIONS.NULL = TRUE;
|
|
|
|
FLD.RDB$CHARACTER_LENGTH.NULL = TRUE;
|
|
|
|
FLD.RDB$CHARACTER_SET_ID.NULL = TRUE;
|
|
|
|
FLD.RDB$COLLATION_ID.NULL = TRUE;
|
|
|
|
|
2005-08-14 07:48:20 +02:00
|
|
|
bool has_dimensions = false;
|
|
|
|
bool has_default = false;
|
2008-12-18 11:57:12 +01:00
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
DYN_UTIL_generate_field_name(tdbb, gbl, RFR.RDB$FIELD_SOURCE);
|
|
|
|
strcpy(FLD.RDB$FIELD_NAME, RFR.RDB$FIELD_SOURCE);
|
2010-01-13 20:14:15 +01:00
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
while ((verb = *(*ptr)++) != isc_dyn_end)
|
2010-01-13 20:14:15 +01:00
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
switch (verb)
|
|
|
|
{
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_rel_name:
|
2001-05-23 15:26:42 +02:00
|
|
|
GET_STRING(ptr, RFR.RDB$RELATION_NAME);
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_fld_query_name:
|
2001-05-23 15:26:42 +02:00
|
|
|
GET_STRING(ptr, RFR.RDB$QUERY_NAME);
|
|
|
|
RFR.RDB$QUERY_NAME.NULL = FALSE;
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_fld_edit_string:
|
2001-05-23 15:26:42 +02:00
|
|
|
GET_STRING(ptr, RFR.RDB$EDIT_STRING);
|
|
|
|
RFR.RDB$EDIT_STRING.NULL = FALSE;
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_fld_position:
|
2001-05-23 15:26:42 +02:00
|
|
|
RFR.RDB$FIELD_POSITION = DYN_get_number(ptr);
|
|
|
|
RFR.RDB$FIELD_POSITION.NULL = FALSE;
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_view_context:
|
2001-05-23 15:26:42 +02:00
|
|
|
RFR.RDB$VIEW_CONTEXT = DYN_get_number(ptr);
|
|
|
|
RFR.RDB$VIEW_CONTEXT.NULL = FALSE;
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_system_flag:
|
2009-06-07 11:49:58 +02:00
|
|
|
RFR.RDB$SYSTEM_FLAG = FLD.RDB$SYSTEM_FLAG = DYN_get_number(ptr);
|
|
|
|
RFR.RDB$SYSTEM_FLAG.NULL = FLD.RDB$SYSTEM_FLAG.NULL = FALSE;
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_update_flag:
|
2001-05-23 15:26:42 +02:00
|
|
|
RFR.RDB$UPDATE_FLAG = DYN_get_number(ptr);
|
|
|
|
RFR.RDB$UPDATE_FLAG.NULL = FALSE;
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_fld_length:
|
2001-05-23 15:26:42 +02:00
|
|
|
FLD.RDB$FIELD_LENGTH = DYN_get_number(ptr);
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_fld_computed_blr:
|
2001-05-23 15:26:42 +02:00
|
|
|
FLD.RDB$COMPUTED_BLR.NULL = FALSE;
|
|
|
|
DYN_put_blr_blob(gbl, ptr, &FLD.RDB$COMPUTED_BLR);
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_fld_computed_source:
|
2001-05-23 15:26:42 +02:00
|
|
|
FLD.RDB$COMPUTED_SOURCE.NULL = FALSE;
|
|
|
|
DYN_put_text_blob(gbl, ptr, &FLD.RDB$COMPUTED_SOURCE);
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_fld_default_value:
|
2005-08-14 07:48:20 +02:00
|
|
|
if (has_dimensions)
|
|
|
|
{
|
2007-03-28 06:20:36 +02:00
|
|
|
DYN_error_punt(false, 225, sql_field_name.c_str());
|
2005-08-14 07:48:20 +02:00
|
|
|
// msg 225: "Default value is not allowed for array type in field %s"
|
|
|
|
}
|
|
|
|
has_default = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
RFR.RDB$DEFAULT_VALUE.NULL = FALSE;
|
|
|
|
DYN_put_blr_blob(gbl, ptr, &RFR.RDB$DEFAULT_VALUE);
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_fld_default_source:
|
2005-08-14 07:48:20 +02:00
|
|
|
if (has_dimensions)
|
|
|
|
{
|
2007-03-28 06:20:36 +02:00
|
|
|
DYN_error_punt(false, 225, sql_field_name.c_str());
|
2005-08-14 07:48:20 +02:00
|
|
|
// msg 225: "Default value is not allowed for array type in field %s"
|
|
|
|
}
|
|
|
|
has_default = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
RFR.RDB$DEFAULT_SOURCE.NULL = FALSE;
|
|
|
|
DYN_put_text_blob(gbl, ptr, &RFR.RDB$DEFAULT_SOURCE);
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_fld_validation_blr:
|
2001-05-23 15:26:42 +02:00
|
|
|
FLD.RDB$VALIDATION_BLR.NULL = FALSE;
|
|
|
|
DYN_put_blr_blob(gbl, ptr, &FLD.RDB$VALIDATION_BLR);
|
|
|
|
break;
|
|
|
|
|
2010-01-13 20:14:15 +01:00
|
|
|
case isc_dyn_fld_identity:
|
|
|
|
{
|
|
|
|
MetaName sequenceName;
|
|
|
|
DYN_UTIL_generate_generator_name(tdbb, sequenceName);
|
|
|
|
|
|
|
|
CreateSequenceNode::store(tdbb, gbl->gbl_transaction, sequenceName,
|
|
|
|
fb_sysflag_identity_generator);
|
|
|
|
|
|
|
|
strcpy(RFR.RDB$GENERATOR_NAME, sequenceName.c_str());
|
|
|
|
RFR.RDB$GENERATOR_NAME.NULL = FALSE;
|
|
|
|
|
|
|
|
RFR.RDB$IDENTITY_TYPE = IDENT_TYPE_BY_DEFAULT;
|
|
|
|
RFR.RDB$IDENTITY_TYPE.NULL = FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_fld_not_null:
|
2001-05-23 15:26:42 +02:00
|
|
|
RFR.RDB$NULL_FLAG.NULL = FALSE;
|
|
|
|
RFR.RDB$NULL_FLAG = TRUE;
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_fld_query_header:
|
2001-05-23 15:26:42 +02:00
|
|
|
DYN_put_blr_blob(gbl, ptr, &RFR.RDB$QUERY_HEADER);
|
|
|
|
RFR.RDB$QUERY_HEADER.NULL = FALSE;
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_fld_type:
|
2001-05-23 15:26:42 +02:00
|
|
|
FLD.RDB$FIELD_TYPE = dtype = DYN_get_number(ptr);
|
|
|
|
switch (dtype)
|
|
|
|
{
|
|
|
|
case blr_short:
|
|
|
|
FLD.RDB$FIELD_LENGTH = 2;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case blr_long:
|
|
|
|
case blr_float:
|
|
|
|
case blr_sql_date:
|
|
|
|
case blr_sql_time:
|
|
|
|
FLD.RDB$FIELD_LENGTH = 4;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case blr_int64:
|
|
|
|
case blr_quad:
|
|
|
|
case blr_timestamp:
|
|
|
|
case blr_double:
|
|
|
|
case blr_d_float:
|
|
|
|
FLD.RDB$FIELD_LENGTH = 8;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
if (dtype == blr_blob)
|
|
|
|
FLD.RDB$FIELD_LENGTH = 8;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_fld_scale:
|
2001-05-23 15:26:42 +02:00
|
|
|
FLD.RDB$FIELD_SCALE = DYN_get_number(ptr);
|
|
|
|
FLD.RDB$FIELD_SCALE.NULL = FALSE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case isc_dyn_fld_precision:
|
|
|
|
FLD.RDB$FIELD_PRECISION = DYN_get_number(ptr);
|
|
|
|
FLD.RDB$FIELD_PRECISION.NULL = FALSE;
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_fld_sub_type:
|
2001-05-23 15:26:42 +02:00
|
|
|
FLD.RDB$FIELD_SUB_TYPE = DYN_get_number(ptr);
|
|
|
|
FLD.RDB$FIELD_SUB_TYPE.NULL = FALSE;
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_fld_char_length:
|
2001-05-23 15:26:42 +02:00
|
|
|
FLD.RDB$CHARACTER_LENGTH = DYN_get_number(ptr);
|
|
|
|
FLD.RDB$CHARACTER_LENGTH.NULL = FALSE;
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_fld_character_set:
|
2001-05-23 15:26:42 +02:00
|
|
|
FLD.RDB$CHARACTER_SET_ID = DYN_get_number(ptr);
|
|
|
|
FLD.RDB$CHARACTER_SET_ID.NULL = FALSE;
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_fld_collation:
|
2009-11-21 08:38:05 +01:00
|
|
|
// Note: the global field's collation is not set, just
|
2009-11-22 01:09:30 +01:00
|
|
|
// the local field. There is no full "domain"
|
|
|
|
// created for the local field.
|
|
|
|
// This is the same decision for items like NULL_FLAG
|
2001-05-23 15:26:42 +02:00
|
|
|
RFR.RDB$COLLATION_ID = DYN_get_number(ptr);
|
|
|
|
RFR.RDB$COLLATION_ID.NULL = FALSE;
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_fld_dimensions:
|
2005-08-14 07:48:20 +02:00
|
|
|
if (has_default)
|
|
|
|
{
|
2007-03-28 06:20:36 +02:00
|
|
|
DYN_error_punt(false, 225, sql_field_name.c_str());
|
2005-08-14 07:48:20 +02:00
|
|
|
// msg 225: "Default value is not allowed for array type in field %s"
|
|
|
|
}
|
|
|
|
has_dimensions = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
FLD.RDB$DIMENSIONS = DYN_get_number(ptr);
|
|
|
|
FLD.RDB$DIMENSIONS.NULL = FALSE;
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_fld_segment_length:
|
2001-05-23 15:26:42 +02:00
|
|
|
FLD.RDB$SEGMENT_LENGTH = DYN_get_number(ptr);
|
|
|
|
FLD.RDB$SEGMENT_LENGTH.NULL = FALSE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
--(*ptr);
|
2010-01-24 16:16:23 +01:00
|
|
|
{
|
|
|
|
MetaNameProxy tmp(RFR.RDB$FIELD_SOURCE);
|
2005-05-12 20:28:04 +02:00
|
|
|
DYN_execute(gbl, ptr, relation_name, &tmp, NULL, NULL, NULL);
|
2010-01-24 16:16:23 +01:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
2010-01-13 20:14:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!RFR.RDB$GENERATOR_NAME.NULL)
|
|
|
|
{
|
|
|
|
bool exact = FLD.RDB$FIELD_TYPE == blr_short || FLD.RDB$FIELD_TYPE == blr_long ||
|
|
|
|
FLD.RDB$FIELD_TYPE == blr_int64;
|
|
|
|
|
|
|
|
if (!exact || FLD.RDB$FIELD_SCALE != 0)
|
|
|
|
{
|
|
|
|
// Identity column @1 of table @2 must be exact numeric with zero scale.
|
|
|
|
DYN_error_punt(false, 273,
|
|
|
|
SafeArg() << sql_field_name.c_str() << relation_name->c_str());
|
|
|
|
}
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-11-25 05:06:48 +01:00
|
|
|
if (RFR.RDB$FIELD_POSITION.NULL == TRUE)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
fld_pos = -1;
|
2005-05-17 09:17:25 +02:00
|
|
|
fb_assert(relation_name);
|
2009-01-03 10:14:29 +01:00
|
|
|
DYN_UTIL_generate_field_position(tdbb, gbl, *relation_name, &fld_pos);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-11-25 05:06:48 +01:00
|
|
|
if (fld_pos >= 0)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
RFR.RDB$FIELD_POSITION = ++fld_pos;
|
|
|
|
RFR.RDB$FIELD_POSITION.NULL = FALSE;
|
|
|
|
}
|
|
|
|
}
|
2010-04-18 03:10:05 +02:00
|
|
|
}
|
|
|
|
END_STORE
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
id = old_id;
|
2010-04-18 03:10:05 +02:00
|
|
|
}
|
|
|
|
END_STORE
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2001-12-24 03:51:06 +01:00
|
|
|
}
|
2009-11-25 05:06:48 +01:00
|
|
|
catch (const Firebird::Exception& ex)
|
|
|
|
{
|
2004-03-01 04:35:23 +01:00
|
|
|
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
|
2009-11-25 05:06:48 +01:00
|
|
|
if (id == drq_s_sql_lfld)
|
|
|
|
{
|
2007-03-28 06:20:36 +02:00
|
|
|
DYN_error_punt(true, 29);
|
2009-11-21 08:38:05 +01:00
|
|
|
// msg 29: "STORE RDB$RELATION_FIELDS failed"
|
2001-12-24 03:51:06 +01:00
|
|
|
}
|
2009-11-25 05:06:48 +01:00
|
|
|
else
|
|
|
|
{
|
2007-03-28 06:20:36 +02:00
|
|
|
DYN_error_punt(true, 28);
|
2009-11-21 08:38:05 +01:00
|
|
|
// msg 28: "STORE RDB$FIELDS failed"
|
2001-12-24 03:51:06 +01:00
|
|
|
}
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-03-31 19:38:53 +02:00
|
|
|
void DYN_define_shadow( Global* gbl, const UCHAR** ptr)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* D Y N _ d e f i n e _ s h a d o w
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Define a shadow.
|
|
|
|
*
|
|
|
|
**************************************/
|
2001-12-25 05:10:23 +01:00
|
|
|
|
2004-05-22 16:28:54 +02:00
|
|
|
thread_db* tdbb = JRD_get_thread_data();
|
2001-12-25 05:10:23 +01:00
|
|
|
|
|
|
|
bool found = false;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-11-05 10:02:33 +01:00
|
|
|
const SLONG shadow_number = DYN_get_number(ptr);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-11-21 08:38:05 +01:00
|
|
|
// If a shadow set identified by the shadow number already exists return error.
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2010-04-18 03:10:05 +02:00
|
|
|
AutoCacheRequest request(tdbb, drq_l_shadow, DYN_REQUESTS);
|
2001-12-24 03:51:06 +01:00
|
|
|
|
2010-04-18 03:10:05 +02:00
|
|
|
try
|
|
|
|
{
|
2001-12-24 03:51:06 +01:00
|
|
|
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
|
|
|
|
FIRST 1 X IN RDB$FILES WITH X.RDB$SHADOW_NUMBER EQ shadow_number
|
2010-04-18 03:10:05 +02:00
|
|
|
{
|
|
|
|
found = true;
|
2001-12-24 03:51:06 +01:00
|
|
|
}
|
2010-04-18 03:10:05 +02:00
|
|
|
END_FOR
|
2001-12-24 03:51:06 +01:00
|
|
|
}
|
2009-11-25 05:06:48 +01:00
|
|
|
catch (const Firebird::Exception& ex)
|
|
|
|
{
|
2004-03-01 04:35:23 +01:00
|
|
|
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
|
2007-03-28 06:20:36 +02:00
|
|
|
DYN_error_punt(true, 164);
|
2009-11-21 08:38:05 +01:00
|
|
|
// msg 164: "Shadow lookup failed"
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2009-11-25 05:06:48 +01:00
|
|
|
if (found)
|
|
|
|
{
|
2007-03-28 06:20:36 +02:00
|
|
|
DYN_error_punt(false, 165, SafeArg() << shadow_number);
|
2009-11-21 08:38:05 +01:00
|
|
|
// msg 165: "Shadow %ld already exists"
|
2001-12-24 03:51:06 +01:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2001-12-25 05:10:23 +01:00
|
|
|
SLONG start = 0;
|
2004-07-06 07:59:40 +02:00
|
|
|
UCHAR verb;
|
2003-11-08 17:40:17 +01:00
|
|
|
while ((verb = *(*ptr)++) != isc_dyn_end)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
switch (verb)
|
|
|
|
{
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_def_file:
|
2001-05-23 15:26:42 +02:00
|
|
|
DYN_define_file(gbl, ptr, shadow_number, &start, 157);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
DYN_unsupported_verb();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-10-21 02:42:38 +02:00
|
|
|
//// TODO: remove this function after rework on constraints and views triggers
|
2005-05-12 20:28:04 +02:00
|
|
|
void DYN_define_trigger(Global* gbl,
|
|
|
|
const UCHAR** ptr,
|
|
|
|
const Firebird::MetaName* relation_name,
|
|
|
|
Firebird::MetaName* trigger_name,
|
|
|
|
const bool ignore_perm)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* D Y N _ d e f i n e _ t r i g g e r
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Define a trigger for a relation.
|
|
|
|
*
|
|
|
|
*
|
2003-11-05 10:02:33 +01:00
|
|
|
* if the ignore_perm flag is true, then this trigger must be defined
|
2001-05-23 15:26:42 +02:00
|
|
|
* now (and fired at run time) without making SQL permissions checks.
|
|
|
|
* In particular, one should not need control permissions on the table
|
|
|
|
* to define this trigger. Currently used to define triggers for
|
|
|
|
* cascading referential interity.
|
2005-05-28 00:45:31 +02:00
|
|
|
*
|
2001-05-23 15:26:42 +02:00
|
|
|
**************************************/
|
|
|
|
|
2004-05-22 16:28:54 +02:00
|
|
|
thread_db* tdbb = JRD_get_thread_data();
|
2001-12-25 05:10:23 +01:00
|
|
|
|
2005-05-12 20:28:04 +02:00
|
|
|
Firebird::MetaName t;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2002-06-30 10:46:51 +02:00
|
|
|
GET_STRING(ptr, t);
|
2009-12-18 00:59:07 +01:00
|
|
|
if (t.isEmpty())
|
2010-07-26 04:37:57 +02:00
|
|
|
DYN_UTIL_generate_trigger_name(tdbb, gbl->gbl_transaction, t);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-12-17 02:36:33 +01:00
|
|
|
if (trigger_name)
|
2005-05-12 20:28:04 +02:00
|
|
|
*trigger_name = t;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2010-04-18 03:10:05 +02:00
|
|
|
AutoCacheRequest request(tdbb, drq_s_triggers, DYN_REQUESTS);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2001-12-25 05:10:23 +01:00
|
|
|
bool b_ending_store = false;
|
2006-10-30 21:58:06 +01:00
|
|
|
const UCHAR* debug_info_ptr = NULL;
|
2001-12-25 05:10:23 +01:00
|
|
|
|
|
|
|
try {
|
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
STORE(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
|
2005-05-28 00:45:31 +02:00
|
|
|
X IN RDB$TRIGGERS
|
2010-04-18 03:10:05 +02:00
|
|
|
{
|
2005-10-30 08:44:26 +01:00
|
|
|
X.RDB$TRIGGER_TYPE.NULL = TRUE;
|
2001-05-23 15:26:42 +02:00
|
|
|
X.RDB$TRIGGER_SEQUENCE = 0;
|
|
|
|
X.RDB$TRIGGER_SEQUENCE.NULL = FALSE;
|
|
|
|
X.RDB$TRIGGER_INACTIVE = 0;
|
|
|
|
X.RDB$TRIGGER_INACTIVE.NULL = FALSE;
|
2005-10-30 08:44:26 +01:00
|
|
|
X.RDB$SYSTEM_FLAG = 0;
|
|
|
|
X.RDB$SYSTEM_FLAG.NULL = FALSE;
|
2009-10-21 02:42:38 +02:00
|
|
|
// ODS_12_0
|
|
|
|
X.RDB$ENTRYPOINT.NULL = TRUE;
|
|
|
|
X.RDB$ENGINE_NAME.NULL = TRUE;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-11-21 08:38:05 +01:00
|
|
|
// Currently, we make no difference between ignoring permissions in
|
|
|
|
// order to define this trigger and ignoring permissions checks when the
|
|
|
|
// trigger fires. The RDB$FLAGS is used to indicate permissions checks
|
|
|
|
// when the trigger fires. Later, if we need to make a difference
|
|
|
|
// between these, then the caller should pass the required value
|
|
|
|
// of RDB$FLAGS as an extra argument to this func.
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
X.RDB$FLAGS = ignore_perm ? TRG_ignore_perm : 0;
|
|
|
|
X.RDB$FLAGS.NULL = FALSE;
|
2009-11-25 05:06:48 +01:00
|
|
|
if (relation_name)
|
|
|
|
{
|
2005-05-12 20:28:04 +02:00
|
|
|
strcpy(X.RDB$RELATION_NAME, relation_name->c_str());
|
2001-05-23 15:26:42 +02:00
|
|
|
X.RDB$RELATION_NAME.NULL = FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
X.RDB$RELATION_NAME.NULL = TRUE;
|
|
|
|
X.RDB$TRIGGER_BLR.NULL = TRUE;
|
|
|
|
X.RDB$TRIGGER_SOURCE.NULL = TRUE;
|
2005-05-12 20:28:04 +02:00
|
|
|
strcpy(X.RDB$TRIGGER_NAME, t.c_str());
|
2004-07-06 07:59:40 +02:00
|
|
|
|
|
|
|
UCHAR verb;
|
2003-11-08 17:40:17 +01:00
|
|
|
while ((verb = *(*ptr)++) != isc_dyn_end)
|
2001-12-25 05:10:23 +01:00
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
switch (verb)
|
|
|
|
{
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_trg_type:
|
2001-05-23 15:26:42 +02:00
|
|
|
X.RDB$TRIGGER_TYPE = DYN_get_number(ptr);
|
|
|
|
X.RDB$TRIGGER_TYPE.NULL = FALSE;
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_sql_object:
|
2001-05-23 15:26:42 +02:00
|
|
|
X.RDB$FLAGS |= TRG_sql;
|
2002-06-30 10:46:51 +02:00
|
|
|
X.RDB$FLAGS.NULL = FALSE;
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_trg_sequence:
|
2001-05-23 15:26:42 +02:00
|
|
|
X.RDB$TRIGGER_SEQUENCE = DYN_get_number(ptr);
|
2002-06-30 10:46:51 +02:00
|
|
|
X.RDB$TRIGGER_SEQUENCE.NULL = FALSE;
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_trg_inactive:
|
2001-05-23 15:26:42 +02:00
|
|
|
X.RDB$TRIGGER_INACTIVE = DYN_get_number(ptr);
|
2002-06-30 10:46:51 +02:00
|
|
|
X.RDB$TRIGGER_INACTIVE.NULL = FALSE;
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_rel_name:
|
2001-05-23 15:26:42 +02:00
|
|
|
GET_STRING(ptr, X.RDB$RELATION_NAME);
|
|
|
|
X.RDB$RELATION_NAME.NULL = FALSE;
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_trg_blr:
|
2003-11-05 10:02:33 +01:00
|
|
|
{
|
|
|
|
const UCHAR* blr = *ptr;
|
|
|
|
DYN_skip_attribute(ptr);
|
|
|
|
DYN_put_blr_blob(gbl, &blr, &X.RDB$TRIGGER_BLR);
|
|
|
|
X.RDB$TRIGGER_BLR.NULL = FALSE;
|
|
|
|
break;
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_trg_source:
|
2003-11-05 10:02:33 +01:00
|
|
|
{
|
|
|
|
const UCHAR* source = *ptr;
|
|
|
|
DYN_skip_attribute(ptr);
|
|
|
|
DYN_put_text_blob(gbl, &source, &X.RDB$TRIGGER_SOURCE);
|
|
|
|
X.RDB$TRIGGER_SOURCE.NULL = FALSE;
|
|
|
|
break;
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2005-10-30 08:44:26 +01:00
|
|
|
case isc_dyn_system_flag:
|
2002-06-30 10:46:51 +02:00
|
|
|
X.RDB$SYSTEM_FLAG = DYN_get_number(ptr);
|
|
|
|
X.RDB$SYSTEM_FLAG.NULL = FALSE;
|
2009-11-21 08:38:05 +01:00
|
|
|
// fb_assert(!ignore_perm || ignore_perm &&
|
|
|
|
// X.RDB$SYSTEM_FLAG == fb_sysflag_referential_constraint);
|
2002-06-30 10:46:51 +02:00
|
|
|
break;
|
|
|
|
|
2006-10-30 21:58:06 +01:00
|
|
|
case isc_dyn_debug_info:
|
|
|
|
debug_info_ptr = *ptr;
|
2008-09-05 11:32:51 +02:00
|
|
|
DYN_skip_attribute(ptr);
|
2006-10-30 21:58:06 +01:00
|
|
|
break;
|
|
|
|
|
2009-10-21 02:42:38 +02:00
|
|
|
case isc_dyn_func_entry_point:
|
|
|
|
// ODS_12_0
|
|
|
|
GET_STRING(ptr, X.RDB$ENTRYPOINT);
|
|
|
|
X.RDB$ENTRYPOINT.NULL = FALSE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case isc_dyn_def_engine:
|
|
|
|
// ODS_12_0
|
|
|
|
GET_STRING(ptr, X.RDB$ENGINE_NAME);
|
|
|
|
X.RDB$ENGINE_NAME.NULL = FALSE;
|
|
|
|
break;
|
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
default:
|
|
|
|
--(*ptr);
|
2010-01-24 16:16:23 +01:00
|
|
|
{
|
2010-01-26 09:34:13 +01:00
|
|
|
const MetaName tmp(X.RDB$RELATION_NAME);
|
2005-05-12 20:28:04 +02:00
|
|
|
DYN_execute(gbl, ptr, &tmp, NULL, &t, NULL, NULL);
|
2010-01-24 16:16:23 +01:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-12-03 16:46:39 +01:00
|
|
|
if (X.RDB$RELATION_NAME.NULL && !tdbb->getAttachment()->locksmith())
|
2008-08-27 14:20:47 +02:00
|
|
|
ERR_post(Arg::Gds(isc_adm_task_denied));
|
2006-11-05 19:30:36 +01:00
|
|
|
|
2009-11-27 07:57:17 +01:00
|
|
|
X.RDB$VALID_BLR = TRUE;
|
|
|
|
X.RDB$VALID_BLR.NULL = FALSE;
|
|
|
|
|
|
|
|
if (debug_info_ptr)
|
|
|
|
{
|
|
|
|
X.RDB$DEBUG_INFO.NULL = FALSE;
|
|
|
|
DYN_put_blr_blob(gbl, &debug_info_ptr, &X.RDB$DEBUG_INFO);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
X.RDB$DEBUG_INFO.NULL = TRUE;
|
|
|
|
|
2001-12-25 05:10:23 +01:00
|
|
|
b_ending_store = true;
|
|
|
|
|
2009-11-21 08:38:05 +01:00
|
|
|
// the END_STORE_SPECIAL adds the foll. lines of code to the END_STORE
|
|
|
|
// if (ignore_perm)
|
2010-04-19 00:19:11 +02:00
|
|
|
// request->getStatement()->flags |= JrdStatement::FLAG_IGNORE_PERM;
|
2009-11-21 08:38:05 +01:00
|
|
|
// after the request is compiled and before the request is sent.
|
|
|
|
// It makes the current request (to define the trigger) go through
|
|
|
|
// without checking any permissions lower in the engine
|
2010-04-18 03:10:05 +02:00
|
|
|
}
|
|
|
|
END_STORE_SPECIAL
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (ignore_perm)
|
2010-04-19 00:19:11 +02:00
|
|
|
request->getStatement()->flags &= ~JrdStatement::FLAG_IGNORE_PERM;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2001-12-25 05:10:23 +01:00
|
|
|
}
|
2009-11-25 05:06:48 +01:00
|
|
|
catch (const Firebird::Exception& ex)
|
|
|
|
{
|
2004-03-01 04:35:23 +01:00
|
|
|
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
|
2009-11-25 05:06:48 +01:00
|
|
|
if (b_ending_store)
|
|
|
|
{
|
2007-03-28 06:20:36 +02:00
|
|
|
DYN_error_punt(true, 31);
|
2009-11-21 08:38:05 +01:00
|
|
|
// msg 31: "DEFINE TRIGGER failed"
|
2001-12-25 05:10:23 +01:00
|
|
|
}
|
|
|
|
throw;
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-05-12 20:28:04 +02:00
|
|
|
void DYN_define_view_relation( Global* gbl, const UCHAR** ptr, const Firebird::MetaName* view)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* D Y N _ d e f i n e _ v i e w _ r e l a t i o n
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Store a RDB$VIEW_RELATION record.
|
|
|
|
*
|
|
|
|
**************************************/
|
2001-12-25 05:10:23 +01:00
|
|
|
|
2004-05-22 16:28:54 +02:00
|
|
|
thread_db* tdbb = JRD_get_thread_data();
|
2001-12-25 05:10:23 +01:00
|
|
|
|
2005-05-12 20:28:04 +02:00
|
|
|
fb_assert(view);
|
2002-06-30 10:46:51 +02:00
|
|
|
|
2010-04-18 03:10:05 +02:00
|
|
|
AutoCacheRequest request(tdbb, drq_s_view_rels, DYN_REQUESTS);
|
2004-07-06 07:59:40 +02:00
|
|
|
SSHORT id = drq_s_view_rels;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2001-12-25 05:10:23 +01:00
|
|
|
bool b_ending_store = false;
|
|
|
|
|
2009-12-17 01:38:55 +01:00
|
|
|
try
|
|
|
|
{
|
2001-12-25 05:10:23 +01:00
|
|
|
STORE(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
|
2005-05-28 00:45:31 +02:00
|
|
|
VRL IN RDB$VIEW_RELATIONS
|
2010-04-18 03:10:05 +02:00
|
|
|
{
|
2005-05-12 20:28:04 +02:00
|
|
|
strcpy(VRL.RDB$VIEW_NAME, view->c_str());
|
2001-12-25 05:10:23 +01:00
|
|
|
GET_STRING(ptr, VRL.RDB$RELATION_NAME);
|
|
|
|
VRL.RDB$CONTEXT_NAME.NULL = TRUE;
|
|
|
|
VRL.RDB$VIEW_CONTEXT.NULL = TRUE;
|
2009-12-15 15:08:28 +01:00
|
|
|
VRL.RDB$CONTEXT_TYPE.NULL = TRUE;
|
|
|
|
VRL.RDB$PACKAGE_NAME.NULL = TRUE;
|
2004-07-06 07:59:40 +02:00
|
|
|
|
|
|
|
UCHAR verb;
|
2003-11-08 17:40:17 +01:00
|
|
|
while ((verb = *(*ptr)++) != isc_dyn_end)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2001-12-25 05:10:23 +01:00
|
|
|
switch (verb)
|
|
|
|
{
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_view_context:
|
2001-12-25 05:10:23 +01:00
|
|
|
VRL.RDB$VIEW_CONTEXT = DYN_get_number(ptr);
|
|
|
|
VRL.RDB$VIEW_CONTEXT.NULL = FALSE;
|
|
|
|
break;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dyn_view_context_name:
|
2001-12-25 05:10:23 +01:00
|
|
|
GET_STRING(ptr, VRL.RDB$CONTEXT_NAME);
|
|
|
|
VRL.RDB$CONTEXT_NAME.NULL = FALSE;
|
|
|
|
break;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-12-15 15:08:28 +01:00
|
|
|
case isc_dyn_view_context_type:
|
|
|
|
VRL.RDB$CONTEXT_TYPE = DYN_get_number(ptr);
|
|
|
|
VRL.RDB$CONTEXT_TYPE.NULL = FALSE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case isc_dyn_pkg_name:
|
|
|
|
GET_STRING(ptr, VRL.RDB$PACKAGE_NAME);
|
|
|
|
VRL.RDB$PACKAGE_NAME.NULL = FALSE;
|
|
|
|
break;
|
|
|
|
|
2001-12-25 05:10:23 +01:00
|
|
|
default:
|
|
|
|
--(*ptr);
|
2010-01-24 16:16:23 +01:00
|
|
|
{
|
2010-01-26 09:34:13 +01:00
|
|
|
const MetaName tmp(VRL.RDB$RELATION_NAME);
|
2005-05-12 20:28:04 +02:00
|
|
|
DYN_execute(gbl, ptr, &tmp, NULL, NULL, NULL, NULL);
|
2010-01-24 16:16:23 +01:00
|
|
|
}
|
2001-12-25 05:10:23 +01:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2001-12-25 05:10:23 +01:00
|
|
|
b_ending_store = true;
|
|
|
|
}
|
2010-04-18 03:10:05 +02:00
|
|
|
END_STORE
|
2001-12-25 05:10:23 +01:00
|
|
|
}
|
2009-01-14 10:19:00 +01:00
|
|
|
catch (const Firebird::Exception& ex)
|
|
|
|
{
|
2004-03-01 04:35:23 +01:00
|
|
|
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
|
2009-11-25 05:06:48 +01:00
|
|
|
if (b_ending_store)
|
|
|
|
{
|
2002-08-11 10:04:54 +02:00
|
|
|
if (id == drq_s_view_rels)
|
|
|
|
{
|
2007-03-28 06:20:36 +02:00
|
|
|
DYN_error_punt(true, 34);
|
2009-11-21 08:38:05 +01:00
|
|
|
// msg 34: "STORE RDB$VIEW_RELATIONS failed"
|
2002-08-11 10:04:54 +02:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
2001-12-25 05:10:23 +01:00
|
|
|
throw;
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-05-12 20:28:04 +02:00
|
|
|
bool is_it_user_name(Global* gbl, const Firebird::MetaName& role_name, thread_db* tdbb)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* i s _ i t _ u s e r _ n a m e
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
*
|
2004-03-28 11:10:30 +02:00
|
|
|
* if role_name is user name returns true. Otherwise returns false.
|
2001-05-23 15:26:42 +02:00
|
|
|
*
|
|
|
|
**************************************/
|
2001-12-25 05:10:23 +01:00
|
|
|
|
2004-03-01 04:35:23 +01:00
|
|
|
USHORT request_id;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
SET_TDBB(tdbb);
|
2003-09-09 13:07:19 +02:00
|
|
|
bool found = false;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2001-12-24 03:51:06 +01:00
|
|
|
try {
|
|
|
|
|
2009-11-21 08:38:05 +01:00
|
|
|
// If there is a user with privilege or a grantor on a relation we
|
|
|
|
// can infer there is a user with this name
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2001-12-25 05:10:23 +01:00
|
|
|
request_id = drq_get_user_priv;
|
2010-04-18 03:10:05 +02:00
|
|
|
AutoCacheRequest request(tdbb, request_id, DYN_REQUESTS);
|
|
|
|
|
2001-12-25 05:10:23 +01:00
|
|
|
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
|
|
|
|
PRIV IN RDB$USER_PRIVILEGES WITH
|
2005-05-12 20:28:04 +02:00
|
|
|
(PRIV.RDB$USER EQ role_name.c_str() AND
|
2001-12-25 05:10:23 +01:00
|
|
|
PRIV.RDB$USER_TYPE = obj_user) OR
|
2005-05-12 20:28:04 +02:00
|
|
|
(PRIV.RDB$GRANTOR EQ role_name.c_str() AND
|
2001-12-25 05:10:23 +01:00
|
|
|
PRIV.RDB$OBJECT_TYPE = obj_relation)
|
2010-04-18 03:10:05 +02:00
|
|
|
{
|
2008-12-18 11:57:12 +01:00
|
|
|
found = true;
|
2010-04-18 03:10:05 +02:00
|
|
|
}
|
|
|
|
END_FOR
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2010-04-18 03:10:05 +02:00
|
|
|
if (found)
|
2001-12-25 05:10:23 +01:00
|
|
|
return found;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-11-21 08:38:05 +01:00
|
|
|
// We can infer that 'role_name' is a user name if it owns any relations
|
|
|
|
// Note we can only get here if a user creates a table and revokes all
|
|
|
|
// his privileges on the table
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2001-12-25 05:10:23 +01:00
|
|
|
request_id = drq_get_rel_owner;
|
2010-04-18 03:10:05 +02:00
|
|
|
request.reset(tdbb, request_id, DYN_REQUESTS);
|
|
|
|
|
2001-12-25 05:10:23 +01:00
|
|
|
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
|
|
|
|
REL IN RDB$RELATIONS WITH
|
2005-05-28 00:45:31 +02:00
|
|
|
REL.RDB$OWNER_NAME EQ role_name.c_str()
|
2010-04-18 03:10:05 +02:00
|
|
|
{
|
2003-09-09 13:07:19 +02:00
|
|
|
found = true;
|
2001-12-25 05:10:23 +01:00
|
|
|
}
|
2010-04-18 03:10:05 +02:00
|
|
|
END_FOR
|
2001-12-24 03:51:06 +01:00
|
|
|
}
|
2009-11-25 05:06:48 +01:00
|
|
|
catch (const Firebird::Exception& ex)
|
|
|
|
{
|
2004-03-01 04:35:23 +01:00
|
|
|
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
|
2001-12-24 03:51:06 +01:00
|
|
|
ERR_punt();
|
|
|
|
}
|
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
return found;
|
|
|
|
}
|