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>
|
|
|
|
|
2010-10-13 12:39:52 +02:00
|
|
|
#include "../common/common.h"
|
2001-05-23 15:26:42 +02:00
|
|
|
#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"
|
2010-10-13 12:39:52 +02:00
|
|
|
#include "../common/gdsassert.h"
|
2001-05-23 15:26:42 +02:00
|
|
|
#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"
|
2010-10-12 10:02:57 +02:00
|
|
|
#include "../yvalve/gds_proto.h"
|
2001-05-23 15:26:42 +02:00
|
|
|
#include "../jrd/inf_proto.h"
|
|
|
|
#include "../jrd/intl_proto.h"
|
2010-10-12 10:02:57 +02:00
|
|
|
#include "../common/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"
|
2010-10-13 12:39:52 +02:00
|
|
|
#include "../common/gdsassert.h"
|
2010-10-12 10:02:57 +02:00
|
|
|
#include "../common/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"
|
2010-10-12 10:02:57 +02:00
|
|
|
#include "../common/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
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-08-07 04:44:39 +02:00
|
|
|
void DYN_define_index(Global* gbl, const UCHAR** ptr, const Firebird::MetaName* relation_name)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* 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();
|
2010-08-07 04:44:39 +02:00
|
|
|
const UCHAR index_type = isc_dyn_def_idx;
|
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
|
|
|
|
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;
|
|
|
|
|
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
|
|
|
default:
|
|
|
|
DYN_unsupported_verb();
|
2006-10-02 04:39:45 +02:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2010-08-02 04:22:26 +02:00
|
|
|
CreateIndexNode::store(tdbb, gbl->gbl_transaction, index_name, definition);
|
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_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_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();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|