8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-22 16:43:03 +01:00

Feature #1113 - Add support for SQL Schemas. (WIP)

This commit is contained in:
Adriano dos Santos Fernandes 2025-01-12 15:10:41 -03:00
parent 855f25ac35
commit 73478271df
224 changed files with 16291 additions and 9722 deletions

View File

@ -11,15 +11,25 @@ database
#
# plugin =
# Pattern (regular expression) that defines what schemas must be included into
# replication. By default, tables from all schemas are replicated.
#
# include_schema_filter =
# Pattern (regular expression) that defines what schemas must be excluded from
# replication. By default, tables from all schemas are replicated.
#
# exclude_schema_filter =
# Pattern (regular expression) that defines what tables must be included into
# replication. By default, all tables are replicated.
#
# include_filter =
# include_filter =
# Pattern (regular expression) that defines what tables must be excluded from
# replication. By default, all tables are replicated.
#
# exclude_filter =
# exclude_filter =
# Boolean parameters describing how replication errors must be handled.
#
@ -42,20 +52,20 @@ database
# Directory to store replication journal files.
#
# journal_directory =
# journal_directory =
# Prefix for replication journal file names. It will be automatically suffixed
# with an ordinal sequential number. If not specified, database filename
# (without path) is used as a prefix.
#
# journal_file_prefix =
# journal_file_prefix =
# Maximum allowed size for a single replication segment.
#
# journal_segment_size = 16777216 # 16MB
# Maximum allowed number of full replication segments. Once this limit is reached,
# the replication process is temporarily delayed to allow the archiving to catch up.
# the replication process is temporarily delayed to allow the archiving to catch up.
# If any of the full segments is not archived during one minute,
# the replication fails with an error.
#
@ -76,7 +86,7 @@ database
# Directory to store archived replication segments.
# It also defines the $(archpathname) substitution macro (see below).
#
# journal_archive_directory =
# journal_archive_directory =
# Program (complete command line with arguments) that is executed when some
# replication segment gets full and needs archiving.
@ -97,7 +107,7 @@ database
# or
# Windows: "copy $(pathname) $(archivepathname)"
#
# journal_archive_command =
# journal_archive_command =
# Timeout, in seconds, to wait until incomplete segment is scheduled for archiving.
# It allows to minimize the replication gap if the database is modified rarely.
@ -121,7 +131,7 @@ database
#
# Multiple entries are allowed (for different synchronous replicas).
#
# sync_replica =
# sync_replica =
#
# It's also possible to configure replicas as separate sub-sections, e.g.:
#
@ -175,13 +185,13 @@ database
# Directory to search for the journal files to be replicated.
#
# journal_source_directory =
# journal_source_directory =
# Filter to limit replication to the particular source database (based on its GUID).
# Expected format: "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"
# Note that double quotes are mandatory, as well as curly braces.
#
# source_guid =
# source_guid =
# If enabled, replication.log contains the detailed log of operations performed
# by the replication server. Otherwise (by default), only errors and warnings are logged.
@ -202,6 +212,14 @@ database
# then reconnects back and tries to re-apply the latest segments from the point of failure.
#
# apply_error_timeout = 60
# Schema search path for compatibility with Firebird versions below 6.0
#
# Firebird master databases below v6 has no schemas, so use this search path in the replica to
# locate the objects.
# Used only with asynchronous replication.
#
# schema_search_path =
}
#

View File

@ -144,7 +144,7 @@
<ClInclude Include="..\..\..\src\common\classes\NoThrowTimeStamp.h" />
<ClInclude Include="..\..\..\src\common\classes\objects_array.h" />
<ClInclude Include="..\..\..\src\common\classes\ParsedList.h" />
<ClInclude Include="..\..\..\src\common\classes\QualifiedName.h" />
<ClInclude Include="..\..\..\src\common\classes\QualifiedMetaString.h" />
<ClInclude Include="..\..\..\src\common\classes\RefCounted.h" />
<ClInclude Include="..\..\..\src\common\classes\RefMutex.h" />
<ClInclude Include="..\..\..\src\common\classes\rwlock.h" />

View File

@ -449,7 +449,7 @@
<ClInclude Include="..\..\..\src\common\classes\objects_array.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\classes\QualifiedName.h">
<ClInclude Include="..\..\..\src\common\classes\MetaString.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\classes\RefCounted.h">

View File

@ -181,7 +181,11 @@
<ClCompile Include="..\..\..\src\common\tests\StringTest.cpp" />
<ClCompile Include="..\..\..\src\common\classes\tests\AlignerTest.cpp" />
<ClCompile Include="..\..\..\src\common\classes\tests\ArrayTest.cpp" />
<ClCompile Include="..\..\..\src\common\classes\tests\ClumpletTest.cpp" />
<ClCompile Include="..\..\..\src\common\classes\tests\DoublyLinkedListTest.cpp" />
<ClCompile Include="..\..\..\src\common\classes\tests\MetaStringTest.cpp" />
<ClCompile Include="..\..\..\src\common\classes\tests\QualifiedMetaStringTest.cpp" />
<ClCompile Include="..\..\..\src\common\classes\tests\VectorTest.cpp" />
<ClCompile Include="..\..\..\src\yvalve\gds.cpp" />
</ItemGroup>
<ItemGroup>
@ -197,4 +201,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>

View File

@ -30,11 +30,23 @@
<ClCompile Include="..\..\..\src\common\classes\tests\ArrayTest.cpp">
<Filter>source</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\common\classes\tests\ClumpletTest.cpp">
<Filter>source</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\common\classes\tests\DoublyLinkedListTest.cpp">
<Filter>source</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\common\classes\tests\MetaStringTest.cpp">
<Filter>source</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\common\classes\tests\QualifiedMetaStringTest.cpp">
<Filter>source</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\common\classes\tests\VectorTest.cpp">
<Filter>source</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\yvalve\gds.cpp">
<Filter>source</Filter>
</ClCompile>
</ItemGroup>
</Project>
</Project>

View File

@ -47,7 +47,8 @@ ALTER DATABASE EXCLUDE ALL FROM PUBLICATION
-- to disable replication of specific tables:
ALTER DATABASE EXCLUDE TABLE T1, T2, T3 FROM PUBLICATION
Tables enabled for replicated can be additionally filtered using two settings in the configuration file: include\_filter and exclude\_filter. They are regular expressions that are applied to table names and define rules for inclusion table\(s\) into the replication set or excluding them from the replication set.
Tables enabled for replicated can be additionally filtered using four settings in the configuration file: include\_schema\_filter, exclude\_schema\_filter, include\_filter and exclude\_filter.
They are regular expressions that are applied to schema and table names and define rules for inclusion table\(s\) into the replication set or excluding them from the replication set.
Synchronous replication can be turned on using the sync\_replica setting \(multiple entries are allowed\). It must specify a connection string to the replica database, prefixed with username/password. In SuperServer and SuperClassic architectures, replica database is being internally attached when the first user gets connected to the master database and detached when the last user disconnects from the master database. In Classic Server architecture, every server process keeps an active connection to the replica database.

View File

@ -119,6 +119,7 @@ DDL_TRIGGER context namespace:
- EVENT_TYPE: event type (CREATE, ALTER, DROP)
- OBJECT_TYPE: object type (TABLE, VIEW, etc)
- DDL_EVENT: event name (<ddl event item>), where <ddl_event_item> is EVENT_TYPE || ' ' || OBJECT_TYPE
- SCHEMA_NAME: object's schema name
- OBJECT_NAME: metadata object name
- OLD_OBJECT_NAME: metadata object name before a rename
- NEW_OBJECT_NAME: metadata object name after a rename
@ -294,51 +295,51 @@ commit;
select id, ddl_event, object_name, old_object_name, new_object_name, sql_text, ok from ddl_log order by id;
ID DDL_EVENT OBJECT_NAME OLD_OBJECT_NAME NEW_OBJECT_NAME SQL_TEXT OK
===================== ========================= =============================== =============================== =============================== ================= ======
2 CREATE TABLE T1 <null> <null> 80:0 Y
ID DDL_EVENT OBJECT_NAME OLD_OBJECT_NAME NEW_OBJECT_NAME SQL_TEXT OK
===================== ========================= =============================== =============================== =============================== ================= ======
2 CREATE TABLE T1 <null> <null> 80:0 Y
==============================================================================
SQL_TEXT:
SQL_TEXT:
recreate table t1 (
n1 integer,
n2 integer
)
==============================================================================
3 CREATE TABLE T1 <null> <null> 80:1 N
3 CREATE TABLE T1 <null> <null> 80:1 N
==============================================================================
SQL_TEXT:
SQL_TEXT:
create table t1 (
n1 integer,
n2 integer
)
==============================================================================
4 DROP TABLE T1 <null> <null> 80:2 Y
4 DROP TABLE T1 <null> <null> 80:2 Y
==============================================================================
SQL_TEXT:
SQL_TEXT:
recreate table t1 (
n integer
)
==============================================================================
5 CREATE TABLE T1 <null> <null> 80:3 Y
5 CREATE TABLE T1 <null> <null> 80:3 Y
==============================================================================
SQL_TEXT:
SQL_TEXT:
recreate table t1 (
n integer
)
==============================================================================
6 CREATE DOMAIN DOM1 <null> <null> 80:4 Y
6 CREATE DOMAIN DOM1 <null> <null> 80:4 Y
==============================================================================
SQL_TEXT:
SQL_TEXT:
create domain dom1 as integer
==============================================================================
7 ALTER DOMAIN DOM1 <null> <null> 80:5 Y
7 ALTER DOMAIN DOM1 <null> <null> 80:5 Y
==============================================================================
SQL_TEXT:
SQL_TEXT:
alter domain dom1 type bigint
==============================================================================
8 ALTER DOMAIN DOM1 DOM1 DOM2 80:6 Y
8 ALTER DOMAIN DOM1 DOM1 DOM2 80:6 Y
==============================================================================
SQL_TEXT:
SQL_TEXT:
alter domain dom1 to dom2
==============================================================================

View File

@ -109,6 +109,8 @@ execute procedure rdb$profiler.finish_session(true);
-- Data analysis
set search_path to plg$profiler, public, system;
set transaction read committed;
select * from plg$prof_sessions;
@ -243,7 +245,9 @@ Input parameters:
# Snapshot tables
Snapshot tables (as well views and sequence) are automatically created in the first usage of the profiler. They are owned by the database owner, with read/write permissions for `PUBLIC`.
The profiler schema, snapshot tables, views and sequence are automatically created in the first usage of the profiler.
They are owned by the database owner, with usage/read/write permissions for the RDB$PROFILER role, granted by default to `PUBLIC`.
When a session is deleted, the related data in other profiler snapshot tables are automatically deleted too through foreign keys with `DELETE CASCADE` option.

View File

@ -17,6 +17,7 @@ Output parameters:
- `RECORD_SOURCE_ID` type `BIGINT NOT NULL` - record source id
- `PARENT_RECORD_SOURCE_ID` type `BIGINT` - parent record source id
- `LEVEL` type `INTEGER NOT NULL` - indentation level (may have gaps in relation to parent's level)
- `SCHEMA_NAME` type `RDB$SCHEMA_NAME` - schema name of a stored procedure
- `PACKAGE_NAME` type `RDB$PACKAGE_NAME` - package name of a stored procedure
- `OBJECT_NAME` type `RDB$RELATION_NAME` - object (table, procedure) name
- `ALIAS` type `RDB$SHORT_DESCRIPTION` - alias name

View File

@ -35,7 +35,8 @@ public:
void setAttachment(IAttachment* attachment) override;
IReplicatedTransaction* startTransaction(ITransaction* transaction, ISC_INT64 number) override;
FB_BOOLEAN cleanupTransaction(ISC_INT64 number) override;
FB_BOOLEAN setSequence(const char* name, ISC_INT64 value) override;
FB_BOOLEAN deprecatedSetSequence(const char* name, ISC_INT64 value) override;
FB_BOOLEAN setSequence2(const char* schemaName, const char* genName, ISC_INT64 value) override;
private:
friend class ReplTransaction;
@ -64,11 +65,17 @@ public:
FB_BOOLEAN startSavepoint() override;
FB_BOOLEAN releaseSavepoint() override;
FB_BOOLEAN rollbackSavepoint() override;
FB_BOOLEAN insertRecord(const char* name, IReplicatedRecord* record) override;
FB_BOOLEAN updateRecord(const char* name, IReplicatedRecord* orgRecord, IReplicatedRecord* newRecord) override;
FB_BOOLEAN deleteRecord(const char* name, IReplicatedRecord* record) override;
FB_BOOLEAN executeSql(const char* sql) override;
FB_BOOLEAN executeSqlIntl(unsigned charset, const char* sql) override;
FB_BOOLEAN deprecatedInsertRecord(const char* name, IReplicatedRecord* record) override;
FB_BOOLEAN insertRecord2(const char* schemaName, const char* tableName, IReplicatedRecord* record) override;
FB_BOOLEAN deprecatedUpdateRecord(const char* name,
IReplicatedRecord* orgRecord, IReplicatedRecord* newRecord) override;
FB_BOOLEAN updateRecord2(const char* schemaName, const char* tableName,
IReplicatedRecord* orgRecord, IReplicatedRecord* newRecord) override;
FB_BOOLEAN deprecatedDeleteRecord(const char* name, IReplicatedRecord* record) override;
FB_BOOLEAN deleteRecord2(const char* schemaName, const char* tableName, IReplicatedRecord* record) override;
FB_BOOLEAN deprecatedExecuteSql(const char* sql) override;
FB_BOOLEAN deprecatedExecuteSqlIntl(unsigned charset, const char* sql) override;
FB_BOOLEAN executeSqlIntl2(unsigned charset, const char* schemaSearchPath, const char* sql) override;
private:
ReplPlugin* parent;
@ -245,9 +252,15 @@ FB_BOOLEAN ReplPlugin::cleanupTransaction(ISC_INT64 number)
return FB_TRUE;
}
FB_BOOLEAN ReplPlugin::setSequence(const char* name, ISC_INT64 value)
FB_BOOLEAN ReplPlugin::deprecatedSetSequence(const char* name, ISC_INT64 value)
{
WriteLog(log, "%p\tsetSequence(%s, %lld)\n", this, name, value);
WriteLog(log, "%p\tdeprecatedSetSequence(%s, %lld)\n", this, name, value);
return FB_TRUE;
}
FB_BOOLEAN ReplPlugin::setSequence2(const char* schemaName, const char* genName, ISC_INT64 value)
{
WriteLog(log, "%p\tsetSequence2(%s.%s, %lld)\n", this, schemaName, genName, value);
return FB_TRUE;
}
@ -506,9 +519,9 @@ bool ReplTransaction::dumpData(IReplicatedRecord* record)
return true;
}
FB_BOOLEAN ReplTransaction::insertRecord(const char* name, IReplicatedRecord* record)
FB_BOOLEAN ReplTransaction::deprecatedInsertRecord(const char* name, IReplicatedRecord* record)
{
WriteLog(parent->log, "%p\tInsert record into %s\n", this, name);
WriteLog(parent->log, "%p\tdeprecated Insert record into %s\n", this, name);
try
{
return dumpData(record) ? FB_TRUE : FB_FALSE;
@ -520,9 +533,24 @@ FB_BOOLEAN ReplTransaction::insertRecord(const char* name, IReplicatedRecord* re
}
}
FB_BOOLEAN ReplTransaction::updateRecord(const char* name, IReplicatedRecord* orgRecord, IReplicatedRecord* newRecord)
FB_BOOLEAN ReplTransaction::insertRecord2(const char* schemaName, const char* tableName, IReplicatedRecord* record)
{
WriteLog(parent->log, "%p\tUpdate %s\nOldData:\n", this, name);
WriteLog(parent->log, "%p\tInsert record into %s.%s\n", this, schemaName, tableName);
try
{
return dumpData(record) ? FB_TRUE : FB_FALSE;
}
catch (const int)
{
parent->status->setErrors(err);
return FB_FALSE;
}
}
FB_BOOLEAN ReplTransaction::deprecatedUpdateRecord(const char* name,
IReplicatedRecord* orgRecord, IReplicatedRecord* newRecord)
{
WriteLog(parent->log, "%p\tdeprecated Update %s\nOldData:\n", this, name);
try
{
if (!dumpData(orgRecord))
@ -538,9 +566,28 @@ FB_BOOLEAN ReplTransaction::updateRecord(const char* name, IReplicatedRecord* or
}
}
FB_BOOLEAN ReplTransaction::deleteRecord(const char* name, IReplicatedRecord* record)
FB_BOOLEAN ReplTransaction::updateRecord2(const char* schemaName, const char* tableName,
IReplicatedRecord* orgRecord, IReplicatedRecord* newRecord)
{
WriteLog(parent->log, "%p\tDelete from %s\n", this, name);
WriteLog(parent->log, "%p\tUpdate %s.%s\nOldData:\n", this, schemaName, tableName);
try
{
if (!dumpData(orgRecord))
return FB_FALSE;
WriteLog(parent->log, "NewData:\n");
return dumpData(newRecord) ? FB_TRUE : FB_FALSE;
}
catch (const int)
{
parent->status->setErrors(err);
return FB_FALSE;
}
}
FB_BOOLEAN ReplTransaction::deprecatedDeleteRecord(const char* name, IReplicatedRecord* record)
{
WriteLog(parent->log, "%p\tdeprecated Delete from %s\n", this, name);
try
{
return dumpData(record) ? FB_TRUE : FB_FALSE;
@ -552,14 +599,34 @@ FB_BOOLEAN ReplTransaction::deleteRecord(const char* name, IReplicatedRecord* re
}
}
FB_BOOLEAN ReplTransaction::executeSql(const char* sql)
FB_BOOLEAN ReplTransaction::deleteRecord2(const char* schemaName, const char* tableName, IReplicatedRecord* record)
{
WriteLog(parent->log, "%p\tExecuteSql(%s)\n", this, sql);
WriteLog(parent->log, "%p\tDelete from %s.%s\n", this, schemaName, tableName);
try
{
return dumpData(record) ? FB_TRUE : FB_FALSE;
}
catch (const int)
{
parent->status->setErrors(err);
return FB_FALSE;
}
}
FB_BOOLEAN ReplTransaction::deprecatedExecuteSql(const char* sql)
{
WriteLog(parent->log, "%p\tdeprecatedExecuteSql(%s)\n", this, sql);
return FB_TRUE;
}
FB_BOOLEAN ReplTransaction::executeSqlIntl(unsigned charset, const char* sql)
FB_BOOLEAN ReplTransaction::deprecatedExecuteSqlIntl(unsigned charset, const char* sql)
{
WriteLog(parent->log, "%p\tExecuteSqlIntl(%u, %s)\n", this, charset, sql);
WriteLog(parent->log, "%p\tdeprecatedExecuteSqlIntl(%u, %s)\n", this, charset, sql);
return FB_TRUE;
}
FB_BOOLEAN ReplTransaction::executeSqlIntl2(unsigned charset, const char* schemaSearchPath, const char* sql)
{
WriteLog(parent->log, "%p\tExecuteSqlIntl2(%u, %s, %s)\n", this, charset, schemaSearchPath, sql);
return FB_TRUE;
}

View File

@ -202,6 +202,7 @@ static void buildDpb(Firebird::ClumpletWriter& dpb, const SINT64 switches)
dpb.reset(isc_dpb_version1);
dpb.insertTag(isc_dpb_gfix_attach);
tdgbl->uSvc->fillDpb(dpb);
dpb.insertString(isc_dpb_search_path, SYSTEM_SCHEMA, fb_strlen(SYSTEM_SCHEMA));
if (switches & sw_sweep) {
dpb.insertByte(isc_dpb_sweep, isc_dpb_records);

View File

@ -68,28 +68,28 @@ private:
void prepareDataStructures()
{
const char* script[] = {
"CREATE TABLE PLG$SRP (PLG$USER_NAME SEC$USER_NAME NOT NULL PRIMARY KEY, "
"CREATE TABLE PUBLIC.PLG$SRP (PLG$USER_NAME SYSTEM.SEC$USER_NAME NOT NULL PRIMARY KEY, "
"PLG$VERIFIER VARCHAR(128) CHARACTER SET OCTETS NOT NULL, "
"PLG$SALT VARCHAR(32) CHARACTER SET OCTETS NOT NULL, "
"PLG$COMMENT RDB$DESCRIPTION, PLG$FIRST SEC$NAME_PART, "
"PLG$MIDDLE SEC$NAME_PART, PLG$LAST SEC$NAME_PART, "
"PLG$ATTRIBUTES RDB$DESCRIPTION, "
"PLG$COMMENT SYSTEM.RDB$DESCRIPTION, PLG$FIRST SYSTEM.SEC$NAME_PART, "
"PLG$MIDDLE SYSTEM.SEC$NAME_PART, PLG$LAST SYSTEM.SEC$NAME_PART, "
"PLG$ATTRIBUTES SYSTEM.RDB$DESCRIPTION, "
"PLG$ACTIVE BOOLEAN)"
,
"CREATE VIEW PLG$SRP_VIEW AS "
"CREATE VIEW PUBLIC.PLG$SRP_VIEW AS "
"SELECT PLG$USER_NAME, PLG$VERIFIER, PLG$SALT, PLG$COMMENT, "
" PLG$FIRST, PLG$MIDDLE, PLG$LAST, PLG$ATTRIBUTES, PLG$ACTIVE "
"FROM PLG$SRP WHERE RDB$SYSTEM_PRIVILEGE(USER_MANAGEMENT) "
"FROM PUBLIC.PLG$SRP WHERE RDB$SYSTEM_PRIVILEGE(USER_MANAGEMENT) "
" OR CURRENT_USER = PLG$SRP.PLG$USER_NAME"
,
"GRANT ALL ON PLG$SRP TO VIEW PLG$SRP_VIEW"
"GRANT ALL ON PUBLIC.PLG$SRP TO VIEW PUBLIC.PLG$SRP_VIEW"
,
"GRANT SELECT ON PLG$SRP_VIEW TO PUBLIC"
"GRANT SELECT ON PUBLIC.PLG$SRP_VIEW TO PUBLIC"
,
"GRANT UPDATE(PLG$VERIFIER, PLG$SALT, PLG$FIRST, PLG$MIDDLE, PLG$LAST, "
" PLG$COMMENT, PLG$ATTRIBUTES) ON PLG$SRP_VIEW TO PUBLIC"
" PLG$COMMENT, PLG$ATTRIBUTES) ON PUBLIC.PLG$SRP_VIEW TO PUBLIC"
,
"GRANT ALL ON PLG$SRP_VIEW TO SYSTEM PRIVILEGE USER_MANAGEMENT"
"GRANT ALL ON PUBLIC.PLG$SRP_VIEW TO SYSTEM PRIVILEGE USER_MANAGEMENT"
,
NULL
};
@ -160,7 +160,7 @@ private:
Firebird::string userName2(user->userName()->get());
prepareName(userName2, '\'');
Firebird::string selGrantor;
selGrantor.printf("SELECT RDB$GRANTOR FROM RDB$USER_PRIVILEGES "
selGrantor.printf("SELECT RDB$GRANTOR FROM SYSTEM.RDB$USER_PRIVILEGES "
"WHERE RDB$USER = '%s' AND RDB$RELATION_NAME = '%s' AND RDB$PRIVILEGE = 'M'",
userName2.c_str(), ADMIN_ROLE);
Message out;
@ -353,7 +353,7 @@ public:
case Firebird::IUser::OP_USER_ADD:
{
const char* insert =
"INSERT INTO plg$srp_view(PLG$USER_NAME, PLG$VERIFIER, PLG$SALT, PLG$FIRST, PLG$MIDDLE, PLG$LAST,"
"INSERT INTO public.plg$srp_view(PLG$USER_NAME, PLG$VERIFIER, PLG$SALT, PLG$FIRST, PLG$MIDDLE, PLG$LAST,"
"PLG$COMMENT, PLG$ATTRIBUTES, PLG$ACTIVE) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)";
Firebird::IStatement* stmt = NULL;
@ -455,7 +455,7 @@ public:
case Firebird::IUser::OP_USER_MODIFY:
{
Firebird::string update = "UPDATE plg$srp_view SET ";
Firebird::string update = "UPDATE public.plg$srp_view SET ";
Firebird::AutoPtr<Varfield> verifier, slt;
if (user->password()->entered())
@ -558,7 +558,7 @@ public:
case Firebird::IUser::OP_USER_DELETE:
{
const char* del = "DELETE FROM plg$srp_view WHERE PLG$USER_NAME=?";
const char* del = "DELETE FROM public.plg$srp_view WHERE PLG$USER_NAME=?";
Firebird::IStatement* stmt = NULL;
try
{
@ -601,11 +601,11 @@ public:
case Firebird::IUser::OP_USER_DISPLAY:
{
Firebird::string disp =
"WITH ADMINS AS (SELECT RDB$USER FROM RDB$USER_PRIVILEGES "
"WITH ADMINS AS (SELECT RDB$USER FROM SYSTEM.RDB$USER_PRIVILEGES "
" WHERE RDB$RELATION_NAME = 'RDB$ADMIN' AND RDB$PRIVILEGE = 'M' GROUP BY RDB$USER) "
"SELECT PLG$USER_NAME, PLG$FIRST, PLG$MIDDLE, PLG$LAST, PLG$COMMENT, PLG$ATTRIBUTES, "
" CASE WHEN RDB$USER IS NULL THEN FALSE ELSE TRUE END, PLG$ACTIVE "
"FROM PLG$SRP_VIEW LEFT JOIN ADMINS "
"FROM SYSTEM.PLG$SRP_VIEW LEFT JOIN ADMINS "
" ON PLG$SRP_VIEW.PLG$USER_NAME = ADMINS.RDB$USER ";
if (user->userName()->entered())
{

View File

@ -196,7 +196,7 @@ public:
HANDSHAKE_DEBUG(fprintf(stderr, "Srv: SRP1: started transaction\n"));
const char* sql =
"SELECT PLG$VERIFIER, PLG$SALT FROM PLG$SRP WHERE PLG$USER_NAME = ? AND PLG$ACTIVE";
"SELECT PLG$VERIFIER, PLG$SALT FROM PUBLIC.PLG$SRP WHERE PLG$USER_NAME = ? AND PLG$ACTIVE";
stmt = att->prepare(&status, tra, 0, sql, 3, IStatement::PREPARE_PREFETCH_METADATA);
if (status->getState() & IStatus::STATE_ERRORS)
{

View File

@ -129,6 +129,7 @@ void SecurityDatabaseManagement::start(Firebird::CheckStatusWrapper* st, Firebir
Firebird::ClumpletWriter dpb(Firebird::ClumpletReader::dpbList, MAX_DPB_SIZE);
dpb.insertByte(isc_dpb_sec_attach, TRUE);
dpb.insertString(isc_dpb_config, Firebird::ParsedList::getNonLoopbackProviders(secDbName));
dpb.insertString(isc_dpb_search_path, SYSTEM_SCHEMA, fb_strlen(SYSTEM_SCHEMA)); // FIXME: plugin schema
unsigned int authBlockSize;
const unsigned char* authBlock = logonInfo->authBlock(&authBlockSize);
@ -343,6 +344,7 @@ int SecurityDatabaseManagement::execute(Firebird::CheckStatusWrapper* st, Firebi
// this checks the "entered" flags for each parameter (except the name)
// and makes all non-entered parameters null valued
// FIXME: epp queries outside engine has not exclusive schema search path set to SYSTEM
STORE (TRANSACTION_HANDLE transaction REQUEST_HANDLE request) U IN PLG$VIEW_USERS USING
STR_STORE(U.PLG$USER_NAME, user->userName()->get());

View File

@ -64,7 +64,11 @@ const UCHAR PWD_REQUEST[] =
blr_begin,
blr_for,
blr_rse, 1,
blr_relation, 9, 'P', 'L', 'G', '$', 'U', 'S', 'E', 'R', 'S', 0,
blr_relation3,
6, 'P', 'U', 'B', 'L', 'I', 'C', // PUBLIC_SCHEMA // FIXME:
9, 'P', 'L', 'G', '$', 'U', 'S', 'E', 'R', 'S',
0,
0,
blr_first,
blr_literal, blr_short, 0, 1, 0,
blr_boolean,

View File

@ -561,7 +561,7 @@ bool BackupRelationTask::fileWriter(Item& item)
BurpGlobals* tdgbl = item.m_gbl;
fb_assert(tdgbl == m_masterGbl);
BURP_verbose(142, m_relation->rel_name);
BURP_verbose(142, m_relation->rel_name.toQuotedString().c_str());
// msg 142 writing data for relation %s
IOBuffer*& buf = item.m_buffer = NULL;

View File

@ -45,6 +45,7 @@ namespace
{"RDB$ROLES", 0, DB_VERSION_DDL9}, // IB5
{"RDB$PACKAGES", 0, DB_VERSION_DDL12}, // FB3
{"RDB$PUBLICATIONS", 0, DB_VERSION_DDL13}, // FB4
{"RDB$SCHEMAS", 0, DB_VERSION_DDL14}, // FB6
{0, 0, 0}
};
@ -102,13 +103,16 @@ void detectRuntimeODS()
Firebird::IRequest* req_handle = nullptr;
FOR (REQUEST_HANDLE req_handle)
RFR IN RDB$RELATION_FIELDS
WITH (RFR.RDB$RELATION_NAME = 'RDB$RELATIONS' OR RFR.RDB$RELATION_NAME = 'RDB$RELATION_FIELDS')
AND RFR.RDB$FIELD_NAME = 'RDB$SYSTEM_FLAG'
WITH (RFR.RDB$RELATION_NAME = 'RDB$RELATIONS' OR RFR.RDB$RELATION_NAME = 'RDB$RELATION_FIELDS') AND
RFR.RDB$FIELD_NAME = 'RDB$SYSTEM_FLAG' AND
(RFR.RDB$SCHEMA_NAME MISSING OR RFR.RDB$SCHEMA_NAME = SYSTEM_SCHEMA)
{
++count;
END_FOR;
}
END_FOR
ON_ERROR
general_on_error();
END_ERROR;
END_ERROR
MISC_release_request_silent(req_handle);
if (count != 2)
@ -119,14 +123,17 @@ void detectRuntimeODS()
{
FOR (REQUEST_HANDLE req_handle2)
FIRST 1 X IN RDB$RELATIONS
WITH X.RDB$RELATION_NAME = rel->relation
AND X.RDB$SYSTEM_FLAG = 1
WITH X.RDB$RELATION_NAME = rel->relation AND
X.RDB$SYSTEM_FLAG = 1 AND
(X.RDB$SCHEMA_NAME MISSING OR X.RDB$SCHEMA_NAME = SYSTEM_SCHEMA)
{
if (tdgbl->runtimeODS < rel->ods_version)
tdgbl->runtimeODS = rel->ods_version;
END_FOR;
}
END_FOR
ON_ERROR
general_on_error();
END_ERROR;
END_ERROR
}
MISC_release_request_silent(req_handle2);
@ -138,15 +145,18 @@ void detectRuntimeODS()
{
FOR (REQUEST_HANDLE req_handle3)
FIRST 1 X2 IN RDB$RELATION_FIELDS
WITH X2.RDB$RELATION_NAME = rf->relation
AND X2.RDB$FIELD_NAME = rf->field
AND X2.RDB$SYSTEM_FLAG = 1
WITH X2.RDB$RELATION_NAME = rf->relation AND
X2.RDB$FIELD_NAME = rf->field AND
X2.RDB$SYSTEM_FLAG = 1 AND
(X2.RDB$SCHEMA_NAME MISSING OR X2.RDB$SCHEMA_NAME = SYSTEM_SCHEMA)
{
if (tdgbl->runtimeODS < rf->ods_version)
tdgbl->runtimeODS = rf->ods_version;
END_FOR;
}
END_FOR
ON_ERROR
general_on_error();
END_ERROR;
END_ERROR
}
MISC_release_request_silent(req_handle3);
}

View File

@ -69,6 +69,7 @@ const int DB_VERSION_DDL11_2 = 112; // ods11.2 db, FB2.5
const int DB_VERSION_DDL12 = 120; // ods12.0 db, FB3.0
const int DB_VERSION_DDL13 = 130; // ods13.0 db, FB4.0
const int DB_VERSION_DDL13_1 = 131; // ods13.1 db, FB5.0
const int DB_VERSION_DDL14 = 140; // ods14 db, FB6.0
const int DB_VERSION_OLDEST_SUPPORTED = DB_VERSION_DDL8; // IB4.0 is ods8

File diff suppressed because it is too large Load Diff

View File

@ -765,13 +765,35 @@ int gbak(Firebird::UtilSvc* uSvc)
}
tdgbl->gbl_sw_user = argv[itr];
break;
case IN_SW_BURP_SKIP_SCHEMA_DATA:
if (++itr >= argc)
{
BURP_error(417, true);
// missing regular expression to skip tables
}
tdgbl->setupSkipIncludePattern(argv[itr], 419, tdgbl->skipSchemaDataMatcher);
// msg 419 regular expression to skip schemas was already set
break;
case IN_SW_BURP_SKIP_DATA:
if (++itr >= argc)
{
BURP_error(354, true);
// missing regular expression to skip tables
}
tdgbl->setupSkipData(argv[itr]);
tdgbl->setupSkipIncludePattern(argv[itr], 356, tdgbl->skipDataMatcher);
// msg 356 regular expression to skip tables was already set
break;
case IN_SW_BURP_INCLUDE_SCHEMA_DATA:
if (++itr >= argc)
{
BURP_error(418, true);
// missing regular expression to include tables
}
tdgbl->setupSkipIncludePattern(argv[itr], 420, tdgbl->includeSchemaDataMatcher);
// msg 420 regular expression to include schemas was already set
break;
case IN_SW_BURP_INCLUDE_DATA:
if (++itr >= argc)
@ -779,7 +801,9 @@ int gbak(Firebird::UtilSvc* uSvc)
BURP_error(389, true);
// missing regular expression to include tables
}
tdgbl->setupIncludeData(argv[itr]);
tdgbl->setupSkipIncludePattern(argv[itr], 390, tdgbl->includeDataMatcher);
// msg 390 regular expression to include tables was already set
break;
case IN_SW_BURP_ROLE:
if (++itr >= argc)
@ -1153,6 +1177,8 @@ int gbak(Firebird::UtilSvc* uSvc)
dpb.insertBytes(isc_dpb_auth_block, authBlock, authSize);
}
dpb.insertString(isc_dpb_search_path, SYSTEM_SCHEMA, fb_strlen(SYSTEM_SCHEMA));
// We call getTableMod() because we are interested in the items that were activated previously,
// not in the original, unchanged table that "switches" took as parameter in the constructor.
for (const Switches::in_sw_tab_t* in_sw_tab = switches.getTableMod();
@ -2664,59 +2690,25 @@ void close_platf(DESC file)
#endif // WIN_NT
void BurpGlobals::setupSkipData(const Firebird::string& regexp)
void BurpGlobals::setupSkipIncludePattern(const string& regexp, USHORT alreadySetErrorCode,
AutoPtr<SimilarToRegex>& matcher)
{
if (skipDataMatcher)
{
BURP_error(356, true);
// msg 356 regular expression to skip tables was already set
}
if (matcher)
BURP_error(alreadySetErrorCode, true);
// Compile skip relation expressions
// Compile expressions
try
{
if (regexp.hasData())
{
Firebird::string filter(regexp);
string filter(regexp);
if (!uSvc->utf8FileNames())
ISC_systemToUtf8(filter);
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
skipDataMatcher.reset(FB_NEW_POOL(tdgbl->getPool()) Firebird::SimilarToRegex(
tdgbl->getPool(), Firebird::SimilarToFlag::CASE_INSENSITIVE,
filter.c_str(), filter.length(),
"\\", 1));
}
}
catch (const Firebird::Exception&)
{
Firebird::fatal_exception::raiseFmt(
"error while compiling regular expression \"%s\"", regexp.c_str());
}
}
void BurpGlobals::setupIncludeData(const Firebird::string& regexp)
{
if (includeDataMatcher)
{
BURP_error(390, true);
// msg 390 regular expression to include tables was already set
}
// Compile include relation expressions
try
{
if (regexp.hasData())
{
Firebird::string filter(regexp);
if (!uSvc->utf8FileNames())
ISC_systemToUtf8(filter);
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
includeDataMatcher.reset(FB_NEW_POOL(tdgbl->getPool()) Firebird::SimilarToRegex(
tdgbl->getPool(), Firebird::SimilarToFlag::CASE_INSENSITIVE,
matcher.reset(FB_NEW_POOL(tdgbl->getPool()) SimilarToRegex(
tdgbl->getPool(), SimilarToFlag::CASE_INSENSITIVE,
filter.c_str(), filter.length(),
"\\", 1));
}
@ -2750,7 +2742,7 @@ namespace // for local symbols
}
}
bool BurpGlobals::skipRelation(const char* name)
bool BurpGlobals::skipRelation(const QualifiedMetaString& name)
{
if (gbl_sw_meta)
return true;
@ -2764,10 +2756,12 @@ bool BurpGlobals::skipRelation(const char* name)
{ false, false, true} // NM p
};
const enum Pattern res1 = checkPattern(skipDataMatcher, name);
const enum Pattern res2 = checkPattern(includeDataMatcher, name);
const enum Pattern res1sch = checkPattern(skipSchemaDataMatcher, name.schema.c_str());
const enum Pattern res1obj = checkPattern(skipDataMatcher, name.object.c_str());
const enum Pattern res2sch = checkPattern(includeSchemaDataMatcher, name.schema.c_str());
const enum Pattern res2obj = checkPattern(includeDataMatcher, name.object.c_str());
return result[res1][res2];
return result[res1sch][res2sch] && result[res1obj][res2obj];
}
void BurpGlobals::read_stats(SINT64* stats)
@ -2888,24 +2882,6 @@ void BurpGlobals::print_stats_header()
burp_output(false, "\n");
}
void BURP_makeSymbol(BurpGlobals* tdgbl, Firebird::string& name) // add double quotes to string
{
if (tdgbl->gbl_dialect < SQL_DIALECT_V6)
return;
const char dq = '"';
for (unsigned p = 0; p < name.length(); ++p)
{
if (name[p] == dq)
{
name.insert(p, 1, dq);
++p;
}
}
name.insert(0u, 1, dq);
name += dq;
}
static void processFetchPass(const SCHAR*& password, int& itr, const int argc, Firebird::UtilSvc::ArgvType& argv)
{
if (++itr >= argc)

View File

@ -42,7 +42,9 @@
#include "../common/UtilSvc.h"
#include "../common/classes/array.h"
#include "../common/classes/fb_pair.h"
#include "../common/classes/GenericMap.h"
#include "../common/classes/MetaString.h"
#include "../common/classes/QualifiedMetaString.h"
#include "../common/SimilarToRegex.h"
#include "../common/status.h"
#include "../common/sha.h"
@ -120,7 +122,8 @@ enum rec_type {
rec_package, // Package
rec_db_creator, // Database creator
rec_publication, // Publication
rec_pub_table // Publication table
rec_pub_table, // Publication table
rec_schema // Schema
};
@ -205,9 +208,12 @@ Version 10: FB3.0.
Version 11: FB4.0.
SQL SECURITY feature, tables RDB$PUBLICATIONS/RDB$PUBLICATION_TABLES.
Version 12: FB6.0.
Schemas.
*/
const int ATT_BACKUP_FORMAT = 11;
const int ATT_BACKUP_FORMAT = 12;
// max array dimension
@ -259,6 +265,7 @@ enum att_type {
att_database_sql_security, // default sql security value
att_default_pub_active, // default publication status
att_default_pub_auto_enable,
att_database_dfl_charset_schema_name, // default character set schema name
// Relation attributes
@ -282,6 +289,7 @@ enum att_type {
att_relation_type,
att_relation_sql_security_deprecated, // can be removed later
att_relation_sql_security,
att_relation_schema_name,
// Field attributes (used for both global and local fields)
@ -341,6 +349,7 @@ enum att_type {
att_field_owner_name, // FB3.0, ODS12_0,
att_field_generator_name,
att_field_identity_type,
att_field_schema_name,
// Index attributes
@ -357,6 +366,7 @@ enum att_type {
att_index_expression_blr,
att_index_condition_source,
att_index_condition_blr,
att_index_foreign_key_schema_name,
// Data record
@ -381,6 +391,7 @@ enum att_type {
// Security class attributes
// FIXME: SERIES + ... ?
att_class_security_class = SERIES + 10,
att_class_acl,
att_class_description,
@ -396,7 +407,9 @@ enum att_type {
att_xdr_length = SERIES + 16,
att_xdr_array,
att_class_description2,
att_view_relation_schema_name,
// Trigger attributes
@ -419,6 +432,7 @@ enum att_type {
att_trig_type2,
att_trig_sql_security_deprecated, // can be removed later
att_trig_sql_security,
att_trig_schema_name,
// Function attributes
@ -444,6 +458,7 @@ enum att_type {
att_function_deterministic_flag,
att_function_sql_security_deprecated, // can be removed later
att_function_sql_security,
att_function_schema_name,
// Function argument attributes
@ -467,6 +482,9 @@ enum att_type {
att_functionarg_field_name,
att_functionarg_relation_name,
att_functionarg_description,
att_functionarg_schema_name,
att_functionarg_field_source_schema_name,
att_functionarg_relation_schema_name,
// TYPE relation attributes
att_type_name = SERIES,
@ -490,6 +508,7 @@ enum att_type {
att_trigmsg_name = SERIES,
att_trigmsg_number,
att_trigmsg_text,
att_trigmsg_schema_name,
// User privilege attributes
att_priv_user = SERIES,
@ -500,6 +519,8 @@ enum att_type {
att_priv_field_name,
att_priv_user_type,
att_priv_obj_type,
att_priv_user_schema_name,
att_priv_object_schema_name,
// files for shadowing purposes
att_file_filename = SERIES,
@ -519,6 +540,7 @@ enum att_type {
att_gen_sysflag,
att_gen_init_val,
att_gen_id_increment,
att_gen_schema_name,
// Stored procedure attributes
@ -541,6 +563,7 @@ enum att_type {
att_procedure_private_flag,
att_procedure_sql_security_deprecated, // can be removed later
att_procedure_sql_security,
att_procedure_schema_name,
// Stored procedure parameter attributes
@ -557,6 +580,8 @@ enum att_type {
att_procedureprm_mechanism,
att_procedureprm_field_name,
att_procedureprm_relation_name,
att_procedureprm_field_source_schema_name,
att_procedureprm_relation_schema_name,
// Exception attributes
@ -567,6 +592,7 @@ enum att_type {
att_exception_msg2,
att_exception_security_class, // FB3.0, ODS12_0
att_exception_owner_name,
att_exception_schema_name, // FB6.0, ODS14_0
// Relation constraints attributes
@ -576,6 +602,7 @@ enum att_type {
att_rel_constraint_defer,
att_rel_constraint_init,
att_rel_constraint_index,
att_rel_constraint_schema_name,
// Referential constraints attributes
@ -584,6 +611,8 @@ enum att_type {
att_ref_match_option,
att_ref_update_rule,
att_ref_delete_rule,
att_ref_schema_name,
att_ref_unique_const_schema_name,
// SQL roles attributes
att_role_name = SERIES,
@ -594,6 +623,7 @@ enum att_type {
// Check constraints attributes
att_chk_constraint_name = SERIES,
att_chk_trigger_name,
att_chk_schema_name,
// Character Set attributes
att_charset_name = SERIES,
@ -607,6 +637,8 @@ enum att_type {
att_charset_bytes_char,
att_charset_security_class, // FB3.0, ODS12_0
att_charset_owner_name,
att_charset_schema_name,
att_charset_coll_schema_name,
att_coll_name = SERIES,
att_coll_id,
@ -620,6 +652,7 @@ enum att_type {
att_coll_specific_attr,
att_coll_security_class, // FB3.0, ODS12_0
att_coll_owner_name,
att_coll_schema_name,
// Names mapping
att_map_name = SERIES,
@ -643,6 +676,7 @@ enum att_type {
att_package_description,
att_package_sql_security_deprecated, // can be removed later
att_package_sql_security,
att_package_schema_name,
// Database creators
att_dbc_user = SERIES,
@ -656,7 +690,16 @@ enum att_type {
// Publication tables
att_ptab_pub_name = SERIES,
att_ptab_table_name
att_ptab_table_name,
att_ptab_table_schema_name,
// Schema attributes
att_schema_name = SERIES,
att_schema_charset_schema_name,
att_schema_charset_name,
att_schema_security_class,
att_schema_owner_name,
att_schema_description,
};
@ -703,7 +746,7 @@ struct burp_fld
SSHORT fld_system_flag;
SSHORT fld_name_length;
TEXT fld_name [GDS_NAME_LEN];
TEXT fld_source [GDS_NAME_LEN];
Firebird::QualifiedMetaString fld_source;
TEXT fld_base [GDS_NAME_LEN];
TEXT fld_query_name [GDS_NAME_LEN];
TEXT fld_security_class [GDS_NAME_LEN];
@ -748,8 +791,7 @@ struct burp_rel
burp_fld* rel_fields;
SSHORT rel_flags;
SSHORT rel_id;
SSHORT rel_name_length;
GDS_NAME rel_name;
Firebird::QualifiedMetaString rel_name;
GDS_NAME rel_owner; // relation owner, if not us
ULONG rel_max_pp; // max pointer page sequence number
};
@ -763,7 +805,7 @@ enum burp_rel_flags_vals {
struct burp_pkg
{
burp_pkg* pkg_next;
GDS_NAME pkg_name;
Firebird::QualifiedMetaString pkg_name;
GDS_NAME pkg_owner;
};
@ -772,16 +814,14 @@ struct burp_pkg
struct burp_prc
{
burp_prc* prc_next;
//SSHORT prc_name_length; // Currently useless, but didn't want to delete it.
GDS_NAME prc_package;
GDS_NAME prc_name;
Firebird::QualifiedMetaString prc_name;
GDS_NAME prc_owner; // relation owner, if not us
};
struct gfld
{
TEXT gfld_name [GDS_NAME_LEN];
Firebird::QualifiedMetaString gfld_name;
ISC_QUAD gfld_vb;
ISC_QUAD gfld_vs;
ISC_QUAD gfld_vs2;
@ -806,7 +846,7 @@ struct burp_meta_obj
{
burp_meta_obj* obj_next;
USHORT obj_type;
GDS_NAME obj_name;
Firebird::QualifiedMetaString obj_name;
bool obj_class;
};
@ -1144,6 +1184,7 @@ public:
Firebird::IRequest* handles_get_ref_constraint_req_handle1;
Firebird::IRequest* handles_get_rel_constraint_req_handle1;
Firebird::IRequest* handles_get_relation_req_handle1;
Firebird::IRequest* handles_get_schema_req_handle1;
Firebird::IRequest* handles_get_security_class_req_handle1;
Firebird::IRequest* handles_get_sql_roles_req_handle1;
Firebird::IRequest* handles_get_trigger_message_req_handle1;
@ -1189,9 +1230,9 @@ public:
{
ThreadData::restoreSpecific();
}
void setupSkipData(const Firebird::string& regexp);
void setupIncludeData(const Firebird::string& regexp);
bool skipRelation(const char* name);
void setupSkipIncludePattern(const Firebird::string& regexp, USHORT alreadySetErrorCode,
Firebird::AutoPtr<Firebird::SimilarToRegex>& matcher);
bool skipRelation(const Firebird::QualifiedMetaString& name);
char veryEnd;
//starting after this members must be initialized in constructor explicitly
@ -1199,9 +1240,8 @@ public:
Firebird::FbLocalStatus status_vector;
Firebird::ThrowLocalStatus throwStatus;
Firebird::Array<Firebird::Pair<Firebird::NonPooled<Firebird::MetaString, Firebird::MetaString> > >
defaultCollations;
Firebird::SortedArray<Firebird::MetaString> systemFields;
Firebird::NonPooledMap<Firebird::QualifiedMetaString, Firebird::QualifiedMetaString> defaultCollations;
Firebird::SortedArray<Firebird::QualifiedMetaString> systemFields;
Firebird::Array<UCHAR> gbl_dpb_data;
Firebird::UtilSvc* uSvc;
bool master; // set for master thread only
@ -1211,7 +1251,9 @@ public:
bool firstMap; // this is the first time we entered get_mapping()
bool firstDbc; // this is the first time we entered get_db_creators()
bool stdIoMode; // stdin or stdout is used as backup file
Firebird::AutoPtr<Firebird::SimilarToRegex> skipSchemaDataMatcher;
Firebird::AutoPtr<Firebird::SimilarToRegex> skipDataMatcher;
Firebird::AutoPtr<Firebird::SimilarToRegex> includeSchemaDataMatcher;
Firebird::AutoPtr<Firebird::SimilarToRegex> includeDataMatcher;
public:

View File

@ -38,7 +38,6 @@ void BURP_abort(Firebird::IStatus* status = nullptr);
void BURP_error(USHORT, bool, const MsgFormat::SafeArg& arg = MsgFormat::SafeArg());
void BURP_error(USHORT, bool, const char* str);
void BURP_error_redirect(Firebird::IStatus*, USHORT, const MsgFormat::SafeArg& arg = MsgFormat::SafeArg());
void BURP_makeSymbol(BurpGlobals*, Firebird::string&);
void BURP_msg_partial(bool, USHORT, const MsgFormat::SafeArg& arg = MsgFormat::SafeArg());
void BURP_msg_put(bool, USHORT, const MsgFormat::SafeArg& arg);
const int BURP_MSG_GET_SIZE = 128; // Use it for buffers passed to this function.

View File

@ -102,6 +102,9 @@ const int IN_SW_BURP_REPLICA = 53; // replica mode
const int IN_SW_BURP_PARALLEL_WORKERS = 54; // parallel workers
const int IN_SW_BURP_DIRECT_IO = 55; // direct IO for backup files
const int IN_SW_BURP_SKIP_SCHEMA_DATA = 56; // skip data from schema
const int IN_SW_BURP_INCLUDE_SCHEMA_DATA = 57; // backup data from schemas
/**************************************************************************/
static const char* const BURP_SW_MODE_NONE = "NONE";
@ -186,8 +189,12 @@ static const Switches::in_sw_tab_t reference_burp_in_sw_table[] =
{IN_SW_BURP_S, 0, "SKIP_BAD_DATA", 0, 0, 0, false, false, 0, 4, NULL, boRestore},
{IN_SW_BURP_SE, 0, "SERVICE", 0, 0, 0, false, false, 277, 2, NULL, boGeneral},
// msg 277: @1SE(RVICE) use services manager
{IN_SW_BURP_SKIP_SCHEMA_DATA, isc_spb_res_skip_schema_data, "SKIP_SCHEMA_DATA", 0, 0, 0, false, false, 415, 13, NULL, boGeneral},
// msg 415: @1SKIP_SCHEMA_DATA skip data for schema
{IN_SW_BURP_SKIP_DATA, isc_spb_res_skip_data, "SKIP_DATA", 0, 0, 0, false, false, 355, 6, NULL, boGeneral},
// msg 355: @1SKIP_DATA skip data for table
{IN_SW_BURP_INCLUDE_SCHEMA_DATA, isc_spb_res_include_schema_data, "INCLUDE_SCHEMA_DATA", 0, 0, 0, false, false, 416, 16, NULL, boGeneral},
// msg 416: @1INCLUDE_SCHEMA_D(ATA) backup data of schemas(s)
{IN_SW_BURP_INCLUDE_DATA, isc_spb_res_include_data, "INCLUDE_DATA", 0, 0, 0, false, false, 388, 7, NULL, boGeneral},
// msg 388: @1INCLUDE(_DATA) backup data of table(s)
{IN_SW_BURP_STATS, isc_spb_bkp_stat, "STATISTICS", 0, 0, 0, false, false, 361, 2, NULL, boGeneral},

File diff suppressed because it is too large Load Diff

View File

@ -195,6 +195,7 @@ IntlParametersBlock::TagType IntlDpb::checkTag(UCHAR tag, const char** tagName)
FB_IPB_TAG(isc_dpb_host_name);
FB_IPB_TAG(isc_dpb_os_user);
FB_IPB_TAG(isc_dpb_owner);
FB_IPB_TAG(isc_dpb_search_path);
return TAG_STRING;
}
@ -324,6 +325,8 @@ IntlParametersBlock::TagType IntlSpbStart::checkTag(UCHAR tag, const char** tagN
case isc_action_svc_validate:
switch (tag)
{
FB_IPB_TAG(isc_spb_val_sch_incl);
FB_IPB_TAG(isc_spb_val_sch_excl);
FB_IPB_TAG(isc_spb_val_tab_incl);
FB_IPB_TAG(isc_spb_val_tab_excl);
FB_IPB_TAG(isc_spb_val_idx_incl);

View File

@ -149,6 +149,21 @@ void MetadataBuilder::setField(CheckStatusWrapper* status, unsigned index, const
}
}
void MetadataBuilder::setSchema(CheckStatusWrapper* status, unsigned index, const char* schema)
{
try
{
MutexLockGuard g(mtx, FB_FUNCTION);
indexError(index, "setSchema");
msgMetadata->items[index].schema = schema;
}
catch (const Exception& ex)
{
ex.stuffException(status);
}
}
void MetadataBuilder::setRelation(CheckStatusWrapper* status, unsigned index, const char* relation)
{
try
@ -407,6 +422,9 @@ void MsgMetadata::assign(IMessageMetadata* from)
items[index].field = from->getField(&status, index);
check(&status);
items[index].schema = from->getSchema(&status, index);
check(&status);
items[index].relation = from->getRelation(&status, index);
check(&status);

View File

@ -50,6 +50,7 @@ public:
{
explicit Item(MemoryPool& pool)
: field(pool),
schema(pool),
relation(pool),
owner(pool),
alias(pool),
@ -67,6 +68,7 @@ public:
Item(MemoryPool& pool, const Item& v)
: field(pool, v.field),
schema(pool, v.schema),
relation(pool, v.relation),
owner(pool, v.owner),
alias(pool, v.alias),
@ -83,6 +85,7 @@ public:
}
string field;
string schema;
string relation;
string owner;
string alias;
@ -165,6 +168,15 @@ public:
return NULL;
}
const char* getSchema(CheckStatusWrapper* status, unsigned index)
{
if (index < items.getCount())
return items[index].schema.c_str();
raiseIndexError(status, index, "getSchema");
return NULL;
}
const char* getRelation(CheckStatusWrapper* status, unsigned index)
{
if (index < items.getCount())
@ -329,6 +341,7 @@ public:
unsigned addField(CheckStatusWrapper* status);
IMessageMetadata* getMetadata(CheckStatusWrapper* status);
void setField(CheckStatusWrapper* status, unsigned index, const char* field);
void setSchema(CheckStatusWrapper* status, unsigned index, const char* schema);
void setRelation(CheckStatusWrapper* status, unsigned index, const char* relation);
void setOwner(CheckStatusWrapper* status, unsigned index, const char* owner);
void setAlias(CheckStatusWrapper* status, unsigned index, const char* alias);

View File

@ -104,6 +104,7 @@ PARSER_TOKEN(TOK_BODY, "BODY", true)
PARSER_TOKEN(TOK_BOOLEAN, "BOOLEAN", false)
PARSER_TOKEN(TOK_BOTH, "BOTH", false)
PARSER_TOKEN(TOK_BREAK, "BREAK", true)
PARSER_TOKEN(TOK_BTRIM, "BTRIM", false)
PARSER_TOKEN(TOK_BY, "BY", false)
PARSER_TOKEN(TOK_CALL, "CALL", false)
PARSER_TOKEN(TOK_CALLER, "CALLER", true)
@ -157,6 +158,7 @@ PARSER_TOKEN(TOK_CURRENT, "CURRENT", false)
PARSER_TOKEN(TOK_CURRENT_CONNECTION, "CURRENT_CONNECTION", false)
PARSER_TOKEN(TOK_CURRENT_DATE, "CURRENT_DATE", false)
PARSER_TOKEN(TOK_CURRENT_ROLE, "CURRENT_ROLE", false)
PARSER_TOKEN(TOK_CURRENT_SCHEMA, "CURRENT_SCHEMA", false)
PARSER_TOKEN(TOK_CURRENT_TIME, "CURRENT_TIME", false)
PARSER_TOKEN(TOK_CURRENT_TIMESTAMP, "CURRENT_TIMESTAMP", false)
PARSER_TOKEN(TOK_CURRENT_TRANSACTION, "CURRENT_TRANSACTION", false)
@ -297,6 +299,7 @@ PARSER_TOKEN(TOK_LONG, "LONG", false)
PARSER_TOKEN(TOK_LOWER, "LOWER", false)
PARSER_TOKEN(TOK_LPAD, "LPAD", true)
PARSER_TOKEN(TOK_LPARAM, "LPARAM", true)
PARSER_TOKEN(TOK_LTRIM, "LTRIM", false)
PARSER_TOKEN(TOK_MAKE_DBKEY, "MAKE_DBKEY", true)
PARSER_TOKEN(TOK_MANUAL, "MANUAL", true)
PARSER_TOKEN(TOK_MAPPING, "MAPPING", true)
@ -440,11 +443,13 @@ PARSER_TOKEN(TOK_RSA_PRIVATE, "RSA_PRIVATE", true)
PARSER_TOKEN(TOK_RSA_PUBLIC, "RSA_PUBLIC", true)
PARSER_TOKEN(TOK_RSA_SIGN_HASH, "RSA_SIGN_HASH", true)
PARSER_TOKEN(TOK_RSA_VERIFY_HASH, "RSA_VERIFY_HASH", true)
PARSER_TOKEN(TOK_RTRIM, "RTRIM", false)
PARSER_TOKEN(TOK_SALT_LENGTH, "SALT_LENGTH", true)
PARSER_TOKEN(TOK_SAVEPOINT, "SAVEPOINT", false)
PARSER_TOKEN(TOK_SCALAR_ARRAY, "SCALAR_ARRAY", true)
PARSER_TOKEN(TOK_DATABASE, "SCHEMA", false) // Alias of DATABASE
PARSER_TOKEN(TOK_SCHEMA, "SCHEMA", false)
PARSER_TOKEN(TOK_SCROLL, "SCROLL", false)
PARSER_TOKEN(TOK_SEARCH_PATH, "SEARCH_PATH", true)
PARSER_TOKEN(TOK_SECOND, "SECOND", false)
PARSER_TOKEN(TOK_SECURITY, "SECURITY", true)
PARSER_TOKEN(TOK_SEGMENT, "SEGMENT", true)
@ -509,9 +514,6 @@ PARSER_TOKEN(TOK_TRANSACTION, "TRANSACTION", true)
PARSER_TOKEN(TOK_TRAPS, "TRAPS", true)
PARSER_TOKEN(TOK_TRIGGER, "TRIGGER", false)
PARSER_TOKEN(TOK_TRIM, "TRIM", false)
PARSER_TOKEN(TOK_BTRIM, "BTRIM", false)
PARSER_TOKEN(TOK_LTRIM, "LTRIM", false)
PARSER_TOKEN(TOK_RTRIM, "RTRIM", false)
PARSER_TOKEN(TOK_TRUE, "TRUE", false)
PARSER_TOKEN(TOK_TRUNC, "TRUNC", true)
PARSER_TOKEN(TOK_TRUSTED, "TRUSTED", true)

View File

@ -43,6 +43,7 @@ static const UCHAR DESCRIBE_VARS[] =
isc_info_sql_scale,
isc_info_sql_length,
isc_info_sql_field,
isc_info_sql_relation_schema,
isc_info_sql_relation,
isc_info_sql_owner,
isc_info_sql_alias,
@ -337,6 +338,10 @@ void StatementMetadata::parse(unsigned bufferLength, const UCHAR* buffer)
getStringInfo(&buffer, bufferEnd, &param->field);
break;
case isc_info_sql_relation_schema:
getStringInfo(&buffer, bufferEnd, &param->schema);
break;
case isc_info_sql_relation:
getStringInfo(&buffer, bufferEnd, &param->relation);
break;

View File

@ -30,7 +30,7 @@
#ifndef COMMON_TEXTTYPE_H
#define COMMON_TEXTTYPE_H
#include "../common/classes/MetaString.h"
#include "../common/classes/QualifiedMetaString.h"
struct texttype;
@ -96,7 +96,7 @@ public:
USHORT getFlags() const;
public:
Firebird::MetaString name;
Firebird::QualifiedMetaString name;
protected:
texttype* tt;

View File

@ -33,6 +33,12 @@ namespace Firebird {
class BlrReader
{
public:
struct Flags
{
bool searchSystemSchema = false;
};
public:
BlrReader(const UCHAR* buffer, unsigned maxLen)
: start(buffer),
@ -121,6 +127,50 @@ public:
return (b4 << 24) | (b3 << 16) | (b2 << 8) | b1;
}
UCHAR parseHeader(Flags* flags = nullptr)
{
const auto version = getByte();
switch (version)
{
case blr_version4:
case blr_version5:
//case blr_version6:
break;
default:
status_exception::raise(
Arg::Gds(isc_metadata_corrupt) <<
Arg::Gds(isc_wroblrver2) << Arg::Num(blr_version4) << Arg::Num(blr_version5/*6*/) <<
Arg::Num(version));
}
auto code = getByte();
if (code == blr_flags)
{
while ((code = getByte()) != blr_end)
{
if (flags)
{
switch (code)
{
case blr_flags_search_system_schema:
flags->searchSystemSchema = true;
break;
}
}
const auto len = getWord();
seekForward(len);
}
}
else
seekBackward(1);
return version;
}
UCHAR checkByte(UCHAR expected)
{
UCHAR byte = getByte();

View File

@ -490,6 +490,8 @@ ClumpletReader::ClumpletType ClumpletReader::getClumpletType(UCHAR tag) const
case isc_action_svc_validate:
switch (tag)
{
case isc_spb_val_sch_incl:
case isc_spb_val_sch_excl:
case isc_spb_val_tab_incl:
case isc_spb_val_tab_excl:
case isc_spb_val_idx_incl:

View File

@ -31,7 +31,11 @@
#include "../common/classes/fb_string.h"
#include "../common/classes/fb_pair.h"
#include "../common/classes/objects_array.h"
#include "../common/StatusArg.h"
#include "../jrd/constants.h"
#include <algorithm>
#include <cctype>
#ifdef SFIO
#include <stdio.h>
@ -68,6 +72,119 @@ public:
MetaString(MemoryPool&, const MetaString& m) { set(m); }
MetaString(MemoryPool&, const AbstractString& s) { assign(s.c_str(), s.length()); }
public:
static void parseList(const string& str, ObjectsArray<MetaString>& list)
{
auto pos = str.begin();
const auto skipSpaces = [&pos, &str]
{
while (pos != str.end() && (*pos == ' ' || *pos == '\t' || *pos == '\f' || *pos == '\r' || *pos == '\n'))
++pos;
return pos != str.end();
};
const auto isQuoted = [](const string& name) -> bool
{
return name.length() >= 2 && name[0] == '"' && name[name.length() - 1] == '"';
};
const auto unquote = [&](const string& name) -> string
{
if (!isQuoted(name))
return name;
string result;
for (size_t i = 1; i < name.length() - 1; ++i)
{
if (name[i] == '"')
{
if (i + 1 < name.length() - 1 && name[i + 1] == '"')
++i;
else
(Arg::Gds(isc_invalid_unqualified_name_list) << str).raise();
}
result += name[i];
}
return result;
};
const auto validateUnquotedIdentifier = [&](const string& name)
{
bool first = true;
for (const auto c : name)
{
if (!((c >= 'A' && c <= 'Z') ||
(c >= 'a' && c <= 'z') ||
c == '{' ||
c == '}' ||
(!first && c >= '0' && c <= '9') ||
(!first && c == '$') ||
(!first && c == '_')))
{
(Arg::Gds(isc_invalid_unqualified_name_list) << str).raise();
}
first = false;
}
return true;
};
list.clear();
if (!skipSpaces())
return;
do
{
const auto nameStart = pos;
auto nameEnd = pos;
bool inQuotes = false;
while (pos != str.end())
{
if (*pos == '"')
inQuotes = !inQuotes;
else if (*pos == ',' && !inQuotes)
break;
nameEnd = ++pos;
skipSpaces();
}
string name(nameStart, nameEnd);
if (isQuoted(name))
name = unquote(name);
else
{
validateUnquotedIdentifier(name);
std::transform(name.begin(), name.end(), name.begin(), ::toupper);
}
if (name.isEmpty())
(Arg::Gds(isc_invalid_unqualified_name_list) << str).raise();
list.add(name);
if (pos == str.end())
break;
if (*pos == ',')
{
++pos;
skipSpaces();
}
} while(true);
}
public:
MetaString& assign(const char* s, FB_SIZE_T l);
MetaString& assign(const char* s) { return assign(s, s ? fb_strlen(s) : 0); }
MetaString& clear() { return assign(nullptr, 0); }

View File

@ -0,0 +1,272 @@
/*
* The contents of this file are subject to the Initial
* Developer's 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.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
*
* Software distributed under the License is distributed AS IS,
* 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 Adriano dos Santos Fernandes
* for the Firebird Open Source RDBMS project.
*
* Copyright (c) 2024 Adriano dos Santos Fernandes <adrianosf@gmail.com>
* and all contributors signed below.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*/
#ifndef QUALIFIED_METASTRING_H
#define QUALIFIED_METASTRING_H
#include "../common/classes/MetaString.h"
#include "../common/StatusArg.h"
#include <algorithm>
#include <cctype>
namespace Firebird {
template <typename T>
class BaseQualifiedName
{
public:
explicit BaseQualifiedName(MemoryPool& p, const T& aObject,
const T& aSchema = {}, const T& aPackage = {})
: object(p, aObject),
schema(p, aSchema),
package(p, aPackage)
{
}
explicit BaseQualifiedName(const T& aObject, const T& aSchema = {}, const T& aPackage = {})
: object(aObject),
schema(aSchema),
package(aPackage)
{
}
BaseQualifiedName(MemoryPool& p, const BaseQualifiedName& src)
: object(p, src.object),
schema(p, src.schema),
package(p, src.package)
{
}
BaseQualifiedName(const BaseQualifiedName& src)
: object(src.object),
schema(src.schema),
package(src.package)
{
}
template <typename TT>
BaseQualifiedName(const BaseQualifiedName<TT>& src)
: object(src.object),
schema(src.schema),
package(src.package)
{
}
explicit BaseQualifiedName(MemoryPool& p)
: object(p),
schema(p),
package(p)
{
}
BaseQualifiedName()
{
}
public:
static BaseQualifiedName<T> parseSchemaObject(const string& str)
{
const auto isQuoted = [](const string& name) -> bool
{
return name.length() >= 2 && name[0] == '"' && name[name.length() - 1] == '"';
};
const auto unquote = [&](const string& name) -> string
{
if (!isQuoted(name))
return name;
string result;
for (size_t i = 1; i < name.length() - 1; ++i)
{
if (name[i] == '"')
{
if (i + 1 < name.length() - 1 && name[i + 1] == '"')
++i;
else
(Arg::Gds(isc_invalid_name) << str).raise();
}
result += name[i];
}
return result;
};
const auto validateUnquotedIdentifier = [&](const string& name)
{
bool first = true;
for (const auto c : name)
{
if (!((c >= 'A' && c <= 'Z') ||
(c >= 'a' && c <= 'z') ||
c == '{' ||
c == '}' ||
(!first && c >= '0' && c <= '9') ||
(!first && c == '$') ||
(!first && c == '_')))
{
(Arg::Gds(isc_invalid_name) << str).raise();
}
first = false;
}
return true;
};
BaseQualifiedName<T> result;
string schema, object;
// Find the last unquoted dot to determine schema and object
bool inQuotes = false;
auto lastDotPos = string::npos;
for (size_t i = 0; i < str.size(); ++i)
{
if (str[i] == '"')
inQuotes = !inQuotes;
else if (str[i] == '.' && !inQuotes)
lastDotPos = i;
}
if (lastDotPos != string::npos)
{
schema = str.substr(0, lastDotPos);
object = str.substr(lastDotPos + 1);
}
else
object = str;
schema.trim(" \t\f\r\n");
object.trim(" \t\f\r\n");
// Process schema if it exists
if (schema.hasData())
{
if (isQuoted(schema))
result.schema = unquote(schema);
else
{
validateUnquotedIdentifier(schema);
std::transform(schema.begin(), schema.end(), schema.begin(), ::toupper);
result.schema = schema;
}
}
if (lastDotPos != string::npos && result.schema.isEmpty())
(Arg::Gds(isc_invalid_name) << str).raise();
// Process object
if (isQuoted(object))
result.object = unquote(object);
else
{
validateUnquotedIdentifier(object);
std::transform(object.begin(), object.end(), object.begin(), ::toupper);
result.object = object;
}
if (result.object.isEmpty())
(Arg::Gds(isc_invalid_name) << str).raise();
return result;
}
public:
bool operator<(const BaseQualifiedName& m) const
{
return schema < m.schema ||
(schema == m.schema && object < m.object) ||
(schema == m.schema && object == m.object && package < m.package);
}
bool operator>(const BaseQualifiedName& m) const
{
return schema > m.schema ||
(schema == m.schema && object > m.object) ||
(schema == m.schema && object == m.object && package > m.package);
}
bool operator==(const BaseQualifiedName& m) const
{
return schema == m.schema && object == m.object && package == m.package;
}
bool operator!=(const BaseQualifiedName& m) const
{
return !(*this == m);
}
public:
BaseQualifiedName getSchemaAndPackage() const
{
return BaseQualifiedName(package, schema);
}
void clear()
{
object = {};
schema = {};
package = {};
}
Firebird::string toQuotedString() const
{
Firebird::string s;
const auto appendName = [&s](const T& name) {
if (name.hasData())
{
s += name.toQuotedString();
return true;
}
return false;
};
if (appendName(schema))
s.append(".");
if (appendName(package))
s.append(".");
appendName(object);
return s;
}
public:
T object;
T schema;
T package;
};
using QualifiedMetaString = Firebird::BaseQualifiedName<MetaString>;
} // namespace Firebird
#endif // QUALIFIED_METASTRING_H

View File

@ -145,6 +145,13 @@ public:
add(item);
}
Array(std::initializer_list<T> items)
: Array()
{
for (auto& item : items)
add(item);
}
~Array()
{
freeData();

View File

@ -306,12 +306,24 @@ namespace Firebird
return iterator(this, getCount());
}
const T& front() const
{
fb_assert(getCount() > 0);
return *begin();
}
T& front()
{
fb_assert(getCount() > 0);
fb_assert(getCount() > 0);
return *begin();
}
const T& back() const
{
fb_assert(getCount() > 0);
return *iterator(this, getCount() - 1);
}
T& back()
{
fb_assert(getCount() > 0);
@ -372,6 +384,13 @@ namespace Firebird
add(item);
}
ObjectsArray(std::initializer_list<T> items)
: A()
{
for (auto& item : items)
add(item);
}
ObjectsArray() :
A()
{

View File

@ -0,0 +1,74 @@
#include "boost/test/unit_test.hpp"
#include "boost/test/data/test_case.hpp"
#include "../common/classes/MetaString.h"
#include "../common/classes/objects_array.h"
#include <numeric>
#include <string>
#include <tuple>
using namespace Firebird;
using std::make_tuple;
BOOST_AUTO_TEST_SUITE(MetaStringSuite)
BOOST_AUTO_TEST_SUITE(MetaStringTests)
const auto parseTestData = boost::unit_test::data::make({
make_tuple("Object1", "\"OBJECT1\""),
make_tuple(" Object2 ", "\"OBJECT2\""),
make_tuple(" Object3 , Object4 ", "\"OBJECT3\", \"OBJECT4\""),
make_tuple(" \"Object5 \" , \" Object6 \" ", "\"Object5\", \" Object6\""),
make_tuple(" Object7 , \" Object8 \" ", "\"OBJECT7\", \" Object8\""),
make_tuple(" Object9 , Object10 ", "\"OBJECT9\", \"OBJECT10\""),
});
BOOST_DATA_TEST_CASE(ParseTest, parseTestData, input, formattedList)
{
const auto parseAndFormatList = [](const char* input) -> std::string
{
ObjectsArray<MetaString> list;
MetaString::parseList(input, list);
if (list.hasData())
{
return std::accumulate(
std::next(list.begin()),
list.end(),
std::string(list[0].toQuotedString().c_str()),
[](const auto& a, const auto& b) {
return a + ", " + (b.hasData() ? b.toQuotedString().c_str() : "\" \"");
}
);
}
else
return {};
};
BOOST_TEST(parseAndFormatList(input) == formattedList);
}
const auto parseErrorTestData = boost::unit_test::data::make({
"1Object",
"_Object",
"$Object",
"\"\"name\"",
"Na me",
"Na.me",
"Name,"
"Name, "
","
"Name,,Name",
});
BOOST_DATA_TEST_CASE(ParseErrorTest, parseErrorTestData, input)
{
ObjectsArray<MetaString> array;
BOOST_CHECK_THROW(MetaString::parseList(input, array), status_exception);
}
BOOST_AUTO_TEST_SUITE_END() // MetaStringTests
BOOST_AUTO_TEST_SUITE_END() // MetaStringSuite

View File

@ -0,0 +1,64 @@
#include "boost/test/unit_test.hpp"
#include "boost/test/data/test_case.hpp"
#include "../common/classes/QualifiedMetaString.h"
#include <tuple>
using namespace Firebird;
using std::make_tuple;
BOOST_AUTO_TEST_SUITE(QualifiedMetaStringSuite)
BOOST_AUTO_TEST_SUITE(QualifiedMetaStringTests)
const auto parseTestData = boost::unit_test::data::make({
make_tuple("Object", "", "OBJECT"),
make_tuple("Schema$_0.{Object}", "SCHEMA$_0", "{OBJECT}"),
make_tuple("Schema.Object", "SCHEMA", "OBJECT"),
make_tuple("\"A\"\"name\"", "", "A\"name"),
make_tuple("Schema.\"Name\"", "SCHEMA", "Name"),
make_tuple("\"Schema\".Name", "Schema", "NAME"),
make_tuple("\"Sche ma\".\"Na me\"", "Sche ma", "Na me"),
make_tuple(" x . y ", "X", "Y"),
make_tuple(" \" x \" . \" y \" ", " x ", " y "),
make_tuple(" \"x\" . \"y\" ", "x", "y"),
make_tuple(" \"Sch\"\"ma\" . \"Obj\"\"ect\" ", "Sch\"ma", "Obj\"ect"),
});
BOOST_DATA_TEST_CASE(ParseTest, parseTestData, input, expectedSchema, expectedObject)
{
const auto name = QualifiedMetaString::parseSchemaObject(input);
BOOST_TEST(name.schema == MetaString(expectedSchema));
BOOST_TEST(name.object == MetaString(expectedObject));
}
const auto parseErrorTestData = boost::unit_test::data::make({
"1Object",
"_Object",
"$Object",
"\"\"name\"",
"Sche ma.Na me",
"Sch.ema.\"Na.me\"",
"a.b.c",
"a\"b\".c\"d\"",
"",
" ",
".",
" . ",
"\"\"",
"\" \"",
"\"\".\"\"",
"\" \".\" \"",
"\" \" . \" \"",
});
BOOST_DATA_TEST_CASE(ParseErrorTest, parseErrorTestData, input)
{
BOOST_CHECK_THROW(QualifiedMetaString::parseSchemaObject(input), status_exception);
}
BOOST_AUTO_TEST_SUITE_END() // QualifiedMetaStringTests
BOOST_AUTO_TEST_SUITE_END() // QualifiedMetaStringSuite

View File

@ -815,6 +815,7 @@ static int print_sdl_verb( ctl* control, SSHORT level)
return 0;
case isc_sdl_field:
case isc_sdl_schema:
case isc_sdl_relation:
print_string(control, offset);
break;

View File

@ -175,7 +175,8 @@ ISC_STATUS SDL_info(CheckStatusWrapper* status_vector,
const UCHAR* p = sdl;
info->sdl_info_fid = info->sdl_info_rid = 0;
info->sdl_info_relation = info->sdl_info_field = "";
info->sdl_info_relation.clear();
info->sdl_info_field.clear();
if (*p++ != isc_sdl_version1)
return error(status_vector, Arg::Gds(isc_invalid_sdl) << Arg::Num(0));
@ -207,9 +208,15 @@ ISC_STATUS SDL_info(CheckStatusWrapper* status_vector,
p += n;
break;
case isc_sdl_schema:
n = *p++;
info->sdl_info_relation.schema.assign(reinterpret_cast<const char*>(p), n);
p += n;
break;
case isc_sdl_relation:
n = *p++;
info->sdl_info_relation.assign(reinterpret_cast<const char*>(p), n);
info->sdl_info_relation.object.assign(reinterpret_cast<const char*>(p), n);
p += n;
break;
@ -281,6 +288,7 @@ int SDL_walk(CheckStatusWrapper* status_vector,
break;
case isc_sdl_field:
case isc_sdl_schema:
case isc_sdl_relation:
n = *p++;
p += n;

View File

@ -25,6 +25,7 @@
#define JRD_SDL_H
#include "../common/classes/MetaString.h"
#include "../common/classes/QualifiedMetaString.h"
#include "../common/dsc.h"
struct sdl_info
@ -32,7 +33,7 @@ struct sdl_info
USHORT sdl_info_fid;
USHORT sdl_info_rid;
Firebird::MetaString sdl_info_field;
Firebird::MetaString sdl_info_relation;
Firebird::QualifiedMetaString sdl_info_relation;
dsc sdl_info_element;
USHORT sdl_info_dimensions;
SLONG sdl_info_lower[MAX_ARRAY_DIMENSIONS];

View File

@ -23,8 +23,8 @@
*/
/* Domain definitions */
CREATE DOMAIN PLG$PASSWD AS VARBINARY(64);
CREATE DOMAIN PLG$ID AS INTEGER;
CREATE DOMAIN PUBLIC.PLG$PASSWD AS VARBINARY(64);
CREATE DOMAIN PUBLIC.PLG$ID AS INTEGER;
COMMIT;
@ -36,41 +36,41 @@ COMMIT;
/* Table: RDB$USERS */
CREATE TABLE PLG$USERS (
PLG$USER_NAME SEC$USER_NAME NOT NULL PRIMARY KEY,
PLG$GROUP_NAME SEC$USER_NAME,
PLG$UID PLG$ID,
PLG$GID PLG$ID,
PLG$PASSWD PLG$PASSWD NOT NULL,
PLG$COMMENT RDB$DESCRIPTION,
PLG$FIRST_NAME SEC$NAME_PART,
PLG$MIDDLE_NAME SEC$NAME_PART,
PLG$LAST_NAME SEC$NAME_PART);
CREATE TABLE PUBLIC.PLG$USERS (
PLG$USER_NAME SYSTEM.SEC$USER_NAME NOT NULL PRIMARY KEY,
PLG$GROUP_NAME SYSTEM.SEC$USER_NAME,
PLG$UID PUBLIC.PLG$ID,
PLG$GID PUBLIC.PLG$ID,
PLG$PASSWD PUBLIC.PLG$PASSWD NOT NULL,
PLG$COMMENT SYSTEM.RDB$DESCRIPTION,
PLG$FIRST_NAME SYSTEM.SEC$NAME_PART,
PLG$MIDDLE_NAME SYSTEM.SEC$NAME_PART,
PLG$LAST_NAME SYSTEM.SEC$NAME_PART);
COMMIT;
/* VIEW: PLG$VIEW_USERS */
CREATE VIEW PLG$VIEW_USERS (PLG$USER_NAME, PLG$GROUP_NAME, PLG$UID, PLG$GID, PLG$PASSWD,
CREATE VIEW PUBLIC.PLG$VIEW_USERS (PLG$USER_NAME, PLG$GROUP_NAME, PLG$UID, PLG$GID, PLG$PASSWD,
PLG$COMMENT, PLG$FIRST_NAME, PLG$MIDDLE_NAME, PLG$LAST_NAME) AS
SELECT PLG$USER_NAME, PLG$GROUP_NAME, PLG$UID, PLG$GID, PLG$PASSWD,
PLG$COMMENT, PLG$FIRST_NAME, PLG$MIDDLE_NAME, PLG$LAST_NAME
FROM PLG$USERS
FROM PUBLIC.PLG$USERS
WHERE CURRENT_USER = 'SYSDBA'
OR CURRENT_ROLE = 'RDB$ADMIN'
OR CURRENT_USER = PLG$USERS.PLG$USER_NAME;
/* Access rights */
GRANT ALL ON PLG$USERS to VIEW PLG$VIEW_USERS;
GRANT SELECT ON PLG$VIEW_USERS to PUBLIC;
GRANT ALL ON PUBLIC.PLG$USERS to VIEW PUBLIC.PLG$VIEW_USERS;
GRANT SELECT ON PUBLIC.PLG$VIEW_USERS to PUBLIC;
GRANT UPDATE(PLG$PASSWD, PLG$GROUP_NAME, PLG$UID, PLG$GID, PLG$FIRST_NAME, PLG$MIDDLE_NAME, PLG$LAST_NAME)
ON PLG$VIEW_USERS TO PUBLIC;
ON PUBLIC.PLG$VIEW_USERS TO PUBLIC;
COMMIT;
/* Needed record - with PASSWD = random + SHA1 (random + 'SYSDBA' + crypt('masterke')) */
INSERT INTO PLG$USERS(PLG$USER_NAME, PLG$PASSWD, PLG$FIRST_NAME, PLG$MIDDLE_NAME, PLG$LAST_NAME)
INSERT INTO PUBLIC.PLG$USERS(PLG$USER_NAME, PLG$PASSWD, PLG$FIRST_NAME, PLG$MIDDLE_NAME, PLG$LAST_NAME)
VALUES ('SYSDBA', 'NLtwcs9LrxLMOYhG0uGM9i6KS7mf3QAKvFVpmRg=', 'Sql', 'Server', 'Administrator');
COMMIT;

View File

@ -142,7 +142,7 @@ void BlrDebugWriter::putDebugSubFunction(DeclareSubFuncNode* subFuncNode)
debugData.add(fb_dbg_subfunc);
dsql_udf* subFunc = subFuncNode->dsqlFunction;
const MetaName& name = subFunc->udf_name.identifier;
const auto& name = subFunc->udf_name.object;
USHORT len = MIN(name.length(), MAX_UCHAR);
debugData.add(len);
@ -162,7 +162,7 @@ void BlrDebugWriter::putDebugSubProcedure(DeclareSubProcNode* subProcNode)
debugData.add(fb_dbg_subproc);
dsql_prc* subProc = subProcNode->dsqlProcedure;
const MetaName& name = subProc->prc_name.identifier;
const auto& name = subProc->prc_name.object;
USHORT len = MIN(name.length(), MAX_UCHAR);
debugData.add(len);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -52,8 +52,8 @@ void DsqlCompilerScratch::dumpContextStack(const DsqlContextStack* stack)
context->ctx_context,
(context->ctx_flags & CTX_system) != 0,
(context->ctx_flags & CTX_returning) != 0,
MAX_SQL_IDENTIFIER_SIZE, MAX_SQL_IDENTIFIER_SIZE, context->ctx_alias.c_str(),
MAX_SQL_IDENTIFIER_SIZE, MAX_SQL_IDENTIFIER_SIZE, context->ctx_internal_alias.c_str());
MAX_SQL_IDENTIFIER_SIZE, MAX_SQL_IDENTIFIER_SIZE, context->ctx_alias[0].toQuotedString().c_str(),
MAX_SQL_IDENTIFIER_SIZE, MAX_SQL_IDENTIFIER_SIZE, context->ctx_internal_alias.toQuotedString().c_str());
}
}
#endif
@ -99,40 +99,88 @@ void DsqlCompilerScratch::putDtype(const TypeClause* field, bool useSubType)
if (field->notNull)
appendUChar(blr_not_nullable);
if (field->typeOfName.hasData())
if (field->typeOfName.object.hasData())
{
if (field->typeOfTable.hasData())
if (field->typeOfTable.object.hasData())
{
if (field->explicitCollation)
{
appendUChar(blr_column_name2);
appendUChar(field->fullDomain ? blr_domain_full : blr_domain_type_of);
appendMetaString(field->typeOfTable.c_str());
appendMetaString(field->typeOfName.c_str());
appendUShort(field->textType);
if (field->typeOfTable.schema != ddlSchema)
{
appendUChar(blr_column_name3);
appendUChar(field->fullDomain ? blr_domain_full : blr_domain_type_of);
appendMetaString(field->typeOfTable.schema.c_str());
appendMetaString(field->typeOfTable.object.c_str());
appendMetaString(field->typeOfName.object.c_str());
appendUChar(1);
appendUShort(field->textType);
}
else
{
appendUChar(blr_column_name2);
appendUChar(field->fullDomain ? blr_domain_full : blr_domain_type_of);
appendMetaString(field->typeOfTable.object.c_str());
appendMetaString(field->typeOfName.object.c_str());
appendUShort(field->textType);
}
}
else
{
appendUChar(blr_column_name);
appendUChar(field->fullDomain ? blr_domain_full : blr_domain_type_of);
appendMetaString(field->typeOfTable.c_str());
appendMetaString(field->typeOfName.c_str());
if (field->typeOfTable.schema != ddlSchema)
{
appendUChar(blr_column_name3);
appendUChar(field->fullDomain ? blr_domain_full : blr_domain_type_of);
appendMetaString(field->typeOfTable.schema.c_str());
appendMetaString(field->typeOfTable.object.c_str());
appendMetaString(field->typeOfName.object.c_str());
appendUChar(0);
}
else
{
appendUChar(blr_column_name);
appendUChar(field->fullDomain ? blr_domain_full : blr_domain_type_of);
appendMetaString(field->typeOfTable.object.c_str());
appendMetaString(field->typeOfName.object.c_str());
}
}
}
else
{
if (field->explicitCollation)
{
appendUChar(blr_domain_name2);
appendUChar(field->fullDomain ? blr_domain_full : blr_domain_type_of);
appendMetaString(field->typeOfName.c_str());
appendUShort(field->textType);
if (field->typeOfName.schema != ddlSchema)
{
appendUChar(blr_domain_name3);
appendUChar(field->fullDomain ? blr_domain_full : blr_domain_type_of);
appendMetaString(field->typeOfName.schema.c_str());
appendMetaString(field->typeOfName.object.c_str());
appendUChar(1);
appendUShort(field->textType);
}
else
{
appendUChar(blr_domain_name2);
appendUChar(field->fullDomain ? blr_domain_full : blr_domain_type_of);
appendMetaString(field->typeOfName.object.c_str());
appendUShort(field->textType);
}
}
else
{
appendUChar(blr_domain_name);
appendUChar(field->fullDomain ? blr_domain_full : blr_domain_type_of);
appendMetaString(field->typeOfName.c_str());
if (field->typeOfName.schema != ddlSchema)
{
appendUChar(blr_domain_name3);
appendUChar(field->fullDomain ? blr_domain_full : blr_domain_type_of);
appendMetaString(field->typeOfName.schema.c_str());
appendMetaString(field->typeOfName.object.c_str());
appendUChar(0);
}
else
{
appendUChar(blr_domain_name);
appendUChar(field->fullDomain ? blr_domain_full : blr_domain_type_of);
appendMetaString(field->typeOfName.object.c_str());
}
}
}
@ -199,40 +247,88 @@ void DsqlCompilerScratch::putType(const TypeClause* type, bool useSubType)
if (type->notNull)
appendUChar(blr_not_nullable);
if (type->typeOfName.hasData())
if (type->typeOfName.object.hasData())
{
if (type->typeOfTable.hasData())
if (type->typeOfTable.object.hasData())
{
if (type->collate.hasData())
if (type->collate.object.hasData())
{
appendUChar(blr_column_name2);
appendUChar(type->fullDomain ? blr_domain_full : blr_domain_type_of);
appendMetaString(type->typeOfTable.c_str());
appendMetaString(type->typeOfName.c_str());
appendUShort(type->textType);
if (type->typeOfTable.schema != ddlSchema)
{
appendUChar(blr_column_name3);
appendUChar(type->fullDomain ? blr_domain_full : blr_domain_type_of);
appendMetaString(type->typeOfTable.schema.c_str());
appendMetaString(type->typeOfTable.object.c_str());
appendMetaString(type->typeOfName.object.c_str());
appendUChar(1);
appendUShort(type->textType);
}
else
{
appendUChar(blr_column_name2);
appendUChar(type->fullDomain ? blr_domain_full : blr_domain_type_of);
appendMetaString(type->typeOfTable.object.c_str());
appendMetaString(type->typeOfName.object.c_str());
appendUShort(type->textType);
}
}
else
{
appendUChar(blr_column_name);
appendUChar(type->fullDomain ? blr_domain_full : blr_domain_type_of);
appendMetaString(type->typeOfTable.c_str());
appendMetaString(type->typeOfName.c_str());
if (type->typeOfTable.schema != ddlSchema)
{
appendUChar(blr_column_name3);
appendUChar(type->fullDomain ? blr_domain_full : blr_domain_type_of);
appendMetaString(type->typeOfTable.schema.c_str());
appendMetaString(type->typeOfTable.object.c_str());
appendMetaString(type->typeOfName.object.c_str());
appendUChar(0);
}
else
{
appendUChar(blr_column_name);
appendUChar(type->fullDomain ? blr_domain_full : blr_domain_type_of);
appendMetaString(type->typeOfTable.object.c_str());
appendMetaString(type->typeOfName.object.c_str());
}
}
}
else
{
if (type->collate.hasData())
if (type->collate.object.hasData())
{
appendUChar(blr_domain_name2);
appendUChar(type->fullDomain ? blr_domain_full : blr_domain_type_of);
appendMetaString(type->typeOfName.c_str());
appendUShort(type->textType);
if (type->typeOfName.schema != ddlSchema)
{
appendUChar(blr_domain_name3);
appendUChar(type->fullDomain ? blr_domain_full : blr_domain_type_of);
appendMetaString(type->typeOfName.schema.c_str());
appendMetaString(type->typeOfName.object.c_str());
appendUChar(1);
appendUShort(type->textType);
}
else
{
appendUChar(blr_domain_name2);
appendUChar(type->fullDomain ? blr_domain_full : blr_domain_type_of);
appendMetaString(type->typeOfName.object.c_str());
appendUShort(type->textType);
}
}
else
{
appendUChar(blr_domain_name);
appendUChar(type->fullDomain ? blr_domain_full : blr_domain_type_of);
appendMetaString(type->typeOfName.c_str());
if (type->typeOfName.schema != ddlSchema)
{
appendUChar(blr_domain_name3);
appendUChar(type->fullDomain ? blr_domain_full : blr_domain_type_of);
appendMetaString(type->typeOfName.schema.c_str());
appendMetaString(type->typeOfName.object.c_str());
appendUChar(0);
}
else
{
appendUChar(blr_domain_name);
appendUChar(type->fullDomain ? blr_domain_full : blr_domain_type_of);
appendMetaString(type->typeOfName.object.c_str());
}
}
}
@ -285,7 +381,7 @@ void DsqlCompilerScratch::putType(const TypeClause* type, bool useSubType)
// Write out local variable field data type.
void DsqlCompilerScratch::putLocalVariableDecl(dsql_var* variable, DeclareVariableNode* hostParam,
const MetaName& collationName)
QualifiedName& collationName)
{
const auto field = variable->field;
@ -476,14 +572,14 @@ void DsqlCompilerScratch::genParameters(Array<NestConst<ParameterClause> >& para
for (FB_SIZE_T i = 0; i < parameters.getCount(); ++i)
{
ParameterClause* parameter = parameters[i];
putDebugArgument(fb_dbg_arg_input, i, parameter->name.c_str());
putDebugArgument(fb_dbg_arg_input, i, parameter->name.c_str()); // TODO: ?
putType(parameter->type, true);
// Add slot for null flag (parameter2).
appendUChar(blr_short);
appendUChar(0);
makeVariable(parameter->type, parameter->name.c_str(),
makeVariable(parameter->type, parameter->name.c_str(), // TODO: ?
dsql_var::TYPE_INPUT, 0, (USHORT) (2 * i), 0);
}
}
@ -498,14 +594,14 @@ void DsqlCompilerScratch::genParameters(Array<NestConst<ParameterClause> >& para
for (FB_SIZE_T i = 0; i < returns.getCount(); ++i)
{
ParameterClause* parameter = returns[i];
putDebugArgument(fb_dbg_arg_output, i, parameter->name.c_str());
putDebugArgument(fb_dbg_arg_output, i, parameter->name.c_str()); // TODO: ?
putType(parameter->type, true);
// Add slot for null flag (parameter2).
appendUChar(blr_short);
appendUChar(0);
makeVariable(parameter->type, parameter->name.c_str(),
makeVariable(parameter->type, parameter->name.c_str(), // TODO: ?
dsql_var::TYPE_OUTPUT, 1, (USHORT) (2 * i), i);
}
}
@ -540,7 +636,7 @@ void DsqlCompilerScratch::addCTEs(WithClause* withClause)
// Add CTE name into CTE aliases stack. It allows later to search for
// aliases of given CTE.
addCTEAlias((*cte)->alias);
addCTEAlias((*cte)->alias.c_str());
}
else
ctes.add(*cte);
@ -932,12 +1028,12 @@ RseNode* DsqlCompilerScratch::pass1RseIsRecursive(RseNode* input)
// Check if table reference is recursive i.e. its name is equal to the name of current processing CTE.
bool DsqlCompilerScratch::pass1RelProcIsRecursive(RecordSourceNode* input)
{
MetaName relName;
QualifiedName relName;
string relAlias;
if (auto procNode = nodeAs<ProcedureSourceNode>(input))
{
relName = procNode->dsqlName.identifier;
relName = procNode->dsqlName;
relAlias = procNode->alias;
}
else if (auto relNode = nodeAs<RelationSourceNode>(input))
@ -951,10 +1047,10 @@ bool DsqlCompilerScratch::pass1RelProcIsRecursive(RecordSourceNode* input)
fb_assert(currCtes.hasData());
const SelectExprNode* currCte = currCtes.object();
const bool recursive = currCte->alias == relName.c_str();
const bool recursive = relName.schema.isEmpty() && currCte->alias == relName.object.c_str();
if (recursive)
addCTEAlias(relAlias.hasData() ? relAlias.c_str() : relName.c_str());
addCTEAlias(relAlias.hasData() ? relAlias.c_str() : relName.object.c_str());
return recursive;
}

View File

@ -96,6 +96,7 @@ public:
mainScratch(aMainScratch),
outerMessagesMap(p),
outerVarsMap(p),
ddlSchema(p),
ctes(p),
cteAliases(p),
subFunctions(p),
@ -151,16 +152,49 @@ public:
dsqlStatement = aDsqlStatement;
}
void qualifyNewName(QualifiedName& name) const
{
using namespace Firebird;
const auto tdbb = JRD_get_thread_data();
if (!dbb->dbb_attachment->qualifyNewName(tdbb, name))
{
if (name.schema.isEmpty())
status_exception::raise(Arg::Gds(isc_dyn_cannot_infer_schema));
else
status_exception::raise(Arg::Gds(isc_dyn_schema_not_found) << name.schema.toQuotedString());
}
}
void qualifyExistingName(QualifiedName& name, ObjectType objectType) const
{
if (!(name.schema.isEmpty() && name.object.hasData()))
return;
const auto tdbb = JRD_get_thread_data();
const auto attachment = tdbb->getAttachment();
if (ddlSchema.hasData())
{
Firebird::ObjectsArray<Firebird::MetaString> schemaSearchPath({ddlSchema, SYSTEM_SCHEMA});
attachment->qualifyExistingName(tdbb, name, objectType, &schemaSearchPath);
}
else
attachment->qualifyExistingName(tdbb, name, objectType);
}
void putBlrMarkers(ULONG marks);
void putDtype(const TypeClause* field, bool useSubType);
void putType(const TypeClause* type, bool useSubType);
void putLocalVariableDecl(dsql_var* variable, DeclareVariableNode* hostParam, const MetaName& collationName);
void putLocalVariableDecl(dsql_var* variable, DeclareVariableNode* hostParam, QualifiedName& collationName);
void putLocalVariableInit(dsql_var* variable, const DeclareVariableNode* hostParam);
void putLocalVariable(dsql_var* variable, DeclareVariableNode* hostParam, const MetaName& collationName)
void putLocalVariable(dsql_var* variable)
{
putLocalVariableDecl(variable, hostParam, collationName);
putLocalVariableInit(variable, hostParam);
QualifiedName dummyCollationName;
putLocalVariableDecl(variable, nullptr, dummyCollationName);
putLocalVariableInit(variable, nullptr);
}
void putOuterMaps();
@ -301,8 +335,8 @@ public:
USHORT errorHandlers = 0; // count of active error handlers
USHORT clientDialect = 0; // dialect passed into the API call
USHORT inOuterJoin = 0; // processing inside outer-join part
Firebird::string aliasRelationPrefix; // prefix for every relation-alias.
MetaName package; // package being defined
Firebird::ObjectsArray<QualifiedName> aliasRelationPrefix; // prefix for every relation-alias.
QualifiedName package; // package being defined
Firebird::Stack<SelectExprNode*> currCtes; // current processing CTE's
dsql_ctx* recursiveCtx = nullptr; // context of recursive CTE
USHORT recursiveCtxId = 0; // id of recursive union stream context
@ -317,6 +351,7 @@ public:
DsqlCompilerScratch* mainScratch = nullptr;
Firebird::NonPooledMap<USHORT, USHORT> outerMessagesMap; // <outer, inner>
Firebird::NonPooledMap<USHORT, USHORT> outerVarsMap; // <outer, inner>
MetaName ddlSchema;
private:
Firebird::HalfStaticArray<SelectExprNode*, 4> ctes; // common table expressions

View File

@ -1055,7 +1055,10 @@ void DsqlDdlRequest::execute(thread_db* tdbb, jrd_tra** traHandle,
(internalScratch->flags & DsqlCompilerScratch::FLAG_INTERNAL_REQUEST);
if (!isInternalRequest && node->mustBeReplicated())
REPL_exec_sql(tdbb, req_transaction, getDsqlStatement()->getOrgText());
{
REPL_exec_sql(tdbb, req_transaction, getDsqlStatement()->getOrgText(),
*getDsqlStatement()->getSchemaSearchPath());
}
}
catch (status_exception& ex)
{

View File

@ -259,16 +259,37 @@ void DsqlStatementCache::buildStatementKey(thread_db* tdbb, RefStrPtr& key, cons
{
const auto attachment = tdbb->getAttachment();
const auto searchPathLen = std::accumulate(
attachment->att_schema_search_path->begin(),
attachment->att_schema_search_path->end(),
0u,
[](const auto& len, const auto& pathItem) {
return len + pathItem.length() + 1u;
}
);
const SSHORT charSetId = isInternalRequest ? CS_METADATA : attachment->att_charset;
const int debugOptions = (int) attachment->getDebugOptions().getDsqlKeepBlr();
key = FB_NEW_POOL(getPool()) RefString(getPool());
key->resize(1 + sizeof(charSetId) + text.length() + 1 + searchPathLen + 1);
key->resize(1 + sizeof(charSetId) + text.length());
char* p = key->begin();
*p = (clientDialect << 2) | (int(isInternalRequest) << 1) | debugOptions;
memcpy(p + 1, &charSetId, sizeof(charSetId));
memcpy(p + 1 + sizeof(charSetId), text.c_str(), text.length());
*p++ = (clientDialect << 2) | (int(isInternalRequest) << 1) | debugOptions;
memcpy(p, &charSetId, sizeof(charSetId));
p += sizeof(charSetId);
memcpy(p, text.c_str(), text.length() + 1);
p += text.length() + 1;
for (const auto& pathItem : *attachment->att_schema_search_path)
{
memcpy(p, pathItem.c_str(), pathItem.length() + 1);
p += pathItem.length() + 1;
}
*p = '\0';
fb_assert(p + 1 == key->end());
}
void DsqlStatementCache::buildVerifyKey(thread_db* tdbb, string& key, bool isInternalRequest)

View File

@ -36,6 +36,16 @@ using namespace Jrd;
// Class DsqlStatement
DsqlStatement::DsqlStatement(MemoryPool& pool, dsql_dbb* aDsqlAttachment)
: PermanentStorage(pool),
dsqlAttachment(aDsqlAttachment),
ports(pool)
{
pool.setStatsGroup(memoryStats);
schemaSearchPath = dsqlAttachment->dbb_attachment->att_schema_search_path;
}
// Rethrow an exception with isc_no_meta_update and prefix codes.
void DsqlStatement::rethrowDdlException(status_exception& ex, bool metadataUpdate, DdlNode* node)
{
@ -80,6 +90,7 @@ int DsqlStatement::release()
void DsqlStatement::doRelease()
{
fb_assert(!cacheKey.hasData());
setSqlText(nullptr);
setOrgText(nullptr, 0);

View File

@ -68,16 +68,7 @@ public:
static void rethrowDdlException(Firebird::status_exception& ex, bool metadataUpdate, DdlNode* node);
public:
DsqlStatement(MemoryPool& pool, dsql_dbb* aDsqlAttachment)
: PermanentStorage(pool),
dsqlAttachment(aDsqlAttachment),
type(TYPE_SELECT),
flags(0),
blrVersion(5),
ports(pool)
{
pool.setStatsGroup(memoryStats);
}
DsqlStatement(MemoryPool& pool, dsql_dbb* aDsqlAttachment);
protected:
virtual ~DsqlStatement() = default;
@ -139,6 +130,8 @@ public:
void setCacheKey(Firebird::RefStrPtr& value) { cacheKey = value; }
void resetCacheKey() { cacheKey = nullptr; }
const auto getSchemaSearchPath() const { return schemaSearchPath; }
public:
virtual bool isDml() const
{
@ -174,9 +167,9 @@ protected:
protected:
dsql_dbb* dsqlAttachment;
Firebird::MemoryStats memoryStats;
Type type; // Type of statement
ULONG flags; // generic flag
unsigned blrVersion;
Type type = TYPE_SELECT; // Type of statement
ULONG flags = 0; // generic flag
unsigned blrVersion = 5;
Firebird::RefStrPtr sqlText;
Firebird::RefStrPtr orgText;
Firebird::RefStrPtr cacheKey;
@ -185,6 +178,7 @@ protected:
dsql_msg* receiveMsg = nullptr; // Per record message to be received
dsql_par* eof = nullptr; // End of file parameter
DsqlCompilerScratch* scratch = nullptr;
Firebird::RefPtr<Firebird::AnyRef<Firebird::ObjectsArray<Firebird::MetaString>>> schemaSearchPath;
private:
Firebird::AtomicCounter refCounter;

File diff suppressed because it is too large Load Diff

View File

@ -339,7 +339,7 @@ public:
class CollateNode final : public TypedNode<ValueExprNode, ExprNode::TYPE_COLLATE>
{
public:
CollateNode(MemoryPool& pool, ValueExprNode* aArg, const MetaName& aCollation);
CollateNode(MemoryPool& pool, ValueExprNode* aArg, const QualifiedName& aCollation);
virtual void getChildren(NodeRefsHolder& holder, bool dsql) const
{
@ -353,7 +353,7 @@ public:
virtual ValueExprNode* dsqlPass(DsqlCompilerScratch* dsqlScratch);
static ValueExprNode* pass1Collate(DsqlCompilerScratch* dsqlScratch, ValueExprNode* input,
const MetaName& collation);
QualifiedName& collation);
// This class is used only in the parser. It turns in a CastNode in dsqlPass.
@ -394,7 +394,7 @@ private:
public:
NestConst<ValueExprNode> arg;
MetaName collation;
QualifiedName collation;
};
@ -530,6 +530,29 @@ public:
};
class CurrentSchemaNode final : public TypedNode<ValueExprNode, ExprNode::TYPE_CURRENT_SCHEMA>
{
public:
explicit CurrentSchemaNode(MemoryPool& pool)
: TypedNode<ValueExprNode, ExprNode::TYPE_CURRENT_SCHEMA>(pool)
{
}
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp);
Firebird::string internalPrint(NodePrinter& printer) const override;
ValueExprNode* dsqlPass(DsqlCompilerScratch* dsqlScratch) override;
void setParameterName(dsql_par* parameter) const override;
void genBlr(DsqlCompilerScratch* dsqlScratch) override;
void make(DsqlCompilerScratch* dsqlScratch, dsc* desc) override;
void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc) override;
ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const override;
ValueExprNode* pass2(thread_db* tdbb, CompilerScratch* csb) override;
dsc* execute(thread_db* tdbb, Request* request) const override;
};
class CurrentUserNode final : public TypedNode<ValueExprNode, ExprNode::TYPE_CURRENT_USER>
{
public:
@ -612,7 +635,7 @@ public:
class DefaultNode : public DsqlNode<DefaultNode, ExprNode::TYPE_DEFAULT>
{
public:
explicit DefaultNode(MemoryPool& pool, const MetaName& aRelationName,
explicit DefaultNode(MemoryPool& pool, const QualifiedName& aRelationName,
const MetaName& aFieldName);
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp);
@ -631,7 +654,7 @@ public:
virtual ValueExprNode* pass1(thread_db* tdbb, CompilerScratch* csb);
public:
const MetaName relationName;
const QualifiedName relationName;
const MetaName fieldName;
private:
@ -839,10 +862,10 @@ public:
private:
static dsql_fld* resolveContext(DsqlCompilerScratch* dsqlScratch,
const MetaName& qualifier, dsql_ctx* context);
const QualifiedName& qualifier, dsql_ctx* context);
public:
MetaName dsqlQualifier;
QualifiedName dsqlQualifier;
MetaName dsqlName;
dsql_ctx* const dsqlContext;
dsql_fld* const dsqlField;
@ -860,7 +883,7 @@ class GenIdNode final : public TypedNode<ValueExprNode, ExprNode::TYPE_GEN_ID>
{
public:
GenIdNode(MemoryPool& pool, bool aDialect1,
const MetaName& name,
const QualifiedName& name,
ValueExprNode* aArg,
bool aImplicit, bool aIdentity);
@ -987,7 +1010,7 @@ public:
void fixMinSInt128(MemoryPool& pool);
public:
const IntlString* dsqlStr = nullptr;
NestConst<IntlString> dsqlStr;
dsc litDesc;
USHORT litNumStringLength = 0;
};
@ -1671,7 +1694,7 @@ public:
class RecordKeyNode final : public TypedNode<ValueExprNode, ExprNode::TYPE_RECORD_KEY>
{
public:
RecordKeyNode(MemoryPool& pool, UCHAR aBlrOp, const MetaName& aDsqlQualifier = NULL);
RecordKeyNode(MemoryPool& pool, UCHAR aBlrOp, const QualifiedName& aDsqlQualifier = {});
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp);
@ -1748,7 +1771,7 @@ private:
void raiseError(dsql_ctx* context) const;
public:
MetaName dsqlQualifier;
QualifiedName dsqlQualifier;
NestConst<RecordSourceNode> dsqlRelation;
StreamType recStream;
const UCHAR blrOp;

View File

@ -85,7 +85,7 @@ public:
text += "<";
text += s;
text += ">";
text += value.toString();
text += value.toQuotedString();
text += "</";
text += s;
text += ">\n";

View File

@ -173,8 +173,6 @@ public:
};
class DdlNode;
class DdlNode : public Node
{
public:
@ -183,14 +181,24 @@ public:
{
}
static void protectSystemSchema(const MetaName& name, ObjectType objType)
{
if (name == SYSTEM_SCHEMA)
{
Firebird::status_exception::raise(
Firebird::Arg::Gds(isc_dyn_cannot_mod_obj_sys_schema) <<
getObjectName(objType));
}
}
static bool deleteSecurityClass(thread_db* tdbb, jrd_tra* transaction,
const MetaName& secClass);
static void storePrivileges(thread_db* tdbb, jrd_tra* transaction,
const MetaName& name, int type, const char* privileges);
const QualifiedName& name, int type, const char* privileges);
static void deletePrivilegesByRelName(thread_db* tdbb, jrd_tra* transaction,
const MetaName& name, int type);
const QualifiedName& name, int type);
public:
// Check permission on DDL operation. Return true if everything is OK.
@ -221,8 +229,8 @@ public:
enum DdlTriggerWhen { DTW_BEFORE, DTW_AFTER };
static void executeDdlTrigger(thread_db* tdbb, jrd_tra* transaction,
DdlTriggerWhen when, int action, const MetaName& objectName,
const MetaName& oldNewObjectName, const Firebird::string& sqlText);
DdlTriggerWhen when, int action, const QualifiedName& objectName,
const QualifiedName& oldNewObjectName, const Firebird::string& sqlText);
protected:
typedef Firebird::Pair<Firebird::Left<MetaName, bid> > MetaNameBidPair;
@ -246,9 +254,9 @@ protected:
}
void executeDdlTrigger(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction,
DdlTriggerWhen when, int action, const MetaName& objectName,
const MetaName& oldNewObjectName);
void storeGlobalField(thread_db* tdbb, jrd_tra* transaction, MetaName& name,
DdlTriggerWhen when, int action, const QualifiedName& objectName,
const QualifiedName& oldNewObjectName);
void storeGlobalField(thread_db* tdbb, jrd_tra* transaction, QualifiedName& name,
const TypeClause* field,
const Firebird::string& computedSource = "",
const BlrDebugWriter::BlrData& computedValue = BlrDebugWriter::BlrData());
@ -468,6 +476,7 @@ public:
TYPE_CURRENT_TIME,
TYPE_CURRENT_TIMESTAMP,
TYPE_CURRENT_ROLE,
TYPE_CURRENT_SCHEMA,
TYPE_CURRENT_USER,
TYPE_DERIVED_EXPR,
TYPE_DECODE,
@ -1655,7 +1664,7 @@ public:
class GeneratorItem : public Printable
{
public:
GeneratorItem(Firebird::MemoryPool& pool, const MetaName& name)
GeneratorItem(Firebird::MemoryPool& pool, const QualifiedName& name)
: id(0), name(pool, name), secName(pool)
{}
@ -1672,8 +1681,8 @@ public:
public:
SLONG id;
MetaName name;
MetaName secName;
QualifiedName name;
QualifiedName secName;
};
typedef Firebird::Array<StreamType> StreamMap;

View File

@ -55,7 +55,7 @@ namespace
{
// Return function and procedure names (in the user charset) and optionally its details for a
// given package.
void collectPackagedItems(thread_db* tdbb, jrd_tra* transaction, const MetaName& metaName,
void collectPackagedItems(thread_db* tdbb, jrd_tra* transaction, const QualifiedName& packageName,
SortedObjectsArray<Signature>& functions,
SortedObjectsArray<Signature>& procedures, bool details)
{
@ -64,7 +64,8 @@ namespace
FOR (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction)
FUN IN RDB$FUNCTIONS
WITH FUN.RDB$PACKAGE_NAME EQ metaName.c_str()
WITH FUN.RDB$SCHEMA_NAME EQ packageName.schema.c_str() AND
FUN.RDB$PACKAGE_NAME EQ packageName.object.c_str()
{
Signature function(FUN.RDB$FUNCTION_NAME);
function.defined = !FUN.RDB$FUNCTION_BLR.NULL || !FUN.RDB$ENTRYPOINT.NULL;
@ -77,21 +78,23 @@ namespace
FOR (REQUEST_HANDLE requestHandle2 TRANSACTION_HANDLE transaction)
ARG IN RDB$FUNCTION_ARGUMENTS CROSS
FLD IN RDB$FIELDS
WITH ARG.RDB$PACKAGE_NAME EQ metaName.c_str() AND
WITH ARG.RDB$SCHEMA_NAME EQ FUN.RDB$SCHEMA_NAME AND
ARG.RDB$PACKAGE_NAME EQ FUN.RDB$PACKAGE_NAME AND
ARG.RDB$FUNCTION_NAME EQ FUN.RDB$FUNCTION_NAME AND
FLD.RDB$SCHEMA_NAME EQUIV ARG.RDB$FIELD_SOURCE_SCHEMA_NAME AND
FLD.RDB$FIELD_NAME EQ ARG.RDB$FIELD_SOURCE
{
SignatureParameter parameter(*getDefaultMemoryPool());
parameter.number = ARG.RDB$ARGUMENT_POSITION;
parameter.name = ARG.RDB$ARGUMENT_NAME;
parameter.fieldSource = ARG.RDB$FIELD_SOURCE;
parameter.fieldSource = QualifiedName(ARG.RDB$FIELD_SOURCE, ARG.RDB$FIELD_SOURCE_SCHEMA_NAME);
parameter.mechanism = ARG.RDB$ARGUMENT_MECHANISM;
if (!ARG.RDB$FIELD_NAME.NULL)
parameter.fieldName = ARG.RDB$FIELD_NAME;
parameter.fieldName = QualifiedName(ARG.RDB$FIELD_NAME);
if (!ARG.RDB$RELATION_NAME.NULL)
parameter.relationName = ARG.RDB$RELATION_NAME;
parameter.relationName = QualifiedName(ARG.RDB$RELATION_NAME, ARG.RDB$RELATION_SCHEMA_NAME);
if (!ARG.RDB$COLLATION_ID.NULL)
parameter.collationId = ARG.RDB$COLLATION_ID;
if (!ARG.RDB$NULL_FLAG.NULL)
@ -132,7 +135,8 @@ namespace
FOR (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction)
PRC IN RDB$PROCEDURES
WITH PRC.RDB$PACKAGE_NAME EQ metaName.c_str()
WITH PRC.RDB$SCHEMA_NAME EQ packageName.schema.c_str() AND
PRC.RDB$PACKAGE_NAME EQ packageName.object.c_str()
{
Signature procedure(PRC.RDB$PROCEDURE_NAME);
procedure.defined = !PRC.RDB$PROCEDURE_BLR.NULL || !PRC.RDB$ENTRYPOINT.NULL;
@ -142,21 +146,23 @@ namespace
FOR (REQUEST_HANDLE requestHandle2 TRANSACTION_HANDLE transaction)
PRM IN RDB$PROCEDURE_PARAMETERS CROSS
FLD IN RDB$FIELDS
WITH PRM.RDB$PACKAGE_NAME EQ metaName.c_str() AND
WITH PRM.RDB$SCHEMA_NAME EQ PRC.RDB$SCHEMA_NAME AND
PRM.RDB$PACKAGE_NAME EQ PRC.RDB$PACKAGE_NAME AND
PRM.RDB$PROCEDURE_NAME EQ PRC.RDB$PROCEDURE_NAME AND
FLD.RDB$SCHEMA_NAME EQUIV PRM.RDB$FIELD_SOURCE_SCHEMA_NAME AND
FLD.RDB$FIELD_NAME EQ PRM.RDB$FIELD_SOURCE
{
SignatureParameter parameter(*getDefaultMemoryPool());
parameter.type = PRM.RDB$PARAMETER_TYPE;
parameter.number = PRM.RDB$PARAMETER_NUMBER;
parameter.name = PRM.RDB$PARAMETER_NAME;
parameter.fieldSource = PRM.RDB$FIELD_SOURCE;
parameter.fieldSource = QualifiedName(PRM.RDB$FIELD_SOURCE, PRM.RDB$FIELD_SOURCE_SCHEMA_NAME);
parameter.mechanism = PRM.RDB$PARAMETER_MECHANISM;
if (!PRM.RDB$FIELD_NAME.NULL)
parameter.fieldName = PRM.RDB$FIELD_NAME;
parameter.fieldName = QualifiedName(PRM.RDB$FIELD_NAME);
if (!PRM.RDB$RELATION_NAME.NULL)
parameter.relationName = PRM.RDB$RELATION_NAME;
parameter.relationName = QualifiedName(PRM.RDB$RELATION_NAME, PRM.RDB$RELATION_SCHEMA_NAME);
if (!PRM.RDB$COLLATION_ID.NULL)
parameter.collationId = PRM.RDB$COLLATION_ID;
if (!PRM.RDB$NULL_FLAG.NULL)
@ -216,6 +222,14 @@ string CreateAlterPackageNode::internalPrint(NodePrinter& printer) const
DdlNode* CreateAlterPackageNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
{
if (create)
dsqlScratch->qualifyNewName(name);
else
dsqlScratch->qualifyExistingName(name, obj_package_header);
protectSystemSchema(name.schema, obj_package_header);
dsqlScratch->ddlSchema = name.schema;
if (alter && !items)
return DdlNode::dsqlPass(dsqlScratch);
@ -235,18 +249,19 @@ DdlNode* CreateAlterPackageNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
CreateAlterFunctionNode* const fun = (*items)[i].function;
ddlNode = fun;
if (functionNames.exist(fun->name))
if (functionNames.exist(fun->name.object))
{
status_exception::raise(
Arg::Gds(isc_no_meta_update) <<
Arg::Gds(isc_dyn_duplicate_package_item) <<
Arg::Str("FUNCTION") << Arg::Str(fun->name));
Arg::Str("FUNCTION") << fun->name.object);
}
functionNames.add(fun->name);
functionNames.add(fun->name.object);
fun->alter = true;
fun->package = name;
fun->name.schema = name.schema;
fun->name.package = name.object;
break;
}
@ -255,18 +270,19 @@ DdlNode* CreateAlterPackageNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
CreateAlterProcedureNode* const proc = (*items)[i].procedure;
ddlNode = proc;
if (procedureNames.exist(proc->name))
if (procedureNames.exist(proc->name.object))
{
status_exception::raise(
Arg::Gds(isc_no_meta_update) <<
Arg::Gds(isc_dyn_duplicate_package_item) <<
Arg::Str("PROCEDURE") << Arg::Str(proc->name));
Arg::Str("PROCEDURE") << proc->name.object);
}
procedureNames.add(proc->name);
procedureNames.add(proc->name.object);
proc->alter = true;
proc->package = name;
proc->name.schema = name.schema;
proc->name.package = name.object;
break;
}
@ -280,6 +296,7 @@ DdlNode* CreateAlterPackageNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
FB_NEW_POOL(pool) DsqlCompilerScratch(pool, dsqlScratch->getAttachment(),
dsqlScratch->getTransaction(), itemStatement);
itemScratch->ddlSchema = name.schema;
itemScratch->clientDialect = dsqlScratch->clientDialect;
itemScratch->flags |= DsqlCompilerScratch::FLAG_DDL;
itemScratch->package = name;
@ -298,16 +315,13 @@ DdlNode* CreateAlterPackageNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
void CreateAlterPackageNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
{
dsc dscName;
dscName.makeText(name.length(), CS_METADATA, (UCHAR*) name.c_str());
if (alter)
{
if (SCL_check_package(tdbb, &dscName, SCL_alter) || !create)
if (SCL_check_package(tdbb, name, SCL_alter) || !create)
return;
}
SCL_check_create_access(tdbb, obj_packages);
SCL_check_create_access(tdbb, obj_packages, name.schema);
}
@ -332,7 +346,7 @@ void CreateAlterPackageNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlS
if (!executeAlterIndividualParameters(tdbb, dsqlScratch, transaction))
status_exception::raise(
Arg::Gds(isc_no_meta_update) <<
Arg::Gds(isc_dyn_package_not_found) << Arg::Str(name));
Arg::Gds(isc_dyn_package_not_found) << name.toQuotedString());
}
else if (!executeAlter(tdbb, dsqlScratch, transaction))
{
@ -342,14 +356,14 @@ void CreateAlterPackageNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlS
{
status_exception::raise(
Arg::Gds(isc_no_meta_update) <<
Arg::Gds(isc_dyn_package_not_found) << Arg::Str(name));
Arg::Gds(isc_dyn_package_not_found) << name.toQuotedString());
}
}
dsc desc;
desc.makeText(name.length(), ttype_metadata,
(UCHAR*) const_cast<char*>(name.c_str())); // safe const_cast
DFW_post_work(transaction, dfw_modify_package_header, &desc, 0);
dsc schemaDesc, nameDesc;
schemaDesc.makeText(name.schema.length(), ttype_metadata, (UCHAR*) const_cast<char*>(name.schema.c_str()));
nameDesc.makeText(name.object.length(), ttype_metadata, (UCHAR*) const_cast<char*>(name.object.c_str()));
DFW_post_work(transaction, dfw_modify_package_header, &nameDesc, &schemaDesc, 0);
}
else
executeCreate(tdbb, dsqlScratch, transaction);
@ -367,8 +381,7 @@ void CreateAlterPackageNode::executeCreate(thread_db* tdbb, DsqlCompilerScratch*
if (createIfNotExistsOnly && !DYN_UTIL_check_unique_name_nothrow(tdbb, transaction, name, obj_package_header))
return;
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE,
DDL_TRIGGER_CREATE_PACKAGE, name, NULL);
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE, DDL_TRIGGER_CREATE_PACKAGE, name, {});
DYN_UTIL_check_unique_name(tdbb, transaction, name, obj_package_header);
@ -377,8 +390,11 @@ void CreateAlterPackageNode::executeCreate(thread_db* tdbb, DsqlCompilerScratch*
STORE (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction)
PKG IN RDB$PACKAGES USING
{
PKG.RDB$SCHEMA_NAME.NULL = FALSE;
strcpy(PKG.RDB$SCHEMA_NAME, name.schema.c_str());
PKG.RDB$PACKAGE_NAME.NULL = FALSE;
strcpy(PKG.RDB$PACKAGE_NAME, name.c_str());
strcpy(PKG.RDB$PACKAGE_NAME, name.object.c_str());
PKG.RDB$SYSTEM_FLAG.NULL = FALSE;
PKG.RDB$SYSTEM_FLAG = 0;
@ -405,8 +421,7 @@ void CreateAlterPackageNode::executeCreate(thread_db* tdbb, DsqlCompilerScratch*
executeItems(tdbb, dsqlScratch, transaction);
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER, DDL_TRIGGER_CREATE_PACKAGE,
name, NULL);
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER, DDL_TRIGGER_CREATE_PACKAGE, name, {});
}
@ -420,12 +435,12 @@ bool CreateAlterPackageNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch*
FOR (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction)
PKG IN RDB$PACKAGES
WITH PKG.RDB$PACKAGE_NAME EQ name.c_str()
WITH PKG.RDB$SCHEMA_NAME EQ name.schema.c_str() AND
PKG.RDB$PACKAGE_NAME EQ name.object.c_str()
{
modified = true;
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE,
DDL_TRIGGER_ALTER_PACKAGE, name, NULL);
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE, DDL_TRIGGER_ALTER_PACKAGE, name, {});
SortedObjectsArray<Signature> existingFuncs(pool);
SortedObjectsArray<Signature> existingProcs(pool);
@ -436,8 +451,7 @@ bool CreateAlterPackageNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch*
{
if (!functionNames.exist(i->name))
{
DropFunctionNode dropNode(pool, i->name);
dropNode.package = name;
DropFunctionNode dropNode(pool, QualifiedName(i->name, name.schema, name.object));
dropNode.dsqlPass(dsqlScratch);
dropNode.executeDdl(tdbb, dsqlScratch, transaction, true);
}
@ -448,8 +462,7 @@ bool CreateAlterPackageNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch*
{
if (!procedureNames.exist(i->name))
{
DropProcedureNode dropNode(pool, i->name);
dropNode.package = name;
DropProcedureNode dropNode(pool, QualifiedName(i->name, name.schema, name.object));
dropNode.dsqlPass(dsqlScratch);
dropNode.executeDdl(tdbb, dsqlScratch, transaction, true);
}
@ -474,10 +487,10 @@ bool CreateAlterPackageNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch*
owner = PKG.RDB$OWNER_NAME;
dsc desc;
desc.makeText(name.length(), ttype_metadata,
(UCHAR*) const_cast<char*>(name.c_str())); // safe const_cast
DFW_post_work(transaction, dfw_drop_package_body, &desc, 0);
dsc schemaDesc, nameDesc;
schemaDesc.makeText(name.schema.length(), ttype_metadata, (UCHAR*) const_cast<char*>(name.schema.c_str()));
nameDesc.makeText(name.object.length(), ttype_metadata, (UCHAR*) const_cast<char*>(name.object.c_str()));
DFW_post_work(transaction, dfw_drop_package_body, &nameDesc, &schemaDesc, 0);
}
END_FOR
@ -485,8 +498,7 @@ bool CreateAlterPackageNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch*
{
executeItems(tdbb, dsqlScratch, transaction);
executeDdlTrigger(tdbb, dsqlScratch, transaction,
DTW_AFTER, DDL_TRIGGER_ALTER_PACKAGE, name, NULL);
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER, DDL_TRIGGER_ALTER_PACKAGE, name, {});
}
return modified;
@ -500,12 +512,12 @@ bool CreateAlterPackageNode::executeAlterIndividualParameters(thread_db* tdbb, D
FOR (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction)
PKG IN RDB$PACKAGES
WITH PKG.RDB$PACKAGE_NAME EQ name.c_str()
WITH PKG.RDB$SCHEMA_NAME EQ name.schema.c_str() AND
PKG.RDB$PACKAGE_NAME EQ name.object.c_str()
{
modified = true;
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE,
DDL_TRIGGER_ALTER_PACKAGE, name, NULL);
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE, DDL_TRIGGER_ALTER_PACKAGE, name, {});
MODIFY PKG
if (ssDefiner.has_value())
@ -523,10 +535,7 @@ bool CreateAlterPackageNode::executeAlterIndividualParameters(thread_db* tdbb, D
END_FOR
if (modified)
{
executeDdlTrigger(tdbb, dsqlScratch, transaction,
DTW_AFTER, DDL_TRIGGER_ALTER_PACKAGE, name, NULL);
}
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER, DDL_TRIGGER_ALTER_PACKAGE, name, {});
return modified;
}
@ -568,14 +577,11 @@ string DropPackageNode::internalPrint(NodePrinter& printer) const
void DropPackageNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
{
dsc dscName;
dscName.makeText(name.length(), CS_METADATA, (UCHAR*) name.c_str());
SCL_check_package(tdbb, &dscName, SCL_drop);
SCL_check_package(tdbb, name, SCL_drop);
}
void DropPackageNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
jrd_tra* transaction)
void DropPackageNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction)
{
MemoryPool& pool = dsqlScratch->getPool();
@ -587,22 +593,22 @@ void DropPackageNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
FOR (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction)
PKG IN RDB$PACKAGES
WITH PKG.RDB$PACKAGE_NAME EQ name.c_str()
WITH PKG.RDB$SCHEMA_NAME EQ name.schema.c_str() AND
PKG.RDB$PACKAGE_NAME EQ name.object.c_str()
{
found = true;
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE,
DDL_TRIGGER_DROP_PACKAGE, name, NULL);
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE, DDL_TRIGGER_DROP_PACKAGE, name, {});
ERASE PKG;
if (!PKG.RDB$SECURITY_CLASS.NULL)
deleteSecurityClass(tdbb, transaction, PKG.RDB$SECURITY_CLASS);
dsc desc;
desc.makeText(name.length(), ttype_metadata,
(UCHAR*) const_cast<char*>(name.c_str())); // safe const_cast
DFW_post_work(transaction, dfw_drop_package_header, &desc, 0);
dsc schemaDesc, nameDesc;
schemaDesc.makeText(name.schema.length(), ttype_metadata, (UCHAR*) const_cast<char*>(name.schema.c_str()));
nameDesc.makeText(name.object.length(), ttype_metadata, (UCHAR*) const_cast<char*>(name.object.c_str()));
DFW_post_work(transaction, dfw_drop_package_header, &nameDesc, &schemaDesc, 0);
}
END_FOR
@ -610,7 +616,7 @@ void DropPackageNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
{
status_exception::raise(
Arg::Gds(isc_no_meta_update) <<
Arg::Gds(isc_dyn_package_not_found) << Arg::Str(name));
Arg::Gds(isc_dyn_package_not_found) << name.toQuotedString());
}
SortedObjectsArray<Signature> existingFuncs(pool);
@ -620,8 +626,7 @@ void DropPackageNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
for (SortedObjectsArray<Signature>::iterator i = existingFuncs.begin();
i != existingFuncs.end(); ++i)
{
DropFunctionNode dropNode(pool, i->name);
dropNode.package = name;
DropFunctionNode dropNode(pool, QualifiedName(i->name, name.schema, name.object));
dropNode.dsqlPass(dsqlScratch);
dropNode.executeDdl(tdbb, dsqlScratch, transaction, true);
}
@ -629,8 +634,7 @@ void DropPackageNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
for (SortedObjectsArray<Signature>::iterator i = existingProcs.begin();
i != existingProcs.end(); ++i)
{
DropProcedureNode dropNode(pool, i->name);
dropNode.package = name;
DropProcedureNode dropNode(pool, QualifiedName(i->name, name.schema, name.object));
dropNode.dsqlPass(dsqlScratch);
dropNode.executeDdl(tdbb, dsqlScratch, transaction, true);
}
@ -639,9 +643,12 @@ void DropPackageNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
FOR (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction)
PRIV IN RDB$USER_PRIVILEGES
WITH ((PRIV.RDB$RELATION_NAME EQ name.c_str() AND
PRIV.RDB$OBJECT_TYPE = obj_package_header) OR
(PRIV.RDB$USER EQ name.c_str() AND PRIV.RDB$USER_TYPE = obj_package_header)) AND
WITH ((PRIV.RDB$RELATION_SCHEMA_NAME EQ name.schema.c_str() AND
PRIV.RDB$RELATION_NAME EQ name.object.c_str() AND
PRIV.RDB$OBJECT_TYPE = obj_package_header) OR
(PRIV.RDB$USER_SCHEMA_NAME EQ name.schema.c_str() AND
PRIV.RDB$USER EQ name.object.c_str() AND
PRIV.RDB$USER_TYPE = obj_package_header)) AND
PRIV.RDB$GRANTOR NOT MISSING
{
ERASE PRIV;
@ -649,10 +656,7 @@ void DropPackageNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
END_FOR
if (found)
{
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER, DDL_TRIGGER_DROP_PACKAGE,
name, NULL);
}
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER, DDL_TRIGGER_DROP_PACKAGE, name, {});
savePoint.release(); // everything is ok
}
@ -676,6 +680,10 @@ string CreatePackageBodyNode::internalPrint(NodePrinter& printer) const
DdlNode* CreatePackageBodyNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
{
dsqlScratch->qualifyExistingName(name, obj_package_header);
protectSystemSchema(name.schema, obj_package_header);
dsqlScratch->ddlSchema = name.schema;
MemoryPool& pool = dsqlScratch->getPool();
source.ltrim("\n\r\t ");
@ -701,17 +709,18 @@ DdlNode* CreatePackageBodyNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
CreateAlterFunctionNode* const fun = (*arrays[i])[j].function;
ddlNode = fun;
if (functionNames[i].exist(fun->name))
if (functionNames[i].exist(fun->name.object))
{
status_exception::raise(
Arg::Gds(isc_no_meta_update) <<
Arg::Gds(isc_dyn_duplicate_package_item) <<
Arg::Str("FUNCTION") << Arg::Str(fun->name));
Arg::Str("FUNCTION") << fun->name.object);
}
functionNames[i].add(fun->name);
functionNames[i].add(fun->name.object);
fun->package = name;
fun->name.schema = name.schema;
fun->name.package = name.object;
fun->create = true;
if (arrays[i] == items)
@ -725,17 +734,18 @@ DdlNode* CreatePackageBodyNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
CreateAlterProcedureNode* const proc = (*arrays[i])[j].procedure;
ddlNode = proc;
if (procedureNames[i].exist(proc->name))
if (procedureNames[i].exist(proc->name.object))
{
status_exception::raise(
Arg::Gds(isc_no_meta_update) <<
Arg::Gds(isc_dyn_duplicate_package_item) <<
Arg::Str("PROCEDURE") << Arg::Str(proc->name));
Arg::Str("PROCEDURE") << proc->name.object);
}
procedureNames[i].add(proc->name);
procedureNames[i].add(proc->name.object);
proc->package = name;
proc->name.schema = name.schema;
proc->name.package = name.object;
proc->create = true;
if (arrays[i] == items)
@ -754,6 +764,7 @@ DdlNode* CreatePackageBodyNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
FB_NEW_POOL(pool) DsqlCompilerScratch(pool, dsqlScratch->getAttachment(),
dsqlScratch->getTransaction(), itemStatement);
itemScratch->ddlSchema = name.schema;
itemScratch->clientDialect = dsqlScratch->clientDialect;
itemScratch->flags |= DsqlCompilerScratch::FLAG_DDL;
itemScratch->package = name;
@ -773,12 +784,11 @@ DdlNode* CreatePackageBodyNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
void CreatePackageBodyNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
{
SCL_check_create_access(tdbb, obj_packages);
SCL_check_create_access(tdbb, obj_packages, name.schema);
}
void CreatePackageBodyNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
jrd_tra* transaction)
void CreatePackageBodyNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction)
{
MemoryPool& pool = dsqlScratch->getPool();
Attachment* attachment = transaction->getAttachment();
@ -791,7 +801,8 @@ void CreatePackageBodyNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlSc
FOR (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction)
PKG IN RDB$PACKAGES
WITH PKG.RDB$PACKAGE_NAME EQ name.c_str()
WITH PKG.RDB$SCHEMA_NAME EQ name.schema.c_str() AND
PKG.RDB$PACKAGE_NAME EQ name.object.c_str()
{
if (!PKG.RDB$VALID_BODY_FLAG.NULL && PKG.RDB$VALID_BODY_FLAG != 0)
{
@ -800,11 +811,10 @@ void CreatePackageBodyNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlSc
status_exception::raise(
Arg::Gds(isc_no_meta_update) <<
Arg::Gds(isc_dyn_package_body_exists) << Arg::Str(name));
Arg::Gds(isc_dyn_package_body_exists) << name.toQuotedString());
}
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE,
DDL_TRIGGER_CREATE_PACKAGE_BODY, name, NULL);
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE, DDL_TRIGGER_CREATE_PACKAGE_BODY, name, {});
MODIFY PKG
PKG.RDB$VALID_BODY_FLAG.NULL = FALSE;
@ -824,7 +834,7 @@ void CreatePackageBodyNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlSc
{
status_exception::raise(
Arg::Gds(isc_no_meta_update) <<
Arg::Gds(isc_dyn_package_not_found) << Arg::Str(name));
Arg::Gds(isc_dyn_package_not_found) << name.toQuotedString());
}
SortedObjectsArray<Signature> headerFuncs(pool);
@ -861,18 +871,18 @@ void CreatePackageBodyNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlSc
CreateAlterFunctionNode* func = elem.function;
if (arrays[i] == items)
func->privateScope = !headerFuncs.exist(Signature(func->name));
else if (existingFuncs.exist(Signature(func->name)))
func->privateScope = !headerFuncs.exist(Signature(func->name.object));
else if (existingFuncs.exist(Signature(func->name.object)))
{
status_exception::raise(
Arg::Gds(isc_no_meta_update) <<
Arg::Gds(isc_dyn_duplicate_package_item) <<
Arg::Str("FUNCTION") << Arg::Str(func->name));
Arg::Str("FUNCTION") << func->name.toQuotedString());
}
func->packageOwner = owner;
func->preserveDefaults =
existingFuncs.exist(Signature(func->name)) && arrays[i] == items;
existingFuncs.exist(Signature(func->name.object)) && arrays[i] == items;
func->executeDdl(tdbb, elem.dsqlScratch, transaction, true);
break;
}
@ -882,18 +892,18 @@ void CreatePackageBodyNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlSc
CreateAlterProcedureNode* proc = elem.procedure;
if (arrays[i] == items)
proc->privateScope = !headerProcs.exist(Signature(proc->name));
else if (existingProcs.exist(Signature(proc->name)))
proc->privateScope = !headerProcs.exist(Signature(proc->name.object));
else if (existingProcs.exist(Signature(proc->name.object)))
{
status_exception::raise(
Arg::Gds(isc_no_meta_update) <<
Arg::Gds(isc_dyn_duplicate_package_item) <<
Arg::Str("PROCEDURE") << Arg::Str(proc->name));
Arg::Str("PROCEDURE") << proc->name.toQuotedString());
}
proc->packageOwner = owner;
proc->preserveDefaults =
existingProcs.exist(Signature(proc->name)) && arrays[i] == items;
existingProcs.exist(Signature(proc->name.object)) && arrays[i] == items;
proc->executeDdl(tdbb, elem.dsqlScratch, transaction, true);
break;
}
@ -914,12 +924,12 @@ void CreatePackageBodyNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlSc
if (!found || !newFuncs[pos].defined)
{
status_exception::raise(
Arg::Gds(isc_dyn_funcnotdef_package) << i->name.c_str() << name.c_str());
Arg::Gds(isc_dyn_funcnotdef_package) << i->name << name.toQuotedString());
}
else if (newFuncs[pos] != *i)
{
status_exception::raise(
Arg::Gds(isc_dyn_funcsignat_package) << i->name.c_str() << name.c_str());
Arg::Gds(isc_dyn_funcsignat_package) << i->name << name.toQuotedString());
}
}
@ -932,17 +942,16 @@ void CreatePackageBodyNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlSc
if (!found || !newProcs[pos].defined)
{
status_exception::raise(
Arg::Gds(isc_dyn_procnotdef_package) << i->name.c_str() << name.c_str());
Arg::Gds(isc_dyn_procnotdef_package) << i->name << name.toQuotedString());
}
else if (newProcs[pos] != *i)
{
status_exception::raise(
Arg::Gds(isc_dyn_procsignat_package) << i->name.c_str() << name.c_str());
Arg::Gds(isc_dyn_procsignat_package) << i->name << name.toQuotedString());
}
}
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER,
DDL_TRIGGER_CREATE_PACKAGE_BODY, name, NULL);
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER, DDL_TRIGGER_CREATE_PACKAGE_BODY, name, {});
savePoint.release(); // everything is ok
}
@ -964,9 +973,7 @@ string DropPackageBodyNode::internalPrint(NodePrinter& printer) const
void DropPackageBodyNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
{
dsc dscName;
dscName.makeText(name.length(), CS_METADATA, (UCHAR*) name.c_str());
SCL_check_package(tdbb, &dscName, SCL_drop);
SCL_check_package(tdbb, name, SCL_drop);
}
@ -983,21 +990,21 @@ void DropPackageBodyNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScra
FOR (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction)
PKG IN RDB$PACKAGES
WITH PKG.RDB$PACKAGE_NAME EQ name.c_str()
WITH PKG.RDB$SCHEMA_NAME EQ name.schema.c_str() AND
PKG.RDB$PACKAGE_NAME EQ name.object.c_str()
{
found = true;
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE,
DDL_TRIGGER_DROP_PACKAGE_BODY, name, NULL);
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE, DDL_TRIGGER_DROP_PACKAGE_BODY, name, {});
MODIFY PKG
PKG.RDB$VALID_BODY_FLAG.NULL = TRUE;
PKG.RDB$PACKAGE_BODY_SOURCE.NULL = TRUE;
dsc desc;
desc.makeText(name.length(), ttype_metadata,
(UCHAR*) const_cast<char*>(name.c_str())); // safe const_cast
DFW_post_work(transaction, dfw_drop_package_body, &desc, 0);
dsc schemaDesc, nameDesc;
schemaDesc.makeText(name.schema.length(), ttype_metadata, (UCHAR*) const_cast<char*>(name.schema.c_str()));
nameDesc.makeText(name.object.length(), ttype_metadata, (UCHAR*) const_cast<char*>(name.object.c_str()));
DFW_post_work(transaction, dfw_drop_package_body, &nameDesc, &schemaDesc, 0);
END_MODIFY
}
END_FOR
@ -1012,19 +1019,19 @@ void DropPackageBodyNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScra
status_exception::raise(
Arg::Gds(isc_no_meta_update) <<
Arg::Gds(isc_dyn_package_not_found) << Arg::Str(name));
Arg::Gds(isc_dyn_package_not_found) << name.toQuotedString());
}
requestHandle.reset(tdbb, drq_m_pkg_fun, DYN_REQUESTS);
FOR (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction)
FUN IN RDB$FUNCTIONS
WITH FUN.RDB$PACKAGE_NAME EQ name.c_str()
WITH FUN.RDB$SCHEMA_NAME EQ name.schema.c_str() AND
FUN.RDB$PACKAGE_NAME EQ name.object.c_str()
{
if (!FUN.RDB$PRIVATE_FLAG.NULL && FUN.RDB$PRIVATE_FLAG != 0)
{
DropFunctionNode dropNode(pool, FUN.RDB$FUNCTION_NAME);
dropNode.package = name;
DropFunctionNode dropNode(pool, QualifiedName(FUN.RDB$FUNCTION_NAME, name.schema, name.object));
dropNode.dsqlPass(dsqlScratch);
dropNode.executeDdl(tdbb, dsqlScratch, transaction, true);
}
@ -1046,12 +1053,12 @@ void DropPackageBodyNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScra
FOR (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction)
PRC IN RDB$PROCEDURES
WITH PRC.RDB$PACKAGE_NAME EQ name.c_str()
WITH PRC.RDB$SCHEMA_NAME EQ name.schema.c_str() AND
PRC.RDB$PACKAGE_NAME EQ name.object.c_str()
{
if (!PRC.RDB$PRIVATE_FLAG.NULL && PRC.RDB$PRIVATE_FLAG != 0)
{
DropProcedureNode dropNode(pool, PRC.RDB$PROCEDURE_NAME);
dropNode.package = name;
DropProcedureNode dropNode(pool, QualifiedName(PRC.RDB$PROCEDURE_NAME, name.schema, name.object));
dropNode.dsqlPass(dsqlScratch);
dropNode.executeDdl(tdbb, dsqlScratch, transaction, true);
}
@ -1068,8 +1075,7 @@ void DropPackageBodyNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScra
}
END_FOR
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER,
DDL_TRIGGER_DROP_PACKAGE_BODY, name, NULL);
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER, DDL_TRIGGER_DROP_PACKAGE_BODY, name, {});
savePoint.release(); // everything is ok
}

View File

@ -68,7 +68,7 @@ public:
};
public:
CreateAlterPackageNode(MemoryPool& pool, const MetaName& aName)
CreateAlterPackageNode(MemoryPool& pool, const QualifiedName& aName)
: DdlNode(pool),
name(pool, aName),
create(true),
@ -94,7 +94,7 @@ protected:
Firebird::Arg::Gds(createAlterCode(create, alter,
isc_dsql_create_pack_failed, isc_dsql_alter_pack_failed,
isc_dsql_create_alter_pack_failed)) <<
name;
name.toQuotedString();
}
private:
@ -104,7 +104,7 @@ private:
void executeItems(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction);
public:
MetaName name;
QualifiedName name;
bool create;
bool alter;
bool createIfNotExistsOnly = false;
@ -122,7 +122,7 @@ private:
class DropPackageNode : public DdlNode
{
public:
DropPackageNode(MemoryPool& pool, const MetaName& aName)
DropPackageNode(MemoryPool& pool, const QualifiedName& aName)
: DdlNode(pool),
name(pool, aName),
silent(false)
@ -134,15 +134,29 @@ public:
virtual void checkPermission(thread_db* tdbb, jrd_tra* transaction);
virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction);
virtual DdlNode* dsqlPass(DsqlCompilerScratch* dsqlScratch)
{
if (recreate)
dsqlScratch->qualifyNewName(name);
else
dsqlScratch->qualifyExistingName(name, obj_package_header);
protectSystemSchema(name.schema, obj_package_header);
dsqlScratch->ddlSchema = name.schema;
return DdlNode::dsqlPass(dsqlScratch);
}
protected:
virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector)
{
statusVector << Firebird::Arg::Gds(isc_dsql_drop_pack_failed) << name;
statusVector << Firebird::Arg::Gds(isc_dsql_drop_pack_failed) << name.toQuotedString();
}
public:
MetaName name;
QualifiedName name;
bool silent;
bool recreate = false;
};
@ -153,7 +167,7 @@ typedef RecreateNode<CreateAlterPackageNode, DropPackageNode, isc_dsql_recreate_
class CreatePackageBodyNode : public DdlNode
{
public:
CreatePackageBodyNode(MemoryPool& pool, const MetaName& aName)
CreatePackageBodyNode(MemoryPool& pool, const QualifiedName& aName)
: DdlNode(pool),
name(pool, aName),
source(pool),
@ -172,11 +186,11 @@ public:
protected:
virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector)
{
statusVector << Firebird::Arg::Gds(isc_dsql_create_pack_body_failed) << name;
statusVector << Firebird::Arg::Gds(isc_dsql_create_pack_body_failed) << name.toQuotedString();
}
public:
MetaName name;
QualifiedName name;
Firebird::string source;
Firebird::Array<CreateAlterPackageNode::Item>* declaredItems;
Firebird::Array<CreateAlterPackageNode::Item>* items;
@ -190,7 +204,7 @@ private:
class DropPackageBodyNode : public DdlNode
{
public:
DropPackageBodyNode(MemoryPool& pool, const MetaName& aName)
DropPackageBodyNode(MemoryPool& pool, const QualifiedName& aName)
: DdlNode(pool),
name(pool, aName),
silent(false)
@ -202,15 +216,25 @@ public:
virtual void checkPermission(thread_db* tdbb, jrd_tra* transaction);
virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction);
virtual DdlNode* dsqlPass(DsqlCompilerScratch* dsqlScratch)
{
dsqlScratch->qualifyExistingName(name, obj_package_header);
protectSystemSchema(name.schema, obj_package_header);
dsqlScratch->ddlSchema = name.schema;
return DdlNode::dsqlPass(dsqlScratch);
}
protected:
virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector)
{
statusVector << Firebird::Arg::Gds(isc_dsql_drop_pack_body_failed) << name;
statusVector << Firebird::Arg::Gds(isc_dsql_drop_pack_body_failed) << name.toQuotedString();
}
public:
MetaName name;
QualifiedName name;
bool silent; // Unused. Just to please RecreateNode template.
bool recreate = false;
};

View File

@ -408,28 +408,13 @@ int Parser::yylexAux()
if (tok_class & CHR_INTRODUCER)
{
// The Introducer (_) is skipped, all other idents are copied
// to become the name of the character set.
char* p = string;
for (; lex.ptr < lex.end && (classes(*lex.ptr) & CHR_IDENT); lex.ptr++)
{
if (lex.ptr >= lex.end)
return -1;
if (lex.ptr >= lex.end)
return -1;
check_copy_incr(p, UPPER7(*lex.ptr), string);
}
if (classes(*lex.ptr) & (CHR_IDENT | CHR_QUOTE))
return TOK_INTRODUCER;
check_bound(p, string);
if (p > string + MAX_SQL_IDENTIFIER_LEN || p > string + METADATA_IDENTIFIER_CHAR_LEN)
yyabandon(yyposn, -104, isc_dyn_name_longer);
*p = 0;
// make a string value to hold the name, the name is resolved in pass1_constant.
yylval.metaNamePtr = FB_NEW_POOL(pool) MetaName(pool, string, p - string);
return TOK_INTRODUCER;
return (UCHAR) c;
}
// parse a quoted string, being sure to look for double quotes
@ -711,15 +696,14 @@ int Parser::yylexAux()
if (introducerCharSetName)
{
const auto symbol = METD_get_charset(scratch->getTransaction(),
introducerCharSetName->length(), introducerCharSetName->c_str());
const auto symbol = METD_get_charset(scratch->getTransaction(), *introducerCharSetName);
if (!symbol)
{
// character set name is not defined
ERRD_post(
Arg::Gds(isc_sqlerr) << Arg::Num(-504) <<
Arg::Gds(isc_charset_not_found) << *introducerCharSetName);
Arg::Gds(isc_charset_not_found) << introducerCharSetName->toQuotedString());
}
currentCharSet = INTL_charset_lookup(tdbb, symbol->intlsym_ttype);

View File

@ -225,6 +225,11 @@ private:
return (name ? *name : MetaName());
}
QualifiedName optName(QualifiedName* name)
{
return (name ? *name : QualifiedName());
}
void transformString(const char* start, unsigned length, Firebird::string& dest);
Firebird::string makeParseStr(const Position& p1, const Position& p2);
ParameterNode* make_parameter();
@ -323,6 +328,11 @@ private:
return clause.hasData();
}
bool isDuplicateClause(const QualifiedName& clause)
{
return clause.object.hasData();
}
bool isDuplicateClause(const Firebird::TriState& clause)
{
return clause.isAssigned();
@ -340,7 +350,7 @@ private:
return clause.hasData();
}
void setCollate(TypeClause* fld, MetaName* name)
void setCollate(TypeClause* fld, QualifiedName* name)
{
if (name)
setClause(fld->collate, "COLLATE", *name);
@ -380,7 +390,7 @@ private:
DsqlStatement* parsedStatement;
// Parser feedback for lexer
MetaName* introducerCharSetName = nullptr;
QualifiedName* introducerCharSetName = nullptr;
// These value/posn are taken from the lexer
YYSTYPE yylval;

File diff suppressed because it is too large Load Diff

View File

@ -97,11 +97,8 @@ public:
public:
Type type;
SLONG code;
// ASF: There are some inconsistencies in the type of 'name'. Metanames have maximum of 31 chars,
// while there are system exceptions with 32 chars. The parser always expects metanames, but
// I'm following the legacy code and making this a string.
Firebird::string name;
MetaName secName;
QualifiedName name;
QualifiedName secName;
};
typedef Firebird::ObjectsArray<ExceptionItem> ExceptionArray;
@ -589,7 +586,7 @@ class ExecProcedureNode final : public TypedNode<StmtNode, StmtNode::TYPE_EXEC_P
{
public:
explicit ExecProcedureNode(MemoryPool& pool,
const QualifiedName& aDsqlName = QualifiedName(),
const QualifiedName& aDsqlName = {},
ValueListNode* aInputs = nullptr, ValueListNode* aOutputs = nullptr,
Firebird::ObjectsArray<MetaName>* aDsqlInputArgNames = nullptr)
: TypedNode<StmtNode, StmtNode::TYPE_EXEC_PROCEDURE>(pool),
@ -802,7 +799,7 @@ public:
class ExceptionNode final : public TypedNode<StmtNode, StmtNode::TYPE_EXCEPTION>
{
public:
ExceptionNode(MemoryPool& pool, const MetaName& name,
ExceptionNode(MemoryPool& pool, const QualifiedName& name,
ValueExprNode* aMessageExpr = NULL, ValueListNode* aParameters = NULL)
: TypedNode<StmtNode, StmtNode::TYPE_EXCEPTION>(pool),
messageExpr(aMessageExpr),
@ -810,7 +807,7 @@ public:
{
exception = FB_NEW_POOL(pool) ExceptionItem(pool);
exception->type = ExceptionItem::XCP_CODE;
exception->name = name.c_str();
exception->name = name;
}
explicit ExceptionNode(MemoryPool& pool)
@ -1386,7 +1383,7 @@ public:
class SetGeneratorNode final : public TypedNode<StmtNode, StmtNode::TYPE_SET_GENERATOR>
{
public:
SetGeneratorNode(MemoryPool& pool, const MetaName& name, ValueExprNode* aValue = NULL)
SetGeneratorNode(MemoryPool& pool, const QualifiedName& name, ValueExprNode* aValue = NULL)
: TypedNode<StmtNode, StmtNode::TYPE_SET_GENERATOR>(pool),
generator(pool, name), value(aValue)
{
@ -1561,7 +1558,7 @@ class SetTransactionNode : public TransactionNode
public:
struct RestrictionOption : Firebird::PermanentStorage
{
RestrictionOption(MemoryPool& p, Firebird::ObjectsArray<MetaName>* aTables,
RestrictionOption(MemoryPool& p, Firebird::ObjectsArray<QualifiedName>* aTables,
unsigned aLockMode)
: PermanentStorage(p),
tables(aTables),
@ -1569,7 +1566,7 @@ public:
{
}
Firebird::ObjectsArray<MetaName>* tables;
Firebird::ObjectsArray<QualifiedName>* tables;
unsigned lockMode;
};
@ -1908,6 +1905,32 @@ public:
};
class SetSearchPathNode : public SessionManagementNode
{
public:
SetSearchPathNode(MemoryPool& pool, Firebird::ObjectsArray<MetaName>* aSchemas)
: SessionManagementNode(pool),
schemas(aSchemas)
{
}
public:
virtual Firebird::string internalPrint(NodePrinter& printer) const
{
SessionManagementNode::internalPrint(printer);
NODE_PRINT(printer, schemas);
return "SetSearchPathNode";
}
virtual void execute(thread_db* tdbb, DsqlRequest* request, jrd_tra** traHandle) const;
public:
NestConst<Firebird::ObjectsArray<MetaName>> schemas;
};
class SetTimeZoneNode : public SessionManagementNode
{
public:

View File

@ -125,7 +125,7 @@ bool DDL_ids(const DsqlCompilerScratch* scratch)
void DDL_resolve_intl_type(DsqlCompilerScratch* dsqlScratch, dsql_fld* field,
const MetaName& collation_name, bool modifying)
QualifiedName& collation_name, bool modifying)
{
/**************************************
*
@ -152,17 +152,18 @@ void DDL_resolve_intl_type(DsqlCompilerScratch* dsqlScratch, dsql_fld* field,
*
**************************************/
if (field->typeOfName.hasData())
if (field->typeOfName.object.hasData())
{
if (field->typeOfTable.hasData())
if (field->typeOfTable.object.hasData())
{
dsql_rel* relation = METD_get_relation(dsqlScratch->getTransaction(), dsqlScratch,
field->typeOfTable.c_str());
dsqlScratch->qualifyExistingName(field->typeOfTable, obj_relation);
dsql_rel* relation = METD_get_relation(dsqlScratch->getTransaction(), dsqlScratch, field->typeOfTable);
const dsql_fld* fld = NULL;
if (relation)
{
const MetaName fieldName(field->typeOfName);
const MetaName fieldName(field->typeOfName.object);
for (fld = relation->rel_fields; fld; fld = fld->fld_next)
{
@ -188,16 +189,18 @@ void DDL_resolve_intl_type(DsqlCompilerScratch* dsqlScratch, dsql_fld* field,
{
// column @1 does not exist in table/view @2
post_607(Arg::Gds(isc_dyn_column_does_not_exist) <<
Arg::Str(field->typeOfName) <<
field->typeOfTable);
field->typeOfName.toQuotedString() <<
field->typeOfTable.toQuotedString());
}
}
else
{
dsqlScratch->qualifyExistingName(field->typeOfName, obj_field);
if (!METD_get_domain(dsqlScratch->getTransaction(), field, field->typeOfName))
{
// Specified domain or source field does not exist
post_607(Arg::Gds(isc_dsql_domain_not_found) << Arg::Str(field->typeOfName));
post_607(Arg::Gds(isc_dsql_domain_not_found) << field->typeOfName.toQuotedString());
}
}
@ -217,7 +220,7 @@ void DDL_resolve_intl_type(DsqlCompilerScratch* dsqlScratch, dsql_fld* field,
if ((field->dtype > dtype_any_text) && field->dtype != dtype_blob)
{
if (field->charSet.hasData() || collation_name.hasData() || (field->flags & FLD_national))
if (field->charSet.object.hasData() || collation_name.object.hasData() || (field->flags & FLD_national))
{
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-204) <<
Arg::Gds(isc_dsql_datatype_err) << Arg::Gds(isc_collation_requires_text));
@ -236,7 +239,7 @@ void DDL_resolve_intl_type(DsqlCompilerScratch* dsqlScratch, dsql_fld* field,
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-204) <<
Arg::Gds(isc_dsql_datatype_err) <<
Arg::Gds(isc_dsql_blob_type_unknown) <<
Arg::Str(field->subTypeName));
field->subTypeName);
}
field->subType = blob_sub_type;
}
@ -248,17 +251,17 @@ void DDL_resolve_intl_type(DsqlCompilerScratch* dsqlScratch, dsql_fld* field,
Arg::Gds(isc_subtype_for_internal_use));
}
if (field->charSet.hasData() && (field->subType == isc_blob_untyped))
if (field->charSet.object.hasData() && (field->subType == isc_blob_untyped))
field->subType = isc_blob_text;
if (field->charSet.hasData() && (field->subType != isc_blob_text))
if (field->charSet.object.hasData() && (field->subType != isc_blob_text))
{
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-204) <<
Arg::Gds(isc_dsql_datatype_err) <<
Arg::Gds(isc_collation_requires_text));
}
if (collation_name.hasData() && (field->subType != isc_blob_text))
if (collation_name.object.hasData() && (field->subType != isc_blob_text))
{
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-204) <<
Arg::Gds(isc_dsql_datatype_err) <<
@ -269,14 +272,14 @@ void DDL_resolve_intl_type(DsqlCompilerScratch* dsqlScratch, dsql_fld* field,
return;
}
if (field->charSetId.has_value() && collation_name.isEmpty())
if (field->charSetId.has_value() && collation_name.object.isEmpty())
{
// This field has already been resolved once, and the collation
// hasn't changed. Therefore, no need to do it again.
return;
}
if (modifying && field->charSet.isEmpty() && field->collate.isEmpty())
if (modifying && field->charSet.object.isEmpty() && field->collate.object.isEmpty())
{
// Use charset and collation from already existing field if any
const dsql_fld* afield = field->fld_next;
@ -311,15 +314,17 @@ void DDL_resolve_intl_type(DsqlCompilerScratch* dsqlScratch, dsql_fld* field,
}
}
if (!modifying && !(field->charSet.hasData() || field->charSetId.has_value() || // set if a domain
if (!modifying && !(field->charSet.object.hasData() || field->charSetId.has_value() || // set if a domain
(field->flags & FLD_national)))
{
// Attach the database default character set to the new field, if not otherwise specified
MetaName defaultCharSet;
QualifiedName defaultCharSet;
if (dsqlScratch->flags & DsqlCompilerScratch::FLAG_DDL)
defaultCharSet = METD_get_default_charset(dsqlScratch->getTransaction());
if (dsqlScratch->ddlSchema.hasData())
defaultCharSet = METD_get_schema_charset(dsqlScratch->getTransaction(), dsqlScratch->ddlSchema);
else if (dsqlScratch->flags & DsqlCompilerScratch::FLAG_DDL)
defaultCharSet = METD_get_database_charset(dsqlScratch->getTransaction());
else
{
USHORT charSet = dsqlScratch->getAttachment()->dbb_attachment->att_charset;
@ -327,7 +332,7 @@ void DDL_resolve_intl_type(DsqlCompilerScratch* dsqlScratch, dsql_fld* field,
defaultCharSet = METD_get_charset_name(dsqlScratch->getTransaction(), charSet);
}
if (defaultCharSet.hasData())
if (defaultCharSet.object.hasData())
field->charSet = defaultCharSet;
else
{
@ -336,25 +341,27 @@ void DDL_resolve_intl_type(DsqlCompilerScratch* dsqlScratch, dsql_fld* field,
assign_field_length(field, 1);
field->textType = 0;
if (collation_name.isEmpty())
if (collation_name.object.isEmpty())
return;
}
}
MetaName charset_name;
QualifiedName charset_name;
if (field->flags & FLD_national)
charset_name = NATIONAL_CHARACTER_SET;
else if (field->charSet.hasData())
charset_name = QualifiedName(NATIONAL_CHARACTER_SET, SYSTEM_SCHEMA);
else if (field->charSet.object.hasData())
{
dsqlScratch->qualifyExistingName(field->charSet, obj_charset);
charset_name = field->charSet;
}
// Find an intlsym for any specified character set name & collation name
const dsql_intlsym* resolved_type = NULL;
if (charset_name.hasData())
if (charset_name.object.hasData())
{
const dsql_intlsym* resolved_charset =
METD_get_charset(dsqlScratch->getTransaction(), (USHORT) charset_name.length(), charset_name.c_str());
const dsql_intlsym* resolved_charset = METD_get_charset(dsqlScratch->getTransaction(), charset_name);
// Error code -204 (IBM's DB2 manual) is close enough
if (!resolved_charset)
@ -362,23 +369,25 @@ void DDL_resolve_intl_type(DsqlCompilerScratch* dsqlScratch, dsql_fld* field,
// specified character set not found
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-204) <<
Arg::Gds(isc_dsql_datatype_err) <<
Arg::Gds(isc_charset_not_found) << Arg::Str(charset_name));
Arg::Gds(isc_charset_not_found) << charset_name.toQuotedString());
}
field->charSetId = resolved_charset->intlsym_charset_id;
resolved_type = resolved_charset;
}
if (collation_name.hasData())
if (collation_name.object.hasData())
{
dsqlScratch->qualifyExistingName(collation_name, obj_collation);
const dsql_intlsym* resolved_collation = METD_get_collation(dsqlScratch->getTransaction(),
collation_name, field->charSetId.value_or(CS_NONE));
if (!resolved_collation)
{
MetaName charSetName;
QualifiedName charSetName;
if (charset_name.hasData())
if (charset_name.object.hasData())
charSetName = charset_name;
else
{
@ -389,7 +398,7 @@ void DDL_resolve_intl_type(DsqlCompilerScratch* dsqlScratch, dsql_fld* field,
// Specified collation not found
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-204) <<
///Arg::Gds(isc_dsql_datatype_err) << // (too large status vector)
Arg::Gds(isc_collation_not_found) << collation_name << charSetName);
Arg::Gds(isc_collation_not_found) << collation_name.toQuotedString() << charSetName.toQuotedString());
}
// If both specified, must be for same character set
@ -402,7 +411,7 @@ void DDL_resolve_intl_type(DsqlCompilerScratch* dsqlScratch, dsql_fld* field,
{
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-204) <<
Arg::Gds(isc_dsql_datatype_err) <<
Arg::Gds(isc_collation_not_for_charset) << collation_name);
Arg::Gds(isc_collation_not_for_charset) << collation_name.toQuotedString());
}
field->explicitCollation = true;

View File

@ -68,7 +68,7 @@ const USHORT blr_dtypes[] = {
};
bool DDL_ids(const Jrd::DsqlCompilerScratch*);
void DDL_resolve_intl_type(Jrd::DsqlCompilerScratch*, Jrd::dsql_fld*, const Jrd::MetaName&,
void DDL_resolve_intl_type(Jrd::DsqlCompilerScratch*, Jrd::dsql_fld*, Jrd::QualifiedName&,
bool = false);
#endif // DSQL_DDL_PROTO_H

View File

@ -121,6 +121,7 @@ dsql_dbb::dsql_dbb(MemoryPool& p, Attachment* attachment)
dbb_charsets_by_id(p),
dbb_cursors(p),
dbb_pool(p),
dbb_schemas_dfl_charset(p),
dbb_dfl_charset(p)
{
dbb_attachment = attachment;
@ -132,6 +133,13 @@ dsql_dbb::~dsql_dbb()
}
void dsql_fld::resolve(DsqlCompilerScratch* dsqlScratch, bool modifying)
{
dsqlScratch->qualifyExistingName(collate, obj_collation);
DDL_resolve_intl_type(dsqlScratch, this, collate, modifying);
}
// Execute a dynamic SQL statement.
void DSQL_execute(thread_db* tdbb,
jrd_tra** tra_handle,
@ -711,15 +719,15 @@ string IntlString::toUtf8(jrd_tra* transaction) const
{
CHARSET_ID id = CS_dynamic;
if (charset.hasData())
if (charset.object.hasData())
{
const dsql_intlsym* resolved = METD_get_charset(transaction, charset.length(), charset.c_str());
const dsql_intlsym* resolved = METD_get_charset(transaction, charset);
if (!resolved)
{
// character set name is not defined
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-504) <<
Arg::Gds(isc_charset_not_found) << charset);
Arg::Gds(isc_charset_not_found) << charset.toQuotedString());
}
id = resolved->intlsym_charset_id;
@ -1190,6 +1198,7 @@ static UCHAR* var_info(const dsql_msg* message,
for (const UCHAR* describe = items; describe < end_describe;)
{
USHORT length;
string str;
MetaName name;
const UCHAR* buffer = buf;
UCHAR item = *describe++;
@ -1235,10 +1244,21 @@ static UCHAR* var_info(const dsql_msg* message,
length = 0;
break;
case isc_info_sql_relation:
if (param->par_rel_name.hasData())
case isc_info_sql_relation_schema:
if (param->par_rel_name.schema.hasData())
{
name = attachment->nameToUserCharSet(tdbb, param->par_rel_name);
name = attachment->nameToUserCharSet(tdbb, param->par_rel_name.schema);
length = name.length();
buffer = reinterpret_cast<const UCHAR*>(name.c_str());
}
else
length = 0;
break;
case isc_info_sql_relation:
if (param->par_rel_name.object.hasData())
{
name = attachment->nameToUserCharSet(tdbb, param->par_rel_name.object);
length = name.length();
buffer = reinterpret_cast<const UCHAR*>(name.c_str());
}
@ -1260,9 +1280,9 @@ static UCHAR* var_info(const dsql_msg* message,
case isc_info_sql_relation_alias:
if (param->par_rel_alias.hasData())
{
name = attachment->nameToUserCharSet(tdbb, param->par_rel_alias);
length = name.length();
buffer = reinterpret_cast<const UCHAR*>(name.c_str());
str = attachment->stringToUserCharSet(tdbb, param->par_rel_alias);
length = str.length();
buffer = reinterpret_cast<const UCHAR*>(str.c_str());
}
else
length = 0;

View File

@ -34,6 +34,7 @@
#ifndef DSQL_DSQL_H
#define DSQL_DSQL_H
#include <numeric>
#include "../common/classes/array.h"
#include "../common/classes/fb_atomic.h"
#include "../common/classes/GenericMap.h"
@ -116,18 +117,19 @@ namespace Jrd {
class dsql_dbb : public pool_alloc<dsql_type_dbb>
{
public:
Firebird::LeftPooledMap<MetaName, class dsql_rel*> dbb_relations; // known relations in database
Firebird::LeftPooledMap<QualifiedName, class dsql_rel*> dbb_relations; // known relations in database
Firebird::LeftPooledMap<QualifiedName, class dsql_prc*> dbb_procedures; // known procedures in database
Firebird::LeftPooledMap<QualifiedName, class dsql_udf*> dbb_functions; // known functions in database
Firebird::LeftPooledMap<MetaName, class dsql_intlsym*> dbb_charsets; // known charsets in database
Firebird::LeftPooledMap<MetaName, class dsql_intlsym*> dbb_collations; // known collations in database
Firebird::LeftPooledMap<QualifiedName, class dsql_intlsym*> dbb_charsets; // known charsets in database
Firebird::LeftPooledMap<QualifiedName, class dsql_intlsym*> dbb_collations; // known collations in database
Firebird::NonPooledMap<SSHORT, dsql_intlsym*> dbb_charsets_by_id; // charsets sorted by charset_id
Firebird::LeftPooledMap<Firebird::string, DsqlDmlRequest*> dbb_cursors; // known cursors in database
Firebird::AutoPtr<DsqlStatementCache> dbb_statement_cache;
MemoryPool& dbb_pool; // The current pool for the dbb
Attachment* dbb_attachment;
MetaName dbb_dfl_charset;
Firebird::FullPooledMap<MetaName, QualifiedName> dbb_schemas_dfl_charset;
QualifiedName dbb_dfl_charset;
bool dbb_no_charset;
dsql_dbb(MemoryPool& p, Attachment* attachment);
@ -156,7 +158,7 @@ public:
dsql_fld* rel_fields; // Field block
//dsql_rel* rel_base_relation; // base relation for an updatable view
MetaName rel_name; // Name of relation
QualifiedName rel_name; // Name of relation
MetaName rel_owner; // Owner of relation
USHORT rel_id; // Relation id
USHORT rel_dbkey_length;
@ -175,7 +177,7 @@ enum rel_flags_vals {
class TypeClause
{
public:
TypeClause(MemoryPool& pool, const MetaName& aCollate)
TypeClause(MemoryPool& pool, const QualifiedName& aCollate)
: fieldSource(pool),
typeOfTable(pool),
typeOfName(pool),
@ -231,11 +233,11 @@ public:
SSHORT textType = 0;
bool fullDomain = false; // Domain name without TYPE OF prefix
bool notNull = false; // NOT NULL was explicit specified
MetaName fieldSource;
MetaName typeOfTable; // TYPE OF table name
MetaName typeOfName; // TYPE OF
MetaName collate;
MetaName charSet; // empty means not specified
QualifiedName fieldSource;
QualifiedName typeOfTable; // TYPE OF table name
QualifiedName typeOfName; // TYPE OF
QualifiedName collate;
QualifiedName charSet; // empty means not specified
MetaName subTypeName; // Subtype name for later resolution
USHORT flags = 0;
USHORT elementDtype = 0; // Data type of array element
@ -249,16 +251,13 @@ class dsql_fld : public TypeClause
{
public:
explicit dsql_fld(MemoryPool& p)
: TypeClause(p, nullptr),
: TypeClause(p, {}),
fld_name(p)
{
}
public:
void resolve(DsqlCompilerScratch* dsqlScratch, bool modifying = false)
{
DDL_resolve_intl_type(dsqlScratch, this, collate, modifying);
}
void resolve(DsqlCompilerScratch* dsqlScratch, bool modifying = false);
public:
dsql_fld* fld_next = nullptr; // Next field in relation
@ -297,7 +296,7 @@ public:
dsql_fld* prc_inputs = nullptr; // Input parameters
dsql_fld* prc_outputs = nullptr; // Output parameters
QualifiedName prc_name; // Name of procedure
QualifiedName prc_name; // Name of procedure
MetaName prc_owner; // Owner of procedure
SSHORT prc_in_count = 0;
SSHORT prc_def_count = 0; // number of inputs with default values
@ -401,7 +400,7 @@ public:
{
}
MetaName intlsym_name;
QualifiedName intlsym_name;
USHORT intlsym_type = 0; // what type of name
USHORT intlsym_flags = 0;
SSHORT intlsym_ttype = 0; // id of implementation
@ -463,8 +462,8 @@ public:
USHORT ctx_scope_level = 0; // Subquery level within this request
USHORT ctx_flags = 0; // Various flag values
USHORT ctx_in_outer_join = 0; // inOuterJoin when context was created
Firebird::string ctx_alias; // Context alias (can include concatenated derived table alias)
Firebird::string ctx_internal_alias; // Alias as specified in query
Firebird::ObjectsArray<QualifiedName> ctx_alias; // Context alias (can include concatenated derived table alias)
QualifiedName ctx_internal_alias; // Alias as specified in query
DsqlContextStack ctx_main_derived_contexts; // contexts used for blr_derived_expr
DsqlContextStack ctx_childs_derived_table; // Childs derived table context
Firebird::LeftPooledMap<MetaName, ImplicitJoin*> ctx_imp_join; // Map of USING fieldname to ImplicitJoin
@ -497,12 +496,29 @@ public:
Firebird::string getObjectName() const
{
if (ctx_relation)
return ctx_relation->rel_name.c_str();
return ctx_relation->rel_name.toQuotedString();
if (ctx_procedure)
return ctx_procedure->prc_name.toString();
return ctx_procedure->prc_name.toQuotedString();
return "";
}
Firebird::string getConcatenatedAlias() const
{
if (ctx_alias.hasData())
{
return std::accumulate(
std::next(ctx_alias.begin()),
ctx_alias.end(),
ctx_alias[0].toQuotedString(),
[](const auto& a, const auto& b) {
return a + " " + b.toQuotedString();
}
);
}
return {};
}
bool getImplicitJoinField(const MetaName& name, NestConst<ValueExprNode>& node);
WindowMap* getWindowMap(DsqlCompilerScratch* dsqlScratch, WindowClause* windowNode);
};
@ -568,12 +584,12 @@ public:
dsql_par* par_null = nullptr; // Null parameter, if used
ValueExprNode* par_node = nullptr; // Associated value node, if any
dsql_ctx* par_context = nullptr; // Context for SELECT FOR UPDATE
MetaName par_dbkey_relname; // Context of internally requested dbkey
MetaName par_rec_version_relname; // Context of internally requested rec. version
QualifiedName par_dbkey_relname; // Context of internally requested dbkey
QualifiedName par_rec_version_relname; // Context of internally requested rec. version
MetaName par_name; // Parameter name, if any
MetaName par_rel_name; // Relation name, if any
QualifiedName par_rel_name; // Relation name, if any
MetaName par_owner_name; // Owner name, if any
MetaName par_rel_alias; // Relation alias, if any
Firebird::string par_rel_alias; // Relation alias, if any
MetaName par_alias; // Alias, if any
dsc par_desc; // Field data type
USHORT par_parameter = 0; // BLR parameter number
@ -605,7 +621,7 @@ public:
s(p, str)
{ }
explicit IntlString(const Firebird::string& str, const MetaName& cs = NULL)
explicit IntlString(const Firebird::string& str, const QualifiedName& cs = {})
: charset(cs),
s(str)
{ }
@ -622,12 +638,12 @@ public:
Firebird::string toUtf8(jrd_tra* transaction) const;
const MetaName& getCharSet() const
const QualifiedName& getCharSet() const
{
return charset;
}
void setCharSet(const MetaName& value)
void setCharSet(const QualifiedName& value)
{
charset = value;
}
@ -648,7 +664,7 @@ public:
}
private:
MetaName charset;
QualifiedName charset;
Firebird::string s;
};
@ -732,11 +748,11 @@ struct SignatureParameter
SSHORT type = 0;
SSHORT number = 0;
MetaName name;
MetaName fieldSource;
MetaName fieldName;
MetaName relationName;
MetaName charSetName;
MetaName collationName;
QualifiedName fieldSource;
QualifiedName fieldName;
QualifiedName relationName;
QualifiedName charSetName;
QualifiedName collationName;
MetaName subTypeName;
std::optional<SSHORT> collationId;
std::optional<SSHORT> nullFlag;
@ -763,8 +779,9 @@ struct SignatureParameter
number == o.number &&
name == o.name &&
(fieldSource == o.fieldSource ||
(fb_utils::implicit_domain(fieldSource.c_str()) &&
fb_utils::implicit_domain(o.fieldSource.c_str()))) &&
(fieldSource.schema == o.fieldSource.schema &&
fb_utils::implicit_domain(fieldSource.object.c_str()) &&
fb_utils::implicit_domain(o.fieldSource.object.c_str()))) &&
fieldName == o.fieldName &&
relationName == o.relationName &&
collationId == o.collationId &&

View File

@ -505,10 +505,21 @@ static void gen_plan(DsqlCompilerScratch* dsqlScratch, const PlanNode* planNode)
// now stuff the access method for this stream
ObjectsArray<PlanNode::AccessItem>::const_iterator idx_iter =
node->accessType->items.begin();
auto idx_iter = node->accessType->items.begin();
FB_SIZE_T idx_count = node->accessType->items.getCount();
const auto checkIndexSchema = [&]()
{
if (node->recordSourceNode &&
node->recordSourceNode->dsqlContext &&
node->recordSourceNode->dsqlContext->ctx_relation &&
idx_iter->indexName.schema.hasData() &&
idx_iter->indexName.schema != node->recordSourceNode->dsqlContext->ctx_relation->rel_name.schema)
{
ERRD_post(Arg::Gds(isc_index_unused) << idx_iter->indexName.toQuotedString());
}
};
switch (node->accessType->type)
{
case PlanNode::AccessType::TYPE_SEQUENTIAL:
@ -516,8 +527,9 @@ static void gen_plan(DsqlCompilerScratch* dsqlScratch, const PlanNode* planNode)
break;
case PlanNode::AccessType::TYPE_NAVIGATIONAL:
checkIndexSchema();
dsqlScratch->appendUChar(blr_navigational);
dsqlScratch->appendNullString(idx_iter->indexName.c_str());
dsqlScratch->appendNullString(idx_iter->indexName.object.c_str());
if (idx_count == 1)
break;
// dimitr: FALL INTO, if the plan item is ORDER ... INDEX (...)
@ -532,7 +544,10 @@ static void gen_plan(DsqlCompilerScratch* dsqlScratch, const PlanNode* planNode)
dsqlScratch->appendUChar(idx_count);
for (; idx_iter != node->accessType->items.end(); ++idx_iter)
dsqlScratch->appendNullString(idx_iter->indexName.c_str());
{
checkIndexSchema();
dsqlScratch->appendNullString(idx_iter->indexName.object.c_str());
}
break;
}

View File

@ -342,7 +342,7 @@ ValueExprNode* MAKE_constant(const char* str, dsql_constant_type numeric_flag, S
@param character_set
**/
LiteralNode* MAKE_str_constant(const IntlString* constant, SSHORT character_set)
LiteralNode* MAKE_str_constant(IntlString* constant, SSHORT character_set)
{
thread_db* tdbb = JRD_get_thread_data();
@ -495,9 +495,9 @@ dsql_par* MAKE_parameter(dsql_msg* message, bool sqlda_flag, bool null_flag,
message->msg_parameters.insert(0, parameter);
parameter->par_parameter = message->msg_parameter++;
parameter->par_rel_name = NULL;
parameter->par_rel_name.clear();
parameter->par_owner_name = NULL;
parameter->par_rel_alias = NULL;
parameter->par_rel_alias.clear();
if (node)
MAKE_parameter_names(parameter, node);

View File

@ -82,7 +82,7 @@ namespace Jrd {
Jrd::LiteralNode* MAKE_const_slong(SLONG);
Jrd::LiteralNode* MAKE_const_sint64(SINT64 value, SCHAR scale);
Jrd::ValueExprNode* MAKE_constant(const char*, Jrd::dsql_constant_type, SSHORT = 0);
Jrd::LiteralNode* MAKE_str_constant(const Jrd::IntlString*, SSHORT);
Jrd::LiteralNode* MAKE_str_constant(Jrd::IntlString*, SSHORT);
Jrd::FieldNode* MAKE_field(Jrd::dsql_ctx*, Jrd::dsql_fld*, Jrd::ValueListNode*);
Jrd::FieldNode* MAKE_field_name(const char*);
Jrd::dsql_par* MAKE_parameter(Jrd::dsql_msg*, bool, bool, USHORT, const Jrd::ValueExprNode*);

View File

@ -76,15 +76,16 @@ namespace
}
}
bool isSystemRelation(thread_db* tdbb, jrd_tra* transaction, const char* relName)
bool isSystemRelation(thread_db* tdbb, jrd_tra* transaction, const QualifiedName& relName)
{
bool rc = false;
AutoCacheRequest handle(tdbb, irq_system_relation, IRQ_REQUESTS);
FOR(REQUEST_HANDLE handle TRANSACTION_HANDLE transaction)
R IN RDB$RELATIONS WITH
R.RDB$RELATION_NAME EQ relName AND
R.RDB$SYSTEM_FLAG EQ 1
R IN RDB$RELATIONS
WITH R.RDB$SCHEMA_NAME EQ relName.schema.c_str() AND
R.RDB$RELATION_NAME EQ relName.object.c_str() AND
R.RDB$SYSTEM_FLAG EQ 1
{
rc = true;
}
@ -93,15 +94,16 @@ namespace
return rc;
}
bool isSystemDomain(thread_db* tdbb, jrd_tra* transaction, const char* fldName)
bool isSystemDomain(thread_db* tdbb, jrd_tra* transaction, const QualifiedName& fldName)
{
bool rc = false;
AutoCacheRequest handle(tdbb, irq_system_domain, IRQ_REQUESTS);
FOR(REQUEST_HANDLE handle TRANSACTION_HANDLE transaction)
R IN RDB$FIELDS WITH
R.RDB$FIELD_NAME EQ fldName AND
R.RDB$SYSTEM_FLAG EQ 1
R IN RDB$FIELDS
WITH R.RDB$SCHEMA_NAME EQ fldName.schema.c_str() AND
R.RDB$FIELD_NAME EQ fldName.object.c_str() AND
R.RDB$SYSTEM_FLAG EQ 1
{
rc = true;
}
@ -112,7 +114,7 @@ namespace
}
void METD_drop_charset(jrd_tra* transaction, const MetaName& metaName)
void METD_drop_charset(jrd_tra* transaction, const QualifiedName& metaName)
{
/**************************************
*
@ -142,7 +144,7 @@ void METD_drop_charset(jrd_tra* transaction, const MetaName& metaName)
}
void METD_drop_collation(jrd_tra* transaction, const MetaName& name)
void METD_drop_collation(jrd_tra* transaction, const QualifiedName& name)
{
/**************************************
*
@ -199,7 +201,7 @@ void METD_drop_function(jrd_tra* transaction, const QualifiedName& name)
if (dbb->dbb_functions.get(name, function))
{
MET_dsql_cache_use(tdbb, SYM_udf, name.identifier, name.package);
MET_dsql_cache_use(tdbb, SYM_udf, name);
function->udf_flags |= UDF_dropped;
dbb->dbb_functions.remove(name);
}
@ -232,14 +234,14 @@ void METD_drop_procedure(jrd_tra* transaction, const QualifiedName& name)
if (dbb->dbb_procedures.get(name, procedure))
{
MET_dsql_cache_use(tdbb, SYM_procedure, name.identifier, name.package);
MET_dsql_cache_use(tdbb, SYM_procedure, name);
procedure->prc_flags |= PRC_dropped;
dbb->dbb_procedures.remove(name);
}
}
void METD_drop_relation(jrd_tra* transaction, const MetaName& name)
void METD_drop_relation(jrd_tra* transaction, const QualifiedName& name)
{
/**************************************
*
@ -271,7 +273,7 @@ void METD_drop_relation(jrd_tra* transaction, const MetaName& name)
}
dsql_intlsym* METD_get_collation(jrd_tra* transaction, const MetaName& name, USHORT charset_id)
dsql_intlsym* METD_get_collation(jrd_tra* transaction, const QualifiedName& name, USHORT charset_id)
{
/**************************************
*
@ -311,7 +313,8 @@ dsql_intlsym* METD_get_collation(jrd_tra* transaction, const MetaName& name, USH
FOR(REQUEST_HANDLE handle TRANSACTION_HANDLE transaction)
X IN RDB$COLLATIONS
CROSS Y IN RDB$CHARACTER_SETS OVER RDB$CHARACTER_SET_ID
WITH X.RDB$COLLATION_NAME EQ name.c_str() AND
WITH X.RDB$SCHEMA_NAME EQ name.schema.c_str() AND
X.RDB$COLLATION_NAME EQ name.object.c_str() AND
X.RDB$CHARACTER_SET_ID EQ charset_id;
{
symbol = FB_NEW_POOL(dbb->dbb_pool) dsql_intlsym(dbb->dbb_pool);
@ -336,7 +339,7 @@ dsql_intlsym* METD_get_collation(jrd_tra* transaction, const MetaName& name, USH
}
dsql_intlsym* METD_get_charset(jrd_tra* transaction, USHORT length, const char* name) // UTF-8
dsql_intlsym* METD_get_charset(jrd_tra* transaction, const QualifiedName& name)
{
/**************************************
*
@ -354,14 +357,13 @@ dsql_intlsym* METD_get_charset(jrd_tra* transaction, USHORT length, const char*
validateTransaction(transaction);
dsql_dbb* dbb = transaction->getDsqlAttachment();
MetaName metaName(name, length);
// Start by seeing if symbol is already defined
dsql_intlsym* symbol;
if (dbb->dbb_charsets.get(metaName, symbol) && !(symbol->intlsym_flags & INTLSYM_dropped))
if (dbb->dbb_charsets.get(name, symbol) && !(symbol->intlsym_flags & INTLSYM_dropped))
{
if (MET_dsql_cache_use(tdbb, SYM_intlsym_charset, metaName))
if (MET_dsql_cache_use(tdbb, SYM_intlsym_charset, name))
symbol->intlsym_flags |= INTLSYM_dropped;
else
return symbol;
@ -374,32 +376,34 @@ dsql_intlsym* METD_get_charset(jrd_tra* transaction, USHORT length, const char*
AutoCacheRequest handle(tdbb, irq_charset, IRQ_REQUESTS);
FOR(REQUEST_HANDLE handle TRANSACTION_HANDLE transaction)
X IN RDB$COLLATIONS
CROSS Y IN RDB$CHARACTER_SETS OVER RDB$CHARACTER_SET_ID
CROSS Z IN RDB$TYPES
WITH Z.RDB$TYPE EQ Y.RDB$CHARACTER_SET_ID
AND Z.RDB$TYPE_NAME EQ name
AND Z.RDB$FIELD_NAME EQ "RDB$CHARACTER_SET_NAME"
AND Y.RDB$DEFAULT_COLLATE_NAME EQ X.RDB$COLLATION_NAME;
CS IN RDB$CHARACTER_SETS
CROSS COLL IN RDB$COLLATIONS OVER RDB$CHARACTER_SET_ID
CROSS T IN RDB$TYPES
WITH CS.RDB$SCHEMA_NAME EQ name.schema.c_str() AND
T.RDB$TYPE_NAME EQ name.object.c_str() AND
COLL.RDB$SCHEMA_NAME EQ CS.RDB$DEFAULT_COLLATE_SCHEMA_NAME AND
COLL.RDB$COLLATION_NAME EQ CS.RDB$DEFAULT_COLLATE_NAME AND
T.RDB$FIELD_NAME EQ "RDB$CHARACTER_SET_NAME" AND
T.RDB$TYPE EQ CS.RDB$CHARACTER_SET_ID
{
symbol = FB_NEW_POOL(dbb->dbb_pool) dsql_intlsym(dbb->dbb_pool);
symbol->intlsym_name = metaName;
symbol->intlsym_name = name;
symbol->intlsym_flags = 0;
symbol->intlsym_charset_id = X.RDB$CHARACTER_SET_ID;
symbol->intlsym_collate_id = X.RDB$COLLATION_ID;
symbol->intlsym_charset_id = COLL.RDB$CHARACTER_SET_ID;
symbol->intlsym_collate_id = COLL.RDB$COLLATION_ID;
symbol->intlsym_ttype =
INTL_CS_COLL_TO_TTYPE(symbol->intlsym_charset_id, symbol->intlsym_collate_id);
symbol->intlsym_bytes_per_char =
(Y.RDB$BYTES_PER_CHARACTER.NULL) ? 1 : (Y.RDB$BYTES_PER_CHARACTER);
(CS.RDB$BYTES_PER_CHARACTER.NULL) ? 1 : (CS.RDB$BYTES_PER_CHARACTER);
}
END_FOR
if (!symbol)
return NULL;
dbb->dbb_charsets.put(metaName, symbol);
dbb->dbb_charsets.put(name, symbol);
dbb->dbb_charsets_by_id.put(symbol->intlsym_charset_id, symbol);
MET_dsql_cache_use(tdbb, SYM_intlsym_charset, metaName);
MET_dsql_cache_use(tdbb, SYM_intlsym_charset, name);
return symbol;
}
@ -431,8 +435,8 @@ USHORT METD_get_charset_bpc(jrd_tra* transaction, SSHORT charset_id)
dsql_intlsym* symbol = NULL;
if (!dbb->dbb_charsets_by_id.get(charset_id, symbol))
{
const MetaName cs_name = METD_get_charset_name(transaction, charset_id);
symbol = METD_get_charset(transaction, cs_name.length(), cs_name.c_str());
const auto cs_name = METD_get_charset_name(transaction, charset_id);
symbol = METD_get_charset(transaction, cs_name);
}
fb_assert(symbol);
@ -441,7 +445,7 @@ USHORT METD_get_charset_bpc(jrd_tra* transaction, SSHORT charset_id)
}
MetaName METD_get_charset_name(jrd_tra* transaction, SSHORT charset_id)
QualifiedName METD_get_charset_name(jrd_tra* transaction, SSHORT charset_id)
{
/**************************************
*
@ -462,14 +466,14 @@ MetaName METD_get_charset_name(jrd_tra* transaction, SSHORT charset_id)
dsql_dbb* dbb = transaction->getDsqlAttachment();
if (charset_id == CS_dynamic)
if (charset_id == CS_dynamic)
charset_id = tdbb->getCharSet();
dsql_intlsym* sym = NULL;
if (dbb->dbb_charsets_by_id.get(charset_id, sym))
return sym->intlsym_name;
MetaName name;
QualifiedName name;
AutoCacheRequest handle(tdbb, irq_cs_name, IRQ_REQUESTS);
@ -477,62 +481,87 @@ MetaName METD_get_charset_name(jrd_tra* transaction, SSHORT charset_id)
Y IN RDB$CHARACTER_SETS
WITH Y.RDB$CHARACTER_SET_ID EQ charset_id
{
name = Y.RDB$CHARACTER_SET_NAME;
name = QualifiedName(Y.RDB$CHARACTER_SET_NAME, Y.RDB$SCHEMA_NAME);
}
END_FOR
// put new charset into hash table if needed
METD_get_charset(transaction, name.length(), name.c_str());
METD_get_charset(transaction, name);
return name;
}
MetaName METD_get_default_charset(jrd_tra* transaction)
// Find the default character set for a database
QualifiedName METD_get_database_charset(jrd_tra* transaction)
{
/**************************************
*
* M E T D _ g e t _ d e f a u l t _ c h a r s e t
*
**************************************
*
* Functional description
* Find the default character set for a database
*
**************************************/
thread_db* tdbb = JRD_get_thread_data();
validateTransaction(transaction);
dsql_dbb* dbb = transaction->getDsqlAttachment();
if (dbb->dbb_no_charset)
return NULL;
return {};
if (dbb->dbb_dfl_charset.hasData())
if (dbb->dbb_dfl_charset.object.hasData())
return dbb->dbb_dfl_charset;
// Now see if it is in the database
AutoCacheRequest handle(tdbb, irq_default_cs, IRQ_REQUESTS);
static const CachedRequestId requestHandleId;
AutoCacheRequest requestHandle(tdbb, requestHandleId);
FOR(REQUEST_HANDLE handle TRANSACTION_HANDLE transaction)
FOR(REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction)
FIRST 1 DBB IN RDB$DATABASE
WITH DBB.RDB$CHARACTER_SET_NAME NOT MISSING;
WITH DBB.RDB$CHARACTER_SET_NAME NOT MISSING
{
// Terminate ASCIIZ string on first trailing blank
fb_utils::exact_name(DBB.RDB$CHARACTER_SET_NAME);
dbb->dbb_dfl_charset = DBB.RDB$CHARACTER_SET_NAME;
dbb->dbb_dfl_charset = QualifiedName(DBB.RDB$CHARACTER_SET_NAME, DBB.RDB$CHARACTER_SET_SCHEMA_NAME);
}
END_FOR
if (dbb->dbb_dfl_charset.isEmpty())
if (dbb->dbb_dfl_charset.object.isEmpty())
{
fb_assert(false);
dbb->dbb_no_charset = true;
}
return dbb->dbb_dfl_charset;
}
bool METD_get_domain(jrd_tra* transaction, TypeClause* field, const MetaName& name) // UTF-8
// Find the default character set for a schema
QualifiedName METD_get_schema_charset(jrd_tra* transaction, const MetaName& schema)
{
thread_db* tdbb = JRD_get_thread_data();
validateTransaction(transaction);
dsql_dbb* dbb = transaction->getDsqlAttachment();
if (const auto charSet = dbb->dbb_schemas_dfl_charset.get(schema))
return *charSet;
// Now see if it is in the database
static const CachedRequestId requestHandleId;
AutoCacheRequest requestHandle(tdbb, requestHandleId);
FOR(REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction)
FIRST 1 SCH IN RDB$SCHEMAS
WITH SCH.RDB$SCHEMA_NAME = schema.c_str()
{
QualifiedName charSet(SCH.RDB$CHARACTER_SET_NAME, SCH.RDB$CHARACTER_SET_SCHEMA_NAME);
dbb->dbb_schemas_dfl_charset.put(schema, charSet);
return charSet;
}
END_FOR
fb_assert(false);
return {};
}
bool METD_get_domain(jrd_tra* transaction, TypeClause* field, const QualifiedName& name) // UTF-8
{
/**************************************
*
@ -553,7 +582,9 @@ bool METD_get_domain(jrd_tra* transaction, TypeClause* field, const MetaName& na
AutoCacheRequest handle(tdbb, irq_domain, IRQ_REQUESTS);
FOR(REQUEST_HANDLE handle TRANSACTION_HANDLE transaction)
FLX IN RDB$FIELDS WITH FLX.RDB$FIELD_NAME EQ name.c_str()
FLX IN RDB$FIELDS
WITH FLX.RDB$SCHEMA_NAME EQ name.schema.c_str() AND
FLX.RDB$FIELD_NAME EQ name.object.c_str()
{
found = true;
field->length = FLX.RDB$FIELD_LENGTH;
@ -592,8 +623,7 @@ bool METD_get_domain(jrd_tra* transaction, TypeClause* field, const MetaName& na
}
dsql_udf* METD_get_function(jrd_tra* transaction, DsqlCompilerScratch* dsqlScratch,
const QualifiedName& name)
dsql_udf* METD_get_function(jrd_tra* transaction, DsqlCompilerScratch* dsqlScratch, const QualifiedName& name)
{
/**************************************
*
@ -611,24 +641,13 @@ dsql_udf* METD_get_function(jrd_tra* transaction, DsqlCompilerScratch* dsqlScrat
validateTransaction(transaction);
dsql_dbb* dbb = transaction->getDsqlAttachment();
QualifiedName metaName(name);
bool maybeUnqualified = dsqlScratch->package.hasData() && metaName.package.isEmpty();
if (maybeUnqualified)
metaName.package = dsqlScratch->package;
// Start by seeing if symbol is already defined
dsql_udf* userFunc = NULL;
if (dbb->dbb_functions.get(metaName, userFunc))
if (dbb->dbb_functions.get(name, userFunc))
{
if (userFunc->udf_private && metaName.package != dsqlScratch->package)
{
status_exception::raise(Arg::Gds(isc_private_function) <<
Arg::Str(metaName.identifier) << Arg::Str(metaName.package));
}
if (MET_dsql_cache_use(tdbb, SYM_udf, metaName.identifier, metaName.package))
if (MET_dsql_cache_use(tdbb, SYM_udf, name))
userFunc->udf_flags |= UDF_dropped;
}
@ -642,43 +661,34 @@ dsql_udf* METD_get_function(jrd_tra* transaction, DsqlCompilerScratch* dsqlScrat
USHORT return_arg = 0;
while (!userFunc)
AutoCacheRequest handle1(tdbb, irq_function, IRQ_REQUESTS);
FOR(REQUEST_HANDLE handle1 TRANSACTION_HANDLE transaction)
X IN RDB$FUNCTIONS
WITH X.RDB$SCHEMA_NAME EQ name.schema.c_str() AND
X.RDB$FUNCTION_NAME EQ name.object.c_str() AND
X.RDB$PACKAGE_NAME EQUIV NULLIF(name.package.c_str(), '')
{
AutoCacheRequest handle1(tdbb, irq_function, IRQ_REQUESTS);
userFunc = FB_NEW_POOL(dbb->dbb_pool) dsql_udf(dbb->dbb_pool);
userFunc->udf_name = name;
userFunc->udf_private = !X.RDB$PRIVATE_FLAG.NULL && X.RDB$PRIVATE_FLAG != 0;
FOR(REQUEST_HANDLE handle1 TRANSACTION_HANDLE transaction)
X IN RDB$FUNCTIONS WITH
X.RDB$FUNCTION_NAME EQ metaName.identifier.c_str() AND
X.RDB$PACKAGE_NAME EQUIV NULLIF(metaName.package.c_str(), '')
{
userFunc = FB_NEW_POOL(dbb->dbb_pool) dsql_udf(dbb->dbb_pool);
userFunc->udf_name = metaName;
userFunc->udf_private = !X.RDB$PRIVATE_FLAG.NULL && X.RDB$PRIVATE_FLAG != 0;
return_arg = X.RDB$RETURN_ARGUMENT;
}
END_FOR
if (!userFunc)
{
if (maybeUnqualified)
{
maybeUnqualified = false;
metaName.package = "";
}
else
return NULL;
}
return_arg = X.RDB$RETURN_ARGUMENT;
}
END_FOR
if (!userFunc)
return nullptr;
SSHORT defaults = 0;
AutoCacheRequest handle2(tdbb, irq_func_return, IRQ_REQUESTS);
FOR(REQUEST_HANDLE handle2 TRANSACTION_HANDLE transaction)
X IN RDB$FUNCTION_ARGUMENTS WITH
X.RDB$FUNCTION_NAME EQ metaName.identifier.c_str() AND
X.RDB$PACKAGE_NAME EQUIV NULLIF(metaName.package.c_str(), '')
X IN RDB$FUNCTION_ARGUMENTS
WITH X.RDB$SCHEMA_NAME EQ name.schema.c_str() AND
X.RDB$FUNCTION_NAME EQ name.object.c_str() AND
X.RDB$PACKAGE_NAME EQUIV NULLIF(name.package.c_str(), '')
SORTED BY X.RDB$ARGUMENT_POSITION
{
if (!X.RDB$FIELD_SOURCE.NULL)
@ -687,6 +697,7 @@ dsql_udf* METD_get_function(jrd_tra* transaction, DsqlCompilerScratch* dsqlScrat
FOR(REQUEST_HANDLE handle3 TRANSACTION_HANDLE transaction)
F IN RDB$FIELDS WITH
F.RDB$SCHEMA_NAME EQUIV X.RDB$FIELD_SOURCE_SCHEMA_NAME AND
F.RDB$FIELD_NAME EQ X.RDB$FIELD_SOURCE
{
if (X.RDB$ARGUMENT_POSITION == return_arg)
@ -717,14 +728,20 @@ dsql_udf* METD_get_function(jrd_tra* transaction, DsqlCompilerScratch* dsqlScrat
!X.RDB$RELATION_NAME.NULL && X.RDB$RELATION_NAME[0])
{
// type of column used in declaration
if (isSystemRelation(tdbb, transaction, X.RDB$RELATION_NAME))
if (isSystemRelation(tdbb, transaction,
QualifiedName(X.RDB$RELATION_NAME, X.RDB$RELATION_SCHEMA_NAME)))
{
userFunc->udf_flags |= UDF_sys_based;
}
}
else if (!X.RDB$FIELD_SOURCE.NULL && X.RDB$FIELD_SOURCE[0])
{
// domain used in declaration
if (isSystemDomain(tdbb, transaction, X.RDB$FIELD_SOURCE))
if (isSystemDomain(tdbb, transaction,
QualifiedName(X.RDB$FIELD_SOURCE, X.RDB$FIELD_SOURCE_SCHEMA_NAME)))
{
userFunc->udf_flags |= UDF_sys_based;
}
}
}
else
@ -896,19 +913,13 @@ dsql_udf* METD_get_function(jrd_tra* transaction, DsqlCompilerScratch* dsqlScrat
dbb->dbb_functions.put(userFunc->udf_name, userFunc);
if (userFunc->udf_private && metaName.package != dsqlScratch->package)
{
status_exception::raise(Arg::Gds(isc_private_function) <<
Arg::Str(metaName.identifier) << Arg::Str(metaName.package));
}
MET_dsql_cache_use(tdbb, SYM_udf, userFunc->udf_name.identifier, userFunc->udf_name.package);
MET_dsql_cache_use(tdbb, SYM_udf, userFunc->udf_name);
return userFunc;
}
void METD_get_primary_key(jrd_tra* transaction, const MetaName& relationName,
void METD_get_primary_key(jrd_tra* transaction, const QualifiedName& relationName,
Array<NestConst<FieldNode> >& fields)
{
/**************************************
@ -931,13 +942,12 @@ void METD_get_primary_key(jrd_tra* transaction, const MetaName& relationName,
AutoCacheRequest handle(tdbb, irq_primary_key, IRQ_REQUESTS);
FOR(REQUEST_HANDLE handle TRANSACTION_HANDLE transaction)
X IN RDB$INDICES CROSS
Y IN RDB$INDEX_SEGMENTS
OVER RDB$INDEX_NAME CROSS
Z IN RDB$RELATION_CONSTRAINTS
OVER RDB$INDEX_NAME
WITH Z.RDB$RELATION_NAME EQ relationName.c_str()
AND Z.RDB$CONSTRAINT_TYPE EQ "PRIMARY KEY"
X IN RDB$INDICES
CROSS Y IN RDB$INDEX_SEGMENTS OVER RDB$SCHEMA_NAME, RDB$INDEX_NAME
CROSS Z IN RDB$RELATION_CONSTRAINTS OVER RDB$SCHEMA_NAME, RDB$INDEX_NAME
WITH Z.RDB$SCHEMA_NAME EQ relationName.schema.c_str() AND
Z.RDB$RELATION_NAME EQ relationName.object.c_str() AND
Z.RDB$CONSTRAINT_TYPE EQ "PRIMARY KEY"
SORTED BY Y.RDB$FIELD_POSITION
{
FieldNode* fieldNode = FB_NEW_POOL(pool) FieldNode(pool);
@ -948,8 +958,7 @@ void METD_get_primary_key(jrd_tra* transaction, const MetaName& relationName,
}
dsql_prc* METD_get_procedure(jrd_tra* transaction, DsqlCompilerScratch* dsqlScratch,
const QualifiedName& name)
dsql_prc* METD_get_procedure(jrd_tra* transaction, DsqlCompilerScratch* dsqlScratch, const QualifiedName& name)
{
/**************************************
*
@ -1003,24 +1012,14 @@ dsql_prc* METD_get_procedure(jrd_tra* transaction, DsqlCompilerScratch* dsqlScra
//
// I hope for a solution, involving savepoint logic.
QualifiedName metaName(name);
bool maybeUnqualified = dsqlScratch->package.hasData() && metaName.package.isEmpty();
if (maybeUnqualified)
metaName.package = dsqlScratch->package;
QualifiedName qualifiedName(name);
// Start by seeing if symbol is already defined
dsql_prc* procedure = NULL;
if (dbb->dbb_procedures.get(metaName, procedure))
if (dbb->dbb_procedures.get(qualifiedName, procedure))
{
if (procedure->prc_private && metaName.package != dsqlScratch->package)
{
status_exception::raise(Arg::Gds(isc_private_procedure) <<
Arg::Str(metaName.identifier) << Arg::Str(metaName.package));
}
if (MET_dsql_cache_use(tdbb, SYM_procedure, metaName.identifier, metaName.package))
if (MET_dsql_cache_use(tdbb, SYM_procedure, qualifiedName))
procedure->prc_flags |= PRC_dropped;
}
@ -1032,36 +1031,24 @@ dsql_prc* METD_get_procedure(jrd_tra* transaction, DsqlCompilerScratch* dsqlScra
// now see if it is in the database
while (!procedure)
AutoCacheRequest handle1(tdbb, irq_procedure, IRQ_REQUESTS);
FOR(REQUEST_HANDLE handle1 TRANSACTION_HANDLE transaction)
X IN RDB$PROCEDURES
WITH X.RDB$SCHEMA_NAME EQ qualifiedName.schema.c_str() AND
X.RDB$PROCEDURE_NAME EQ qualifiedName.object.c_str() AND
X.RDB$PACKAGE_NAME EQUIV NULLIF(qualifiedName.package.c_str(), '')
{
AutoCacheRequest handle1(tdbb, irq_procedure, IRQ_REQUESTS);
FOR(REQUEST_HANDLE handle1 TRANSACTION_HANDLE transaction)
X IN RDB$PROCEDURES
WITH X.RDB$PROCEDURE_NAME EQ metaName.identifier.c_str() AND
X.RDB$PACKAGE_NAME EQUIV NULLIF(metaName.package.c_str(), '')
{
fb_utils::exact_name(X.RDB$OWNER_NAME);
procedure = FB_NEW_POOL(dbb->dbb_pool) dsql_prc(dbb->dbb_pool);
procedure->prc_id = X.RDB$PROCEDURE_ID;
procedure->prc_name = metaName;
procedure->prc_owner = X.RDB$OWNER_NAME;
procedure->prc_private = !X.RDB$PRIVATE_FLAG.NULL && X.RDB$PRIVATE_FLAG != 0;
}
END_FOR
if (!procedure)
{
if (maybeUnqualified)
{
maybeUnqualified = false;
metaName.package = "";
}
else
return NULL;
}
procedure = FB_NEW_POOL(dbb->dbb_pool) dsql_prc(dbb->dbb_pool);
procedure->prc_id = X.RDB$PROCEDURE_ID;
procedure->prc_name = qualifiedName;
procedure->prc_owner = X.RDB$OWNER_NAME;
procedure->prc_private = !X.RDB$PRIVATE_FLAG.NULL && X.RDB$PRIVATE_FLAG != 0;
}
END_FOR
if (!procedure)
return nullptr;
// Lookup parameter stuff
@ -1076,10 +1063,12 @@ dsql_prc* METD_get_procedure(jrd_tra* transaction, DsqlCompilerScratch* dsqlScra
FOR (REQUEST_HANDLE handle2 TRANSACTION_HANDLE transaction)
PR IN RDB$PROCEDURE_PARAMETERS
CROSS FLD IN RDB$FIELDS
WITH FLD.RDB$FIELD_NAME EQ PR.RDB$FIELD_SOURCE AND
PR.RDB$PROCEDURE_NAME EQ metaName.identifier.c_str() AND
WITH PR.RDB$SCHEMA_NAME EQ qualifiedName.schema.c_str() AND
PR.RDB$PROCEDURE_NAME EQ qualifiedName.object.c_str() AND
PR.RDB$PARAMETER_TYPE = type AND
PR.RDB$PACKAGE_NAME EQUIV NULLIF(metaName.package.c_str(), '')
PR.RDB$PACKAGE_NAME EQUIV NULLIF(qualifiedName.package.c_str(), '') AND
FLD.RDB$SCHEMA_NAME EQUIV PR.RDB$FIELD_SOURCE_SCHEMA_NAME AND
FLD.RDB$FIELD_NAME EQ PR.RDB$FIELD_SOURCE
SORTED BY DESCENDING PR.RDB$PARAMETER_NUMBER
{
const SSHORT pr_collation_id_null = PR.RDB$COLLATION_ID.NULL;
@ -1106,7 +1095,7 @@ dsql_prc* METD_get_procedure(jrd_tra* transaction, DsqlCompilerScratch* dsqlScra
// get parameter information
parameter->fld_name = PR.RDB$PARAMETER_NAME;
parameter->fieldSource = PR.RDB$FIELD_SOURCE;
parameter->fieldSource = QualifiedName(PR.RDB$FIELD_SOURCE, PR.RDB$FIELD_SOURCE_SCHEMA_NAME);
parameter->fld_id = PR.RDB$PARAMETER_NUMBER;
parameter->length = FLD.RDB$FIELD_LENGTH;
@ -1138,28 +1127,25 @@ dsql_prc* METD_get_procedure(jrd_tra* transaction, DsqlCompilerScratch* dsqlScra
if (!PR.RDB$FIELD_NAME.NULL)
{
fb_utils::exact_name(PR.RDB$FIELD_NAME);
parameter->typeOfName = PR.RDB$FIELD_NAME;
parameter->typeOfName = QualifiedName(PR.RDB$FIELD_NAME, PR.RDB$FIELD_SOURCE_SCHEMA_NAME);
}
if (!PR.RDB$RELATION_NAME.NULL)
{
fb_utils::exact_name(PR.RDB$RELATION_NAME);
parameter->typeOfTable = PR.RDB$RELATION_NAME;
}
parameter->typeOfTable = QualifiedName(PR.RDB$RELATION_NAME, PR.RDB$RELATION_SCHEMA_NAME);
if (parameter->typeOfTable.hasData())
if (parameter->typeOfTable.object.hasData())
{
if (isSystemRelation(tdbb, transaction, parameter->typeOfTable.c_str()))
if (isSystemRelation(tdbb, transaction, parameter->typeOfTable))
parameter->flags |= FLD_system;
}
else if (parameter->typeOfName.hasData())
else if (parameter->typeOfName.object.hasData())
{
if (isSystemDomain(tdbb, transaction, parameter->typeOfName.c_str()))
if (isSystemDomain(tdbb, transaction, parameter->typeOfName))
parameter->flags |= FLD_system;
}
else if (parameter->fieldSource.hasData())
else if (parameter->fieldSource.object.hasData())
{
if (isSystemDomain(tdbb, transaction, parameter->fieldSource.c_str()))
if (isSystemDomain(tdbb, transaction, parameter->fieldSource))
parameter->flags |= FLD_system;
}
@ -1183,21 +1169,14 @@ dsql_prc* METD_get_procedure(jrd_tra* transaction, DsqlCompilerScratch* dsqlScra
dbb->dbb_procedures.put(procedure->prc_name, procedure);
if (procedure->prc_private && metaName.package != dsqlScratch->package)
{
status_exception::raise(Arg::Gds(isc_private_procedure) <<
Arg::Str(metaName.identifier) << Arg::Str(metaName.package));
}
MET_dsql_cache_use(tdbb, SYM_procedure, procedure->prc_name.identifier,
procedure->prc_name.package);
MET_dsql_cache_use(tdbb, SYM_procedure, procedure->prc_name);
return procedure;
}
dsql_rel* METD_get_relation(jrd_tra* transaction, DsqlCompilerScratch* dsqlScratch,
const MetaName& name)
const QualifiedName& name)
{
/**************************************
*
@ -1242,9 +1221,10 @@ dsql_rel* METD_get_relation(jrd_tra* transaction, DsqlCompilerScratch* dsqlScrat
FOR(REQUEST_HANDLE handle1 TRANSACTION_HANDLE transaction)
REL IN RDB$RELATIONS
CROSS RFR IN RDB$RELATION_FIELDS OVER RDB$RELATION_NAME
WITH REL.RDB$RELATION_NAME EQ name.c_str()
AND (REL.RDB$RELATION_ID MISSING OR RFR.RDB$FIELD_ID MISSING)
CROSS RFR IN RDB$RELATION_FIELDS OVER RDB$SCHEMA_NAME, RDB$RELATION_NAME
WITH REL.RDB$SCHEMA_NAME EQ name.schema.c_str() AND
REL.RDB$RELATION_NAME EQ name.object.c_str() AND
(REL.RDB$RELATION_ID MISSING OR RFR.RDB$FIELD_ID MISSING)
{
permanent = false;
}
@ -1259,10 +1239,10 @@ dsql_rel* METD_get_relation(jrd_tra* transaction, DsqlCompilerScratch* dsqlScrat
AutoCacheRequest handle2(tdbb, irq_relation, IRQ_REQUESTS);
FOR(REQUEST_HANDLE handle2 TRANSACTION_HANDLE transaction)
X IN RDB$RELATIONS WITH X.RDB$RELATION_NAME EQ name.c_str()
X IN RDB$RELATIONS
WITH X.RDB$SCHEMA_NAME EQ name.schema.c_str() AND
X.RDB$RELATION_NAME EQ name.object.c_str()
{
fb_utils::exact_name(X.RDB$OWNER_NAME);
// Allocate from default or permanent pool as appropriate
if (!X.RDB$RELATION_ID.NULL)
@ -1300,17 +1280,15 @@ dsql_rel* METD_get_relation(jrd_tra* transaction, DsqlCompilerScratch* dsqlScrat
AutoCacheRequest handle3(tdbb, irq_fields, IRQ_REQUESTS);
FOR(REQUEST_HANDLE handle3 TRANSACTION_HANDLE transaction)
FLX IN RDB$FIELDS CROSS
RFR IN RDB$RELATION_FIELDS
WITH FLX.RDB$FIELD_NAME EQ RFR.RDB$FIELD_SOURCE
AND RFR.RDB$RELATION_NAME EQ name.c_str()
FLX IN RDB$FIELDS
CROSS RFR IN RDB$RELATION_FIELDS
WITH RFR.RDB$SCHEMA_NAME EQ name.schema.c_str() AND
RFR.RDB$RELATION_NAME EQ name.object.c_str() AND
FLX.RDB$SCHEMA_NAME EQUIV RFR.RDB$FIELD_SOURCE_SCHEMA_NAME AND
FLX.RDB$FIELD_NAME EQ RFR.RDB$FIELD_SOURCE
SORTED BY RFR.RDB$FIELD_POSITION
{
// allocate the field block
fb_utils::exact_name(RFR.RDB$FIELD_NAME);
fb_utils::exact_name(RFR.RDB$FIELD_SOURCE);
// Allocate the field block
// Allocate from default or permanent pool as appropriate
dsql_fld* field = NULL;
@ -1331,7 +1309,7 @@ dsql_rel* METD_get_relation(jrd_tra* transaction, DsqlCompilerScratch* dsqlScrat
// get field information
field->fld_name = RFR.RDB$FIELD_NAME;
field->fieldSource = RFR.RDB$FIELD_SOURCE;
field->fieldSource = QualifiedName(RFR.RDB$FIELD_SOURCE, RFR.RDB$FIELD_SOURCE_SCHEMA_NAME);
field->length = FLX.RDB$FIELD_LENGTH;
field->scale = FLX.RDB$FIELD_SCALE;
field->subType = FLX.RDB$FIELD_SUB_TYPE;
@ -1415,8 +1393,9 @@ bool METD_get_type(jrd_tra* transaction, const MetaName& name, const char* field
AutoCacheRequest handle(tdbb, irq_type, IRQ_REQUESTS);
FOR(REQUEST_HANDLE handle TRANSACTION_HANDLE transaction)
X IN RDB$TYPES WITH
X.RDB$FIELD_NAME EQ field AND X.RDB$TYPE_NAME EQ name.c_str();
X IN RDB$TYPES
WITH X.RDB$FIELD_NAME EQ field AND
X.RDB$TYPE_NAME EQ name.c_str()
{
found = true;
*value = X.RDB$TYPE;
@ -1428,7 +1407,7 @@ bool METD_get_type(jrd_tra* transaction, const MetaName& name, const char* field
dsql_rel* METD_get_view_base(jrd_tra* transaction, DsqlCompilerScratch* dsqlScratch,
const char* view_name, MetaNamePairMap& fields)
const QualifiedName& viewName, MetaNamePairMap& fields)
{
/**************************************
*
@ -1449,8 +1428,8 @@ dsql_rel* METD_get_view_base(jrd_tra* transaction, DsqlCompilerScratch* dsqlScra
validateTransaction(transaction);
dsql_rel* relation = NULL;
auto nextViewName = viewName;
dsql_rel* relation = nullptr;
bool first = true;
bool cont = true;
MetaNamePairMap previousAux;
@ -1463,7 +1442,8 @@ dsql_rel* METD_get_view_base(jrd_tra* transaction, DsqlCompilerScratch* dsqlScra
FOR(REQUEST_HANDLE handle1 TRANSACTION_HANDLE transaction)
X IN RDB$VIEW_RELATIONS
WITH X.RDB$VIEW_NAME EQ view_name
WITH X.RDB$SCHEMA_NAME EQ nextViewName.schema.c_str() AND
X.RDB$VIEW_NAME EQ nextViewName.object.c_str()
{
// return NULL if there is more than one context
if (X.RDB$VIEW_CONTEXT != 1 || X.RDB$CONTEXT_TYPE == VCT_PROCEDURE)
@ -1473,10 +1453,8 @@ dsql_rel* METD_get_view_base(jrd_tra* transaction, DsqlCompilerScratch* dsqlScra
break;
}
fb_utils::exact_name(X.RDB$CONTEXT_NAME);
fb_utils::exact_name(X.RDB$RELATION_NAME);
relation = METD_get_relation(transaction, dsqlScratch, X.RDB$RELATION_NAME);
nextViewName = QualifiedName(X.RDB$RELATION_NAME, X.RDB$RELATION_SCHEMA_NAME);
relation = METD_get_relation(transaction, dsqlScratch, nextViewName);
Array<MetaName> ambiguities;
MetaNamePairMap currentAux;
@ -1491,7 +1469,8 @@ dsql_rel* METD_get_view_base(jrd_tra* transaction, DsqlCompilerScratch* dsqlScra
FOR(REQUEST_HANDLE handle2 TRANSACTION_HANDLE transaction)
RFL IN RDB$RELATION_FIELDS
WITH RFL.RDB$RELATION_NAME EQ X.RDB$VIEW_NAME
WITH RFL.RDB$SCHEMA_NAME EQUIV X.RDB$SCHEMA_NAME AND
RFL.RDB$RELATION_NAME EQ X.RDB$VIEW_NAME
{
if (RFL.RDB$BASE_FIELD.NULL || RFL.RDB$FIELD_NAME.NULL)
continue;
@ -1534,9 +1513,7 @@ dsql_rel* METD_get_view_base(jrd_tra* transaction, DsqlCompilerScratch* dsqlScra
previousAux.takeOwnership(currentAux);
if (relation->rel_flags & REL_view)
view_name = X.RDB$RELATION_NAME;
else
if (!(relation->rel_flags & REL_view))
{
cont = false;
break;
@ -1555,7 +1532,7 @@ dsql_rel* METD_get_view_base(jrd_tra* transaction, DsqlCompilerScratch* dsqlScra
bool METD_get_view_relation(jrd_tra* transaction, DsqlCompilerScratch* dsqlScratch,
const Jrd::MetaName& view_name, const Jrd::MetaName& relation_or_alias,
const Jrd::QualifiedName& view_name, const Jrd::QualifiedName& relation_or_alias,
dsql_rel*& relation, dsql_prc*& procedure)
{
/**************************************
@ -1577,29 +1554,27 @@ bool METD_get_view_relation(jrd_tra* transaction, DsqlCompilerScratch* dsqlScrat
AutoCacheRequest handle(tdbb, irq_view, IRQ_REQUESTS);
FOR(REQUEST_HANDLE handle TRANSACTION_HANDLE transaction)
X IN RDB$VIEW_RELATIONS WITH X.RDB$VIEW_NAME EQ view_name.c_str()
X IN RDB$VIEW_RELATIONS
WITH X.RDB$SCHEMA_NAME EQ view_name.schema.c_str() AND
X.RDB$VIEW_NAME EQ view_name.object.c_str()
{
fb_utils::exact_name(X.RDB$CONTEXT_NAME);
fb_utils::exact_name(X.RDB$RELATION_NAME);
QualifiedName relationName(X.RDB$RELATION_NAME, X.RDB$RELATION_SCHEMA_NAME);
if (relation_or_alias == X.RDB$RELATION_NAME ||
relation_or_alias == X.RDB$CONTEXT_NAME)
if (PASS1_compare_alias(relationName, relation_or_alias) ||
(relation_or_alias.schema.isEmpty() && relation_or_alias.object == X.RDB$CONTEXT_NAME))
{
if ( (relation = METD_get_relation(transaction, dsqlScratch, X.RDB$RELATION_NAME)) )
if ((relation = METD_get_relation(transaction, dsqlScratch, relationName)))
return true;
const QualifiedName procName(X.RDB$RELATION_NAME,
const QualifiedName procName(X.RDB$RELATION_NAME, X.RDB$RELATION_SCHEMA_NAME,
X.RDB$PACKAGE_NAME.NULL ? nullptr : X.RDB$PACKAGE_NAME);
if ( (procedure = METD_get_procedure(transaction, dsqlScratch, procName)) )
return true;
}
if (METD_get_view_relation(transaction, dsqlScratch, X.RDB$RELATION_NAME,
relation_or_alias, relation, procedure))
{
if (METD_get_view_relation(transaction, dsqlScratch, relationName, relation_or_alias, relation, procedure))
return true;
}
}
END_FOR

View File

@ -45,29 +45,30 @@ namespace Jrd {
class FieldNode;
};
void METD_drop_charset(Jrd::jrd_tra*, const Jrd::MetaName&);
void METD_drop_collation(Jrd::jrd_tra*, const Jrd::MetaName&);
void METD_drop_charset(Jrd::jrd_tra*, const Jrd::QualifiedName&);
void METD_drop_collation(Jrd::jrd_tra*, const Jrd::QualifiedName&);
void METD_drop_function(Jrd::jrd_tra*, const Jrd::QualifiedName&);
void METD_drop_procedure(Jrd::jrd_tra*, const Jrd::QualifiedName&);
void METD_drop_relation(Jrd::jrd_tra*, const Jrd::MetaName&);
void METD_drop_relation(Jrd::jrd_tra*, const Jrd::QualifiedName&);
Jrd::dsql_intlsym* METD_get_charset(Jrd::jrd_tra*, USHORT, const char* name);
Jrd::dsql_intlsym* METD_get_charset(Jrd::jrd_tra*, const Jrd::QualifiedName& name);
USHORT METD_get_charset_bpc(Jrd::jrd_tra*, SSHORT);
Jrd::MetaName METD_get_charset_name(Jrd::jrd_tra*, SSHORT);
Jrd::dsql_intlsym* METD_get_collation(Jrd::jrd_tra*, const Jrd::MetaName&, USHORT charset_id);
Jrd::MetaName METD_get_default_charset(Jrd::jrd_tra*);
bool METD_get_domain(Jrd::jrd_tra*, class Jrd::TypeClause*, const Jrd::MetaName& name);
Jrd::QualifiedName METD_get_charset_name(Jrd::jrd_tra*, SSHORT);
Jrd::dsql_intlsym* METD_get_collation(Jrd::jrd_tra*, const Jrd::QualifiedName&, USHORT charset_id);
Jrd::QualifiedName METD_get_database_charset(Jrd::jrd_tra*);
Jrd::QualifiedName METD_get_schema_charset(Jrd::jrd_tra*, const Jrd::MetaName&);
bool METD_get_domain(Jrd::jrd_tra*, class Jrd::TypeClause*, const Jrd::QualifiedName& name);
Jrd::dsql_udf* METD_get_function(Jrd::jrd_tra*, Jrd::DsqlCompilerScratch*,
const Jrd::QualifiedName&);
void METD_get_primary_key(Jrd::jrd_tra*, const Jrd::MetaName&,
Firebird::Array<NestConst<Jrd::FieldNode> >&);
void METD_get_primary_key(Jrd::jrd_tra*, const Jrd::QualifiedName&,
Firebird::Array<NestConst<Jrd::FieldNode>>&);
Jrd::dsql_prc* METD_get_procedure(Jrd::jrd_tra*, Jrd::DsqlCompilerScratch*,
const Jrd::QualifiedName&);
Jrd::dsql_rel* METD_get_relation(Jrd::jrd_tra*, Jrd::DsqlCompilerScratch*, const Jrd::MetaName&);
Jrd::dsql_rel* METD_get_relation(Jrd::jrd_tra*, Jrd::DsqlCompilerScratch*, const Jrd::QualifiedName&);
bool METD_get_type(Jrd::jrd_tra*, const Jrd::MetaName&, const char*, SSHORT*);
Jrd::dsql_rel* METD_get_view_base(Jrd::jrd_tra*, Jrd::DsqlCompilerScratch*, const char* view_name,
Jrd::dsql_rel* METD_get_view_base(Jrd::jrd_tra*, Jrd::DsqlCompilerScratch*, const Jrd::QualifiedName& viewName,
Jrd::MetaNamePairMap& fields);
bool METD_get_view_relation(Jrd::jrd_tra*, Jrd::DsqlCompilerScratch*, const Jrd::MetaName& view_name,
const Jrd::MetaName& relation_or_alias, Jrd::dsql_rel*& relation, Jrd::dsql_prc*& procedure);
bool METD_get_view_relation(Jrd::jrd_tra*, Jrd::DsqlCompilerScratch*, const Jrd::QualifiedName& view_name,
const Jrd::QualifiedName& relation_or_alias, Jrd::dsql_rel*& relation, Jrd::dsql_prc*& procedure);
#endif // DSQL_METD_PROTO_H

View File

@ -1 +1 @@
117 shift/reduce conflicts, 22 reduce/reduce conflicts.
130 shift/reduce conflicts, 13 reduce/reduce conflicts.

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,26 @@
/* FIXME: quote vs no quote in plans:
create schema s1;
create schema s2;
create table s1.t1 (n1 integer);
create table s2.t2 (n2 integer);
insert into s1.t1 values (1);
insert into s2.t2 values (2);
commit;
set planonly;
select * from s1.t1, s2.t2;
PLAN JOIN (T1 NATURAL, T2 NATURAL)
select * from s1.t1 a, s1.t1 b;
PLAN JOIN ("A" NATURAL, "B" NATURAL)
*/
/* FIXME: explained plan:
Table ""S1"."T1"" as ""X"" Full Scan
*/
/*
* PROGRAM: Dynamic SQL runtime support
* MODULE: pass1.cpp
@ -139,6 +162,7 @@
*/
#include "firebird.h"
#include <numeric>
#include <string.h>
#include <stdio.h>
#include "ibase.h"
@ -165,6 +189,7 @@
#include "../common/dsc_proto.h"
#include "../jrd/intl_proto.h"
#include "../jrd/jrd_proto.h"
#include "../jrd/met_proto.h"
#include "../yvalve/why_proto.h"
#include "../jrd/SysFunction.h"
#include "../common/classes/array.h"
@ -177,7 +202,6 @@ using namespace Jrd;
using namespace Firebird;
static string pass1_alias_concat(const string&, const string&);
static ValueListNode* pass1_group_by_list(DsqlCompilerScratch*, ValueListNode*, ValueListNode*);
static ValueExprNode* pass1_make_derived_field(thread_db*, DsqlCompilerScratch*, ValueExprNode*);
static RseNode* pass1_rse(DsqlCompilerScratch*, RecordSourceNode*, ValueListNode*, RowsClause*, bool, bool, USHORT);
@ -346,84 +370,117 @@ dsql_ctx* PASS1_make_context(DsqlCompilerScratch* dsqlScratch, RecordSourceNode*
thread_db* const tdbb = JRD_get_thread_data();
dsql_rel* relation = NULL;
dsql_prc* procedure = NULL;
// figure out whether this is a relation or a procedure
// and give an error if it is neither
MetaName relation_name;
QualifiedName name;
ProcedureSourceNode* procNode = NULL;
RelationSourceNode* relNode = NULL;
SelectExprNode* selNode = NULL;
if ((procNode = nodeAs<ProcedureSourceNode>(relationNode)))
relation_name = procNode->dsqlName.identifier;
name = procNode->dsqlName;
else if ((relNode = nodeAs<RelationSourceNode>(relationNode)))
relation_name = relNode->dsqlName;
name = relNode->dsqlName;
//// TODO: LocalTableSourceNode
else if ((selNode = nodeAs<SelectExprNode>(relationNode)))
relation_name = selNode->alias.c_str();
name.object = selNode->alias;
SelectExprNode* cte = NULL;
dsql_rel* relation = NULL;
dsql_prc* procedure = NULL;
if (selNode)
{
// No processing needed here for derived tables.
}
else if (procNode && (procNode->dsqlName.package.hasData() || procNode->inputSources))
else if (!((procNode && procNode->inputSources) || name.schema.hasData() || name.package.hasData()) &&
(cte = dsqlScratch->findCTE(name.object)))
{
if (procNode->dsqlName.package.isEmpty())
{
const auto subProcedure = dsqlScratch->getSubProcedure(procNode->dsqlName.identifier);
procedure = subProcedure ? subProcedure->dsqlProcedure : NULL;
}
if (!procedure)
procedure = METD_get_procedure(dsqlScratch->getTransaction(), dsqlScratch, procNode->dsqlName);
if (!procedure)
{
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-204) <<
Arg::Gds(isc_dsql_procedure_err) <<
Arg::Gds(isc_random) <<
Arg::Str(procNode->dsqlName.toString()) <<
Arg::Gds(isc_dsql_line_col_error) << Arg::Num(relationNode->line) <<
Arg::Num(relationNode->column));
}
}
else if ((cte = dsqlScratch->findCTE(relation_name)))
relationNode = cte;
}
else
{
if (procNode && procNode->dsqlName.package.isEmpty())
auto qualifiedName = name;
if (name.package.isEmpty())
{
const auto subProcedure = dsqlScratch->getSubProcedure(procNode->dsqlName.identifier);
procedure = subProcedure ? subProcedure->dsqlProcedure : NULL;
if (name.schema.isEmpty())
{
if (const auto subProcedure = dsqlScratch->getSubProcedure(name.object))
procedure = subProcedure->dsqlProcedure;
else if (dsqlScratch->package.object.hasData())
{
const QualifiedName packagedName(name.object,
dsqlScratch->package.schema, dsqlScratch->package.object);
if ((procedure = METD_get_procedure(dsqlScratch->getTransaction(), dsqlScratch, packagedName)))
qualifiedName = packagedName;
}
if (!procedure)
dsqlScratch->qualifyExistingName(qualifiedName, obj_procedure);
}
else
{
QualifiedName packageName(name.schema);
dsqlScratch->qualifyExistingName(packageName, obj_package_header);
if (MET_check_package_exists(tdbb, packageName))
{
qualifiedName.schema = packageName.schema;
qualifiedName.package = packageName.object;
}
}
}
if (!procedure)
relation = METD_get_relation(dsqlScratch->getTransaction(), dsqlScratch, relation_name);
procedure = METD_get_procedure(dsqlScratch->getTransaction(), dsqlScratch, qualifiedName);
if (!relation && !procedure && procNode)
procedure = METD_get_procedure(dsqlScratch->getTransaction(), dsqlScratch, procNode->dsqlName);
if (!relation && !procedure)
if (!procedure && !(name.package.hasData() || (procNode && procNode->inputSources)))
{
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-204) <<
Arg::Gds(isc_dsql_relation_err) <<
Arg::Gds(isc_random) << Arg::Str(relation_name) <<
Arg::Gds(isc_dsql_line_col_error) << Arg::Num(relationNode->line) <<
Arg::Num(relationNode->column));
qualifiedName = name;
dsqlScratch->qualifyExistingName(qualifiedName, obj_relation);
relation = METD_get_relation(dsqlScratch->getTransaction(), dsqlScratch, qualifiedName);
}
}
if (procedure && !procedure->prc_out_count)
{
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-84) <<
Arg::Gds(isc_dsql_procedure_use_err) << Arg::Str(procedure->prc_name.toString()) <<
Arg::Gds(isc_dsql_line_col_error) << Arg::Num(relationNode->line) <<
Arg::Num(relationNode->column));
if (!procedure && !relation)
{
const auto errorCode = name.package.hasData() || (procNode && procNode->inputSources) ?
isc_dsql_procedure_err : isc_dsql_relation_err;
ERRD_post(
Arg::Gds(isc_sqlerr) << Arg::Num(-204) <<
Arg::Gds(errorCode) <<
Arg::Gds(isc_random) << name.toQuotedString() <<
Arg::Gds(isc_dsql_line_col_error) << Arg::Num(relationNode->line) << Arg::Num(relationNode->column));
}
name = qualifiedName;
if (procedure)
{
if (procedure->prc_private && name.getSchemaAndPackage() != dsqlScratch->package)
{
status_exception::raise(
Arg::Gds(isc_private_procedure) <<
name.object <<
name.getSchemaAndPackage().toQuotedString());
}
if (!procedure->prc_out_count)
{
ERRD_post(
Arg::Gds(isc_sqlerr) << Arg::Num(-84) <<
Arg::Gds(isc_dsql_procedure_use_err) << name.toQuotedString() <<
Arg::Gds(isc_dsql_line_col_error) <<
Arg::Num(relationNode->line) << Arg::Num(relationNode->column));
}
procNode->dsqlName = name;
}
else if (relNode)
relNode->dsqlName = name;
}
// Set up context block.
@ -469,20 +526,16 @@ dsql_ctx* PASS1_make_context(DsqlCompilerScratch* dsqlScratch, RecordSourceNode*
}
if (str.hasData())
context->ctx_internal_alias = str;
context->ctx_internal_alias = QualifiedName(str);
if (dsqlScratch->aliasRelationPrefix.hasData() && !selNode)
{
if (str.hasData())
str = pass1_alias_concat(dsqlScratch->aliasRelationPrefix, str);
else
str = pass1_alias_concat(dsqlScratch->aliasRelationPrefix, relation_name.c_str());
}
context->ctx_alias = dsqlScratch->aliasRelationPrefix;
if (str.hasData())
{
context->ctx_alias = str;
context->ctx_alias.push(QualifiedName(str));
if (context->ctx_alias.hasData())
{
// check to make sure the context is not already used at this same
// query level (if there are no subqueries, this checks that the
// alias is not used twice in the dsqlScratch).
@ -493,34 +546,45 @@ dsql_ctx* PASS1_make_context(DsqlCompilerScratch* dsqlScratch, RecordSourceNode*
if (conflict->ctx_scope_level != context->ctx_scope_level)
continue;
const TEXT* conflict_name;
ObjectsArray<QualifiedName> conflictNames;
ISC_STATUS error_code;
if (conflict->ctx_alias.hasData())
{
conflict_name = conflict->ctx_alias.c_str();
conflictNames = conflict->ctx_alias;
error_code = isc_alias_conflict_err;
// alias %s conflicts with an alias in the same dsqlScratch.
}
else if (conflict->ctx_procedure)
{
conflict_name = conflict->ctx_procedure->prc_name.identifier.c_str();
conflictNames.add(conflict->ctx_procedure->prc_name);
error_code = isc_procedure_conflict_error;
// alias %s conflicts with a procedure in the same dsqlScratch.
}
else if (conflict->ctx_relation)
{
conflict_name = conflict->ctx_relation->rel_name.c_str();
conflictNames.add(conflict->ctx_relation->rel_name);
error_code = isc_relation_conflict_err;
// alias %s conflicts with a relation in the same dsqlScratch.
}
else
continue;
if (context->ctx_alias == conflict_name)
if (PASS1_compare_alias(context->ctx_alias, conflictNames))
{
fb_assert(conflictNames.hasData());
const auto conflictStr = std::accumulate(
std::next(conflictNames.begin()),
conflictNames.end(),
conflictNames[0].toQuotedString(),
[](const auto& a, const auto& b) {
return a + " " + b.toQuotedString();
}
);
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-204) <<
Arg::Gds(error_code) << Arg::Str(conflict_name));
Arg::Gds(error_code) << conflictStr);
}
}
}
@ -529,7 +593,7 @@ dsql_ctx* PASS1_make_context(DsqlCompilerScratch* dsqlScratch, RecordSourceNode*
{
USHORT count = 0;
if (procNode->inputSources)
if (procNode && procNode->inputSources)
{
context->ctx_proc_inputs = Node::doDsqlPass(dsqlScratch, procNode->inputSources, false);
count = context->ctx_proc_inputs->items.getCount();
@ -538,7 +602,7 @@ dsql_ctx* PASS1_make_context(DsqlCompilerScratch* dsqlScratch, RecordSourceNode*
if (count > procedure->prc_in_count ||
count < procedure->prc_in_count - procedure->prc_def_count)
{
ERRD_post(Arg::Gds(isc_prcmismat) << procNode->dsqlName.toString());
ERRD_post(Arg::Gds(isc_prcmismat) << procNode->dsqlName.toQuotedString());
}
if (count)
@ -595,7 +659,7 @@ dsql_ctx* PASS1_make_context(DsqlCompilerScratch* dsqlScratch, RecordSourceNode*
}
if (mismatchStatus.hasData())
status_exception::raise(Arg::Gds(isc_prcmismat) << procNode->dsqlName.toString() << mismatchStatus);
status_exception::raise(Arg::Gds(isc_prcmismat) << procNode->dsqlName.toQuotedString() << mismatchStatus);
}
}
}
@ -641,70 +705,89 @@ void PASS1_ambiguity_check(DsqlCompilerScratch* dsqlScratch,
if (ambiguous_contexts.getCount() < 2)
return;
TEXT buffer[1024];
USHORT loop = 0;
buffer[0] = 0;
TEXT* b = buffer;
TEXT* p = NULL;
string buffers[2];
string* bufferPtr = &buffers[0];
for (DsqlContextStack::const_iterator stack(ambiguous_contexts); stack.hasData(); ++stack)
{
string& buffer = *bufferPtr;
const dsql_ctx* context = stack.object();
const dsql_rel* relation = context->ctx_relation;
const dsql_prc* procedure = context->ctx_procedure;
if (strlen(b) > (sizeof(buffer) - 50))
{
// Buffer full
break;
}
// if this is the second loop add "and " before relation.
if (++loop > 2)
strcat(buffer, "and ");
if (buffer.hasData())
buffer += " and ";
// Process relation when present.
if (relation)
{
if (!(relation->rel_flags & REL_view))
strcat(buffer, "table ");
buffer += "table ";
else
strcat(buffer, "view ");
strcat(buffer, relation->rel_name.c_str());
buffer += "view ";
buffer += relation->rel_name.toQuotedString();
}
else if (procedure)
{
// Process procedure when present.
strcat(b, "procedure ");
strcat(b, procedure->prc_name.toString().c_str());
buffer += "procedure ";
buffer += procedure->prc_name.toQuotedString();
}
else
{
// When there's no relation and no procedure it's a derived table.
strcat(b, "derived table ");
if (context->ctx_alias.hasData())
strcat(b, context->ctx_alias.c_str());
}
strcat(buffer, " ");
if (!p)
p = b + strlen(b);
}
const auto contextAliases = context->getConcatenatedAlias();
if (p)
*--p = 0;
// When there's no relation and no procedure it's a derived table.
buffer += "derived table ";
if (context->ctx_alias.hasData())
buffer += contextAliases;
}
if (bufferPtr == &buffers[0])
++bufferPtr;
}
if (dsqlScratch->clientDialect >= SQL_DIALECT_V6)
{
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-204) <<
Arg::Gds(isc_dsql_ambiguous_field_name) << Arg::Str(buffer) << Arg::Str(++p) <<
Arg::Gds(isc_dsql_ambiguous_field_name) << buffers[0] << buffers[1] <<
Arg::Gds(isc_random) << name);
}
ERRD_post_warning(Arg::Warning(isc_sqlwarn) << Arg::Num(204) <<
Arg::Warning(isc_dsql_ambiguous_field_name) << Arg::Str(buffer) <<
Arg::Str(++p) <<
Arg::Warning(isc_dsql_ambiguous_field_name) << buffers[0] << buffers[1] <<
Arg::Warning(isc_random) << name);
}
bool PASS1_compare_alias(const QualifiedName& contextAlias, const QualifiedName& lookupAlias)
{
return lookupAlias == contextAlias || lookupAlias.schema.isEmpty() && lookupAlias.object == contextAlias.object;
}
bool PASS1_compare_alias(const ObjectsArray<QualifiedName>& contextAlias,
const ObjectsArray<QualifiedName>& lookupAlias)
{
if (contextAlias.getCount() != lookupAlias.getCount())
return false;
auto contextAliasIt = contextAlias.begin();
for (const auto& lookupAliasIt : lookupAlias)
{
if (!PASS1_compare_alias(*contextAliasIt, lookupAliasIt))
return false;
++contextAliasIt;
}
return true;
}
// Compose two booleans.
BoolExprNode* PASS1_compose(BoolExprNode* expr1, BoolExprNode* expr2, UCHAR blrOp)
{
@ -727,13 +810,12 @@ BoolExprNode* PASS1_compose(BoolExprNode* expr1, BoolExprNode* expr2, UCHAR blrO
void PASS1_field_unknown(const TEXT* qualifier_name, const TEXT* field_name,
const ExprNode* flawed_node)
{
TEXT field_buffer[MAX_SQL_IDENTIFIER_SIZE * 2];
string buffer;
if (qualifier_name)
{
sprintf(field_buffer, "%.*s.%.*s", (int) MAX_SQL_IDENTIFIER_LEN, qualifier_name,
(int) MAX_SQL_IDENTIFIER_LEN, field_name ? field_name : "*");
field_name = field_buffer;
buffer.printf("%s.%s", qualifier_name, (field_name ? field_name : "*"));
field_name = buffer.c_str();
}
if (flawed_node)
@ -941,13 +1023,13 @@ DeclareCursorNode* PASS1_cursor_name(DsqlCompilerScratch* dsqlScratch, const Met
{
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-504) <<
Arg::Gds(isc_dsql_cursor_err) <<
Arg::Gds(isc_dsql_cursor_not_found) << name);
Arg::Gds(isc_dsql_cursor_not_found) << name.toQuotedString());
}
else if (cursor && !existence_flag)
{
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-502) <<
Arg::Gds(isc_dsql_decl_err) <<
Arg::Gds(isc_dsql_cursor_exists) << name);
Arg::Gds(isc_dsql_cursor_exists) << name.toQuotedString());
}
return cursor;
@ -983,14 +1065,14 @@ RseNode* PASS1_derived_table(DsqlCompilerScratch* dsqlScratch, SelectExprNode* i
thread_db* tdbb = JRD_get_thread_data();
MemoryPool& pool = *tdbb->getDefaultPool();
const string& alias = input->alias;
const auto& alias = input->alias;
// Create the context now, because we need to know it for the tables inside.
dsql_ctx* const context = PASS1_make_context(dsqlScratch, input);
// Save some values to restore after rse process.
DsqlContextStack* const req_base = dsqlScratch->context;
const string aliasRelationPrefix = dsqlScratch->aliasRelationPrefix;
const auto aliasRelationPrefix = dsqlScratch->aliasRelationPrefix;
// Change context, because the derived table cannot reference other streams
// at the same scope_level (unless this is a lateral derived table).
@ -1014,7 +1096,9 @@ RseNode* PASS1_derived_table(DsqlCompilerScratch* dsqlScratch, SelectExprNode* i
baseContext = temp.object();
dsqlScratch->context = &temp;
dsqlScratch->aliasRelationPrefix = pass1_alias_concat(aliasRelationPrefix, alias);
if (alias.hasData())
dsqlScratch->aliasRelationPrefix.add(QualifiedName(alias));
RecordSourceNode* query = input->querySpec;
UnionSourceNode* unionQuery = nodeAs<UnionSourceNode>(query);
@ -1101,20 +1185,10 @@ RseNode* PASS1_derived_table(DsqlCompilerScratch* dsqlScratch, SelectExprNode* i
// CVC: prepare a truncated alias for the derived table here
// because we need it several times.
TEXT aliasbuffer[100] = "";
const TEXT* aliasname = aliasbuffer;
string aliasname;
if (alias.hasData())
{
int length = alias.length();
if (length > 99)
{
length = 99;
memcpy(aliasbuffer, alias.c_str(), length);
aliasbuffer[length] = 0;
}
else
aliasname = alias.c_str();
}
aliasname = alias;
else
aliasname = "<unnamed>";
@ -1236,7 +1310,7 @@ RseNode* PASS1_derived_table(DsqlCompilerScratch* dsqlScratch, SelectExprNode* i
const string* const saveCteAlias =
dsqlScratch->currCteAlias ? *dsqlScratch->currCteAlias : NULL;
dsqlScratch->resetCTEAlias(alias);
dsqlScratch->resetCTEAlias(alias.c_str());
rse = PASS1_rse(dsqlScratch, input, select);
@ -1260,7 +1334,10 @@ RseNode* PASS1_derived_table(DsqlCompilerScratch* dsqlScratch, SelectExprNode* i
context->ctx_rse = rse;
if (cte_alias)
context->ctx_alias = cte_alias;
{
context->ctx_alias.clear();
context->ctx_alias.push(QualifiedName(cte_alias));
}
dsqlScratch->context = req_base;
@ -1481,7 +1558,7 @@ static ValueListNode* pass1_group_by_list(DsqlCompilerScratch* dsqlScratch, Valu
if ((field = nodeAs<FieldNode>(sub)))
{
// check for alias or field node
if (selectList && field->dsqlQualifier.isEmpty() && field->dsqlName.hasData())
if (selectList && field->dsqlQualifier.object.isEmpty() && field->dsqlName.hasData())
{
// AB: Check first against the select list for matching column.
// When no matches at all are found we go on with our
@ -1735,31 +1812,11 @@ RecordSourceNode* PASS1_relation(DsqlCompilerScratch* dsqlScratch, RecordSourceN
}
// Concatenate 2 input strings together for a new alias string
// Note: Both input params can be empty.
static string pass1_alias_concat(const string& input1, const string& input2)
{
string output;
if (input1.hasData())
output.append(input1);
if (input2.hasData())
{
if (output.hasData())
output.append(" ");
output.append(input2);
}
return output;
}
// Wrapper for pass1_rse_impl. Substitute recursive CTE alias (if needed) and call pass1_rse_impl.
static RseNode* pass1_rse(DsqlCompilerScratch* dsqlScratch, RecordSourceNode* input,
ValueListNode* order, RowsClause* rows, bool updateLock, bool skipLocked, USHORT flags)
{
string save_alias;
ObjectsArray<QualifiedName> save_alias;
RseNode* rseNode = nodeAs<RseNode>(input);
const bool isRecursive = rseNode && (rseNode->dsqlFlags & RecordSourceNode::DFLAG_RECURSIVE);
AutoSetRestore<USHORT> autoScopeLevel(&dsqlScratch->scopeLevel, dsqlScratch->scopeLevel);
@ -1769,7 +1826,8 @@ static RseNode* pass1_rse(DsqlCompilerScratch* dsqlScratch, RecordSourceNode* in
fb_assert(dsqlScratch->recursiveCtx);
save_alias = dsqlScratch->recursiveCtx->ctx_alias;
dsqlScratch->recursiveCtx->ctx_alias = *dsqlScratch->getNextCTEAlias();
dsqlScratch->recursiveCtx->ctx_alias.clear();
dsqlScratch->recursiveCtx->ctx_alias.add(QualifiedName(*dsqlScratch->getNextCTEAlias()));
// ASF: We need to reset the scope level to the same value found in the non-recursive
// part of the query, to verify usage of aggregate functions correctly. See CORE-4322.
@ -2373,7 +2431,7 @@ ValueListNode* PASS1_sort(DsqlCompilerScratch* dsqlScratch, ValueListNode* input
ValueExprNode* aliasNode = NULL;
// check for alias or field node
if (selectList && field->dsqlQualifier.isEmpty() && field->dsqlName.hasData())
if (selectList && field->dsqlQualifier.object.isEmpty() && field->dsqlName.hasData())
{
// AB: Check first against the select list for matching column.
// When no matches at all are found we go on with our
@ -2608,9 +2666,9 @@ static RseNode* pass1_union(DsqlCompilerScratch* dsqlScratch, UnionSourceNode* i
ptr != end;
++ptr, ++uptr)
{
OrderNode* order1 = nodeAs<OrderNode>(*ptr);
const ValueExprNode* position = order1->value;
const CollateNode* collateNode = nodeAs<CollateNode>(position);
const auto order1 = nodeAs<OrderNode>(*ptr);
auto position = order1->value;
const auto collateNode = nodeAs<CollateNode>(position);
if (collateNode)
position = collateNode->arg;

View File

@ -39,6 +39,9 @@ namespace Jrd
}
void PASS1_ambiguity_check(Jrd::DsqlCompilerScratch*, const Jrd::MetaName&, const Jrd::DsqlContextStack&);
bool PASS1_compare_alias(const Jrd::QualifiedName& contextAlias, const Jrd::QualifiedName& lookupAlias);
bool PASS1_compare_alias(const Firebird::ObjectsArray<Jrd::QualifiedName>& contextAlias,
const Firebird::ObjectsArray<Jrd::QualifiedName>& lookupAlias);
Jrd::BoolExprNode* PASS1_compose(Jrd::BoolExprNode*, Jrd::BoolExprNode*, UCHAR);
Jrd::DeclareCursorNode* PASS1_cursor_name(Jrd::DsqlCompilerScratch*, const Jrd::MetaName&, USHORT, bool);
Jrd::RseNode* PASS1_derived_table(Jrd::DsqlCompilerScratch*, Jrd::SelectExprNode*, const char*,

View File

@ -816,7 +816,7 @@ void SQL_par_field_dtype(gpre_req* request, gpre_fld* field, bool is_udf)
if (field->fld_flags & FLD_national)
{
gpre_sym* symbol = MSC_find_symbol(HSH_lookup(DEFAULT_CHARACTER_SET_NAME), SYM_charset);
gpre_sym* symbol = MSC_find_symbol(HSH_lookup(NATIONAL_CHARACTER_SET), SYM_charset);
if (!symbol)
{
PAR_error("NATIONAL character set missing");

View File

@ -173,6 +173,8 @@ bool MET_database(gpre_dbb* database, bool print_version)
}
#endif
dpb.insertString(isc_dpb_search_path, SYSTEM_SCHEMA, fb_strlen(SYSTEM_SCHEMA));
if (isc_attach_database(gds_status, 0, database->dbb_filename, &DB,
dpb.getBufferLength(),
reinterpret_cast<const char*>(dpb.getBuffer())))

View File

@ -408,6 +408,9 @@ interface MessageMetadata : ReferenceCounted
version: // 3.0 => 4.0
uint getAlignment(Status status);
uint getAlignedLength(Status status);
version: // 5.0 => 6.0 Alpha1
const string getSchema(Status status, uint index);
}
interface MetadataBuilder : ReferenceCounted
@ -430,6 +433,9 @@ version: // 3.0 => 4.0
void setRelation(Status status, uint index, const string relation);
void setOwner(Status status, uint index, const string owner);
void setAlias(Status status, uint index, const string alias);
version: // 5.0 => 6.0 Alpha1
void setSchema(Status status, uint index, const string schema);
}
interface ResultSet : ReferenceCounted
@ -1132,6 +1138,9 @@ interface RoutineMetadata : Versioned
MessageMetadata getTriggerMetadata(Status status) const;
const string getTriggerTable(Status status) const;
uint getTriggerType(Status status) const;
version: // 5.0 => 6.0 Alpha1
const string getSchema(Status status) const;
}
@ -1228,6 +1237,12 @@ version: // 4.0 Beta1 => 4.0 Beta2
uint* fractions, uint timeZoneBufferLength, string timeZoneBuffer);
void decodeTimeStampTzEx(Status status, const ISC_TIMESTAMP_TZ_EX* timeStampTz, uint* year, uint* month, uint* day,
uint* hours, uint* minutes, uint* seconds, uint* fractions, uint timeZoneBufferLength, string timeZoneBuffer);
version: // 5.0 => 6.0 Alpha1
Attachment executeCreateDatabase2(Status status,
uint stmtLength, const string creatDBstatement, uint dialect,
uint dpbLength, const uchar* dpb,
boolean* stmtIsCreateDb);
}
interface OffsetsCallback : Versioned
@ -1742,16 +1757,24 @@ interface ReplicatedTransaction : Disposable
void rollbackSavepoint(Status status);
// ReplicatedRecords parameters point to local objects, do not ever store the pointer.
void insertRecord(Status status, const string name,
ReplicatedRecord record);
void updateRecord(Status status, const string name,
ReplicatedRecord orgRecord,
ReplicatedRecord newRecord);
void deleteRecord(Status status, const string name,
ReplicatedRecord record);
void deprecatedInsertRecord(Status status, const string name, ReplicatedRecord record);
void deprecatedUpdateRecord(Status status, const string name,
ReplicatedRecord orgRecord, ReplicatedRecord newRecord);
void deprecatedDeleteRecord(Status status, const string name, ReplicatedRecord record);
void executeSql(Status status, const string sql);
void executeSqlIntl(Status status, uint charset, const string sql);
void deprecatedExecuteSql(Status status, const string sql);
void deprecatedExecuteSqlIntl(Status status, uint charset, const string sql);
version: // 5.0 => 6.0 Alpha1
// ReplicatedRecords parameters point to local objects, do not ever store the pointer.
void insertRecord2(Status status, const string schemaName, const string tableName,
ReplicatedRecord record);
void updateRecord2(Status status, const string schemaName, const string tableName,
ReplicatedRecord orgRecord, ReplicatedRecord newRecord);
void deleteRecord2(Status status, const string schemaName, const string tableName,
ReplicatedRecord record);
void executeSqlIntl2(Status status, uint charset, const string schemaSearchPath, const string sql);
}
interface ReplicatedSession : PluginBase
@ -1761,7 +1784,10 @@ interface ReplicatedSession : PluginBase
ReplicatedTransaction startTransaction(Status status, Transaction transaction, int64 number);
void cleanupTransaction(Status status, int64 number);
void setSequence(Status status, const string name, int64 value);
void deprecatedSetSequence(Status status, const string name, int64 value);
version: // 5.0 => 6.0 Alpha1
void setSequence2(Status status, const string schemaName, const string genName, int64 value);
}
// Profiler interfaces
@ -1789,7 +1815,7 @@ interface ProfilerSession : Disposable
void finish(Status status, ISC_TIMESTAMP_TZ timestamp);
void defineStatement(Status status, int64 statementId, int64 parentStatementId,
void deprecatedDefineStatement(Status status, int64 statementId, int64 parentStatementId,
const string type, const string packageName, const string routineName, const string sqlText);
void defineCursor(int64 statementId, uint cursorId, const string name, uint line, uint column);
@ -1813,6 +1839,13 @@ interface ProfilerSession : Disposable
void beforeRecordSourceGetRecord(int64 statementId, int64 requestId, uint cursorId, uint recSourceId);
void afterRecordSourceGetRecord(int64 statementId, int64 requestId, uint cursorId, uint recSourceId,
ProfilerStats stats);
version: // 5.0 => 6.0 Alpha1
[notImplementedAction call deprecatedDefineStatement(status, statementId, parentStatementId,
type, packageName, routineName, sqlText)]
void defineStatement2(Status status, int64 statementId, int64 parentStatementId,
const string type, const string schemaName, const string packageName, const string routineName,
const string sqlText);
}
interface ProfilerStats : Versioned

View File

@ -1365,7 +1365,7 @@ namespace Firebird
}
};
#define FIREBIRD_IMESSAGE_METADATA_VERSION 4u
#define FIREBIRD_IMESSAGE_METADATA_VERSION 5u
class IMessageMetadata : public IReferenceCounted
{
@ -1389,6 +1389,7 @@ namespace Firebird
unsigned (CLOOP_CARG *getMessageLength)(IMessageMetadata* self, IStatus* status) CLOOP_NOEXCEPT;
unsigned (CLOOP_CARG *getAlignment)(IMessageMetadata* self, IStatus* status) CLOOP_NOEXCEPT;
unsigned (CLOOP_CARG *getAlignedLength)(IMessageMetadata* self, IStatus* status) CLOOP_NOEXCEPT;
const char* (CLOOP_CARG *getSchema)(IMessageMetadata* self, IStatus* status, unsigned index) CLOOP_NOEXCEPT;
};
protected:
@ -1551,9 +1552,23 @@ namespace Firebird
StatusType::checkException(status);
return ret;
}
template <typename StatusType> const char* getSchema(StatusType* status, unsigned index)
{
if (cloopVTable->version < 5)
{
StatusType::setVersionError(status, "IMessageMetadata", cloopVTable->version, 5);
StatusType::checkException(status);
return 0;
}
StatusType::clearException(status);
const char* ret = static_cast<VTable*>(this->cloopVTable)->getSchema(this, status, index);
StatusType::checkException(status);
return ret;
}
};
#define FIREBIRD_IMETADATA_BUILDER_VERSION 4u
#define FIREBIRD_IMETADATA_BUILDER_VERSION 5u
class IMetadataBuilder : public IReferenceCounted
{
@ -1574,6 +1589,7 @@ namespace Firebird
void (CLOOP_CARG *setRelation)(IMetadataBuilder* self, IStatus* status, unsigned index, const char* relation) CLOOP_NOEXCEPT;
void (CLOOP_CARG *setOwner)(IMetadataBuilder* self, IStatus* status, unsigned index, const char* owner) CLOOP_NOEXCEPT;
void (CLOOP_CARG *setAlias)(IMetadataBuilder* self, IStatus* status, unsigned index, const char* alias) CLOOP_NOEXCEPT;
void (CLOOP_CARG *setSchema)(IMetadataBuilder* self, IStatus* status, unsigned index, const char* schema) CLOOP_NOEXCEPT;
};
protected:
@ -1712,6 +1728,19 @@ namespace Firebird
static_cast<VTable*>(this->cloopVTable)->setAlias(this, status, index, alias);
StatusType::checkException(status);
}
template <typename StatusType> void setSchema(StatusType* status, unsigned index, const char* schema)
{
if (cloopVTable->version < 5)
{
StatusType::setVersionError(status, "IMetadataBuilder", cloopVTable->version, 5);
StatusType::checkException(status);
return;
}
StatusType::clearException(status);
static_cast<VTable*>(this->cloopVTable)->setSchema(this, status, index, schema);
StatusType::checkException(status);
}
};
#define FIREBIRD_IRESULT_SET_VERSION 5u
@ -4376,7 +4405,7 @@ namespace Firebird
}
};
#define FIREBIRD_IROUTINE_METADATA_VERSION 2u
#define FIREBIRD_IROUTINE_METADATA_VERSION 3u
class IRoutineMetadata : public IVersioned
{
@ -4392,6 +4421,7 @@ namespace Firebird
IMessageMetadata* (CLOOP_CARG *getTriggerMetadata)(const IRoutineMetadata* self, IStatus* status) CLOOP_NOEXCEPT;
const char* (CLOOP_CARG *getTriggerTable)(const IRoutineMetadata* self, IStatus* status) CLOOP_NOEXCEPT;
unsigned (CLOOP_CARG *getTriggerType)(const IRoutineMetadata* self, IStatus* status) CLOOP_NOEXCEPT;
const char* (CLOOP_CARG *getSchema)(const IRoutineMetadata* self, IStatus* status) CLOOP_NOEXCEPT;
};
protected:
@ -4478,6 +4508,20 @@ namespace Firebird
StatusType::checkException(status);
return ret;
}
template <typename StatusType> const char* getSchema(StatusType* status) const
{
if (cloopVTable->version < 3)
{
StatusType::setVersionError(status, "IRoutineMetadata", cloopVTable->version, 3);
StatusType::checkException(status);
return 0;
}
StatusType::clearException(status);
const char* ret = static_cast<VTable*>(this->cloopVTable)->getSchema(this, status);
StatusType::checkException(status);
return ret;
}
};
#define FIREBIRD_IEXTERNAL_ENGINE_VERSION 4u
@ -4653,7 +4697,7 @@ namespace Firebird
}
};
#define FIREBIRD_IUTIL_VERSION 4u
#define FIREBIRD_IUTIL_VERSION 5u
class IUtil : public IVersioned
{
@ -4682,6 +4726,7 @@ namespace Firebird
IInt128* (CLOOP_CARG *getInt128)(IUtil* self, IStatus* status) CLOOP_NOEXCEPT;
void (CLOOP_CARG *decodeTimeTzEx)(IUtil* self, IStatus* status, const ISC_TIME_TZ_EX* timeTz, unsigned* hours, unsigned* minutes, unsigned* seconds, unsigned* fractions, unsigned timeZoneBufferLength, char* timeZoneBuffer) CLOOP_NOEXCEPT;
void (CLOOP_CARG *decodeTimeStampTzEx)(IUtil* self, IStatus* status, const ISC_TIMESTAMP_TZ_EX* timeStampTz, unsigned* year, unsigned* month, unsigned* day, unsigned* hours, unsigned* minutes, unsigned* seconds, unsigned* fractions, unsigned timeZoneBufferLength, char* timeZoneBuffer) CLOOP_NOEXCEPT;
IAttachment* (CLOOP_CARG *executeCreateDatabase2)(IUtil* self, IStatus* status, unsigned stmtLength, const char* creatDBstatement, unsigned dialect, unsigned dpbLength, const unsigned char* dpb, FB_BOOLEAN* stmtIsCreateDb) CLOOP_NOEXCEPT;
};
protected:
@ -4902,6 +4947,20 @@ namespace Firebird
static_cast<VTable*>(this->cloopVTable)->decodeTimeStampTzEx(this, status, timeStampTz, year, month, day, hours, minutes, seconds, fractions, timeZoneBufferLength, timeZoneBuffer);
StatusType::checkException(status);
}
template <typename StatusType> IAttachment* executeCreateDatabase2(StatusType* status, unsigned stmtLength, const char* creatDBstatement, unsigned dialect, unsigned dpbLength, const unsigned char* dpb, FB_BOOLEAN* stmtIsCreateDb)
{
if (cloopVTable->version < 5)
{
StatusType::setVersionError(status, "IUtil", cloopVTable->version, 5);
StatusType::checkException(status);
return 0;
}
StatusType::clearException(status);
IAttachment* ret = static_cast<VTable*>(this->cloopVTable)->executeCreateDatabase2(this, status, stmtLength, creatDBstatement, dialect, dpbLength, dpb, stmtIsCreateDb);
StatusType::checkException(status);
return ret;
}
};
#define FIREBIRD_IOFFSETS_CALLBACK_VERSION 2u
@ -6890,7 +6949,7 @@ namespace Firebird
}
};
#define FIREBIRD_IREPLICATED_TRANSACTION_VERSION 3u
#define FIREBIRD_IREPLICATED_TRANSACTION_VERSION 4u
class IReplicatedTransaction : public IDisposable
{
@ -6903,11 +6962,15 @@ namespace Firebird
void (CLOOP_CARG *startSavepoint)(IReplicatedTransaction* self, IStatus* status) CLOOP_NOEXCEPT;
void (CLOOP_CARG *releaseSavepoint)(IReplicatedTransaction* self, IStatus* status) CLOOP_NOEXCEPT;
void (CLOOP_CARG *rollbackSavepoint)(IReplicatedTransaction* self, IStatus* status) CLOOP_NOEXCEPT;
void (CLOOP_CARG *insertRecord)(IReplicatedTransaction* self, IStatus* status, const char* name, IReplicatedRecord* record) CLOOP_NOEXCEPT;
void (CLOOP_CARG *updateRecord)(IReplicatedTransaction* self, IStatus* status, const char* name, IReplicatedRecord* orgRecord, IReplicatedRecord* newRecord) CLOOP_NOEXCEPT;
void (CLOOP_CARG *deleteRecord)(IReplicatedTransaction* self, IStatus* status, const char* name, IReplicatedRecord* record) CLOOP_NOEXCEPT;
void (CLOOP_CARG *executeSql)(IReplicatedTransaction* self, IStatus* status, const char* sql) CLOOP_NOEXCEPT;
void (CLOOP_CARG *executeSqlIntl)(IReplicatedTransaction* self, IStatus* status, unsigned charset, const char* sql) CLOOP_NOEXCEPT;
void (CLOOP_CARG *deprecatedInsertRecord)(IReplicatedTransaction* self, IStatus* status, const char* name, IReplicatedRecord* record) CLOOP_NOEXCEPT;
void (CLOOP_CARG *deprecatedUpdateRecord)(IReplicatedTransaction* self, IStatus* status, const char* name, IReplicatedRecord* orgRecord, IReplicatedRecord* newRecord) CLOOP_NOEXCEPT;
void (CLOOP_CARG *deprecatedDeleteRecord)(IReplicatedTransaction* self, IStatus* status, const char* name, IReplicatedRecord* record) CLOOP_NOEXCEPT;
void (CLOOP_CARG *deprecatedExecuteSql)(IReplicatedTransaction* self, IStatus* status, const char* sql) CLOOP_NOEXCEPT;
void (CLOOP_CARG *deprecatedExecuteSqlIntl)(IReplicatedTransaction* self, IStatus* status, unsigned charset, const char* sql) CLOOP_NOEXCEPT;
void (CLOOP_CARG *insertRecord2)(IReplicatedTransaction* self, IStatus* status, const char* schemaName, const char* tableName, IReplicatedRecord* record) CLOOP_NOEXCEPT;
void (CLOOP_CARG *updateRecord2)(IReplicatedTransaction* self, IStatus* status, const char* schemaName, const char* tableName, IReplicatedRecord* orgRecord, IReplicatedRecord* newRecord) CLOOP_NOEXCEPT;
void (CLOOP_CARG *deleteRecord2)(IReplicatedTransaction* self, IStatus* status, const char* schemaName, const char* tableName, IReplicatedRecord* record) CLOOP_NOEXCEPT;
void (CLOOP_CARG *executeSqlIntl2)(IReplicatedTransaction* self, IStatus* status, unsigned charset, const char* schemaSearchPath, const char* sql) CLOOP_NOEXCEPT;
};
protected:
@ -6965,43 +7028,95 @@ namespace Firebird
StatusType::checkException(status);
}
template <typename StatusType> void insertRecord(StatusType* status, const char* name, IReplicatedRecord* record)
template <typename StatusType> void deprecatedInsertRecord(StatusType* status, const char* name, IReplicatedRecord* record)
{
StatusType::clearException(status);
static_cast<VTable*>(this->cloopVTable)->insertRecord(this, status, name, record);
static_cast<VTable*>(this->cloopVTable)->deprecatedInsertRecord(this, status, name, record);
StatusType::checkException(status);
}
template <typename StatusType> void updateRecord(StatusType* status, const char* name, IReplicatedRecord* orgRecord, IReplicatedRecord* newRecord)
template <typename StatusType> void deprecatedUpdateRecord(StatusType* status, const char* name, IReplicatedRecord* orgRecord, IReplicatedRecord* newRecord)
{
StatusType::clearException(status);
static_cast<VTable*>(this->cloopVTable)->updateRecord(this, status, name, orgRecord, newRecord);
static_cast<VTable*>(this->cloopVTable)->deprecatedUpdateRecord(this, status, name, orgRecord, newRecord);
StatusType::checkException(status);
}
template <typename StatusType> void deleteRecord(StatusType* status, const char* name, IReplicatedRecord* record)
template <typename StatusType> void deprecatedDeleteRecord(StatusType* status, const char* name, IReplicatedRecord* record)
{
StatusType::clearException(status);
static_cast<VTable*>(this->cloopVTable)->deleteRecord(this, status, name, record);
static_cast<VTable*>(this->cloopVTable)->deprecatedDeleteRecord(this, status, name, record);
StatusType::checkException(status);
}
template <typename StatusType> void executeSql(StatusType* status, const char* sql)
template <typename StatusType> void deprecatedExecuteSql(StatusType* status, const char* sql)
{
StatusType::clearException(status);
static_cast<VTable*>(this->cloopVTable)->executeSql(this, status, sql);
static_cast<VTable*>(this->cloopVTable)->deprecatedExecuteSql(this, status, sql);
StatusType::checkException(status);
}
template <typename StatusType> void executeSqlIntl(StatusType* status, unsigned charset, const char* sql)
template <typename StatusType> void deprecatedExecuteSqlIntl(StatusType* status, unsigned charset, const char* sql)
{
StatusType::clearException(status);
static_cast<VTable*>(this->cloopVTable)->executeSqlIntl(this, status, charset, sql);
static_cast<VTable*>(this->cloopVTable)->deprecatedExecuteSqlIntl(this, status, charset, sql);
StatusType::checkException(status);
}
template <typename StatusType> void insertRecord2(StatusType* status, const char* schemaName, const char* tableName, IReplicatedRecord* record)
{
if (cloopVTable->version < 4)
{
StatusType::setVersionError(status, "IReplicatedTransaction", cloopVTable->version, 4);
StatusType::checkException(status);
return;
}
StatusType::clearException(status);
static_cast<VTable*>(this->cloopVTable)->insertRecord2(this, status, schemaName, tableName, record);
StatusType::checkException(status);
}
template <typename StatusType> void updateRecord2(StatusType* status, const char* schemaName, const char* tableName, IReplicatedRecord* orgRecord, IReplicatedRecord* newRecord)
{
if (cloopVTable->version < 4)
{
StatusType::setVersionError(status, "IReplicatedTransaction", cloopVTable->version, 4);
StatusType::checkException(status);
return;
}
StatusType::clearException(status);
static_cast<VTable*>(this->cloopVTable)->updateRecord2(this, status, schemaName, tableName, orgRecord, newRecord);
StatusType::checkException(status);
}
template <typename StatusType> void deleteRecord2(StatusType* status, const char* schemaName, const char* tableName, IReplicatedRecord* record)
{
if (cloopVTable->version < 4)
{
StatusType::setVersionError(status, "IReplicatedTransaction", cloopVTable->version, 4);
StatusType::checkException(status);
return;
}
StatusType::clearException(status);
static_cast<VTable*>(this->cloopVTable)->deleteRecord2(this, status, schemaName, tableName, record);
StatusType::checkException(status);
}
template <typename StatusType> void executeSqlIntl2(StatusType* status, unsigned charset, const char* schemaSearchPath, const char* sql)
{
if (cloopVTable->version < 4)
{
StatusType::setVersionError(status, "IReplicatedTransaction", cloopVTable->version, 4);
StatusType::checkException(status);
return;
}
StatusType::clearException(status);
static_cast<VTable*>(this->cloopVTable)->executeSqlIntl2(this, status, charset, schemaSearchPath, sql);
StatusType::checkException(status);
}
};
#define FIREBIRD_IREPLICATED_SESSION_VERSION 4u
#define FIREBIRD_IREPLICATED_SESSION_VERSION 5u
class IReplicatedSession : public IPluginBase
{
@ -7011,7 +7126,8 @@ namespace Firebird
FB_BOOLEAN (CLOOP_CARG *init)(IReplicatedSession* self, IStatus* status, IAttachment* attachment) CLOOP_NOEXCEPT;
IReplicatedTransaction* (CLOOP_CARG *startTransaction)(IReplicatedSession* self, IStatus* status, ITransaction* transaction, ISC_INT64 number) CLOOP_NOEXCEPT;
void (CLOOP_CARG *cleanupTransaction)(IReplicatedSession* self, IStatus* status, ISC_INT64 number) CLOOP_NOEXCEPT;
void (CLOOP_CARG *setSequence)(IReplicatedSession* self, IStatus* status, const char* name, ISC_INT64 value) CLOOP_NOEXCEPT;
void (CLOOP_CARG *deprecatedSetSequence)(IReplicatedSession* self, IStatus* status, const char* name, ISC_INT64 value) CLOOP_NOEXCEPT;
void (CLOOP_CARG *setSequence2)(IReplicatedSession* self, IStatus* status, const char* schemaName, const char* genName, ISC_INT64 value) CLOOP_NOEXCEPT;
};
protected:
@ -7050,10 +7166,23 @@ namespace Firebird
StatusType::checkException(status);
}
template <typename StatusType> void setSequence(StatusType* status, const char* name, ISC_INT64 value)
template <typename StatusType> void deprecatedSetSequence(StatusType* status, const char* name, ISC_INT64 value)
{
StatusType::clearException(status);
static_cast<VTable*>(this->cloopVTable)->setSequence(this, status, name, value);
static_cast<VTable*>(this->cloopVTable)->deprecatedSetSequence(this, status, name, value);
StatusType::checkException(status);
}
template <typename StatusType> void setSequence2(StatusType* status, const char* schemaName, const char* genName, ISC_INT64 value)
{
if (cloopVTable->version < 5)
{
StatusType::setVersionError(status, "IReplicatedSession", cloopVTable->version, 5);
StatusType::checkException(status);
return;
}
StatusType::clearException(status);
static_cast<VTable*>(this->cloopVTable)->setSequence2(this, status, schemaName, genName, value);
StatusType::checkException(status);
}
};
@ -7106,7 +7235,7 @@ namespace Firebird
}
};
#define FIREBIRD_IPROFILER_SESSION_VERSION 3u
#define FIREBIRD_IPROFILER_SESSION_VERSION 4u
class IProfilerSession : public IDisposable
{
@ -7117,7 +7246,7 @@ namespace Firebird
unsigned (CLOOP_CARG *getFlags)(IProfilerSession* self) CLOOP_NOEXCEPT;
void (CLOOP_CARG *cancel)(IProfilerSession* self, IStatus* status) CLOOP_NOEXCEPT;
void (CLOOP_CARG *finish)(IProfilerSession* self, IStatus* status, ISC_TIMESTAMP_TZ timestamp) CLOOP_NOEXCEPT;
void (CLOOP_CARG *defineStatement)(IProfilerSession* self, IStatus* status, ISC_INT64 statementId, ISC_INT64 parentStatementId, const char* type, const char* packageName, const char* routineName, const char* sqlText) CLOOP_NOEXCEPT;
void (CLOOP_CARG *deprecatedDefineStatement)(IProfilerSession* self, IStatus* status, ISC_INT64 statementId, ISC_INT64 parentStatementId, const char* type, const char* packageName, const char* routineName, const char* sqlText) CLOOP_NOEXCEPT;
void (CLOOP_CARG *defineCursor)(IProfilerSession* self, ISC_INT64 statementId, unsigned cursorId, const char* name, unsigned line, unsigned column) CLOOP_NOEXCEPT;
void (CLOOP_CARG *defineRecordSource)(IProfilerSession* self, ISC_INT64 statementId, unsigned cursorId, unsigned recSourceId, unsigned level, const char* accessPath, unsigned parentRecSourceId) CLOOP_NOEXCEPT;
void (CLOOP_CARG *onRequestStart)(IProfilerSession* self, IStatus* status, ISC_INT64 statementId, ISC_INT64 requestId, ISC_INT64 callerStatementId, ISC_INT64 callerRequestId, ISC_TIMESTAMP_TZ timestamp) CLOOP_NOEXCEPT;
@ -7128,6 +7257,7 @@ namespace Firebird
void (CLOOP_CARG *afterRecordSourceOpen)(IProfilerSession* self, ISC_INT64 statementId, ISC_INT64 requestId, unsigned cursorId, unsigned recSourceId, IProfilerStats* stats) CLOOP_NOEXCEPT;
void (CLOOP_CARG *beforeRecordSourceGetRecord)(IProfilerSession* self, ISC_INT64 statementId, ISC_INT64 requestId, unsigned cursorId, unsigned recSourceId) CLOOP_NOEXCEPT;
void (CLOOP_CARG *afterRecordSourceGetRecord)(IProfilerSession* self, ISC_INT64 statementId, ISC_INT64 requestId, unsigned cursorId, unsigned recSourceId, IProfilerStats* stats) CLOOP_NOEXCEPT;
void (CLOOP_CARG *defineStatement2)(IProfilerSession* self, IStatus* status, ISC_INT64 statementId, ISC_INT64 parentStatementId, const char* type, const char* schemaName, const char* packageName, const char* routineName, const char* sqlText) CLOOP_NOEXCEPT;
};
protected:
@ -7172,10 +7302,10 @@ namespace Firebird
StatusType::checkException(status);
}
template <typename StatusType> void defineStatement(StatusType* status, ISC_INT64 statementId, ISC_INT64 parentStatementId, const char* type, const char* packageName, const char* routineName, const char* sqlText)
template <typename StatusType> void deprecatedDefineStatement(StatusType* status, ISC_INT64 statementId, ISC_INT64 parentStatementId, const char* type, const char* packageName, const char* routineName, const char* sqlText)
{
StatusType::clearException(status);
static_cast<VTable*>(this->cloopVTable)->defineStatement(this, status, statementId, parentStatementId, type, packageName, routineName, sqlText);
static_cast<VTable*>(this->cloopVTable)->deprecatedDefineStatement(this, status, statementId, parentStatementId, type, packageName, routineName, sqlText);
StatusType::checkException(status);
}
@ -7232,6 +7362,18 @@ namespace Firebird
{
static_cast<VTable*>(this->cloopVTable)->afterRecordSourceGetRecord(this, statementId, requestId, cursorId, recSourceId, stats);
}
template <typename StatusType> void defineStatement2(StatusType* status, ISC_INT64 statementId, ISC_INT64 parentStatementId, const char* type, const char* schemaName, const char* packageName, const char* routineName, const char* sqlText)
{
if (cloopVTable->version < 4)
{
deprecatedDefineStatement(status, statementId, parentStatementId, type, packageName, routineName, sqlText);
return;
}
StatusType::clearException(status);
static_cast<VTable*>(this->cloopVTable)->defineStatement2(this, status, statementId, parentStatementId, type, schemaName, packageName, routineName, sqlText);
StatusType::checkException(status);
}
};
#define FIREBIRD_IPROFILER_STATS_VERSION 2u
@ -9609,6 +9751,7 @@ namespace Firebird
this->getMessageLength = &Name::cloopgetMessageLengthDispatcher;
this->getAlignment = &Name::cloopgetAlignmentDispatcher;
this->getAlignedLength = &Name::cloopgetAlignedLengthDispatcher;
this->getSchema = &Name::cloopgetSchemaDispatcher;
}
} vTable;
@ -9870,6 +10013,21 @@ namespace Firebird
}
}
static const char* CLOOP_CARG cloopgetSchemaDispatcher(IMessageMetadata* self, IStatus* status, unsigned index) CLOOP_NOEXCEPT
{
StatusType status2(status);
try
{
return static_cast<Name*>(self)->Name::getSchema(&status2, index);
}
catch (...)
{
StatusType::catchException(&status2);
return static_cast<const char*>(0);
}
}
static void CLOOP_CARG cloopaddRefDispatcher(IReferenceCounted* self) CLOOP_NOEXCEPT
{
try
@ -9926,6 +10084,7 @@ namespace Firebird
virtual unsigned getMessageLength(StatusType* status) = 0;
virtual unsigned getAlignment(StatusType* status) = 0;
virtual unsigned getAlignedLength(StatusType* status) = 0;
virtual const char* getSchema(StatusType* status, unsigned index) = 0;
};
template <typename Name, typename StatusType, typename Base>
@ -9957,6 +10116,7 @@ namespace Firebird
this->setRelation = &Name::cloopsetRelationDispatcher;
this->setOwner = &Name::cloopsetOwnerDispatcher;
this->setAlias = &Name::cloopsetAliasDispatcher;
this->setSchema = &Name::cloopsetSchemaDispatcher;
}
} vTable;
@ -10161,6 +10321,20 @@ namespace Firebird
}
}
static void CLOOP_CARG cloopsetSchemaDispatcher(IMetadataBuilder* self, IStatus* status, unsigned index, const char* schema) CLOOP_NOEXCEPT
{
StatusType status2(status);
try
{
static_cast<Name*>(self)->Name::setSchema(&status2, index, schema);
}
catch (...)
{
StatusType::catchException(&status2);
}
}
static void CLOOP_CARG cloopaddRefDispatcher(IReferenceCounted* self) CLOOP_NOEXCEPT
{
try
@ -10214,6 +10388,7 @@ namespace Firebird
virtual void setRelation(StatusType* status, unsigned index, const char* relation) = 0;
virtual void setOwner(StatusType* status, unsigned index, const char* owner) = 0;
virtual void setAlias(StatusType* status, unsigned index, const char* alias) = 0;
virtual void setSchema(StatusType* status, unsigned index, const char* schema) = 0;
};
template <typename Name, typename StatusType, typename Base>
@ -15404,6 +15579,7 @@ namespace Firebird
this->getTriggerMetadata = &Name::cloopgetTriggerMetadataDispatcher;
this->getTriggerTable = &Name::cloopgetTriggerTableDispatcher;
this->getTriggerType = &Name::cloopgetTriggerTypeDispatcher;
this->getSchema = &Name::cloopgetSchemaDispatcher;
}
} vTable;
@ -15544,6 +15720,21 @@ namespace Firebird
return static_cast<unsigned>(0);
}
}
static const char* CLOOP_CARG cloopgetSchemaDispatcher(const IRoutineMetadata* self, IStatus* status) CLOOP_NOEXCEPT
{
StatusType status2(status);
try
{
return static_cast<const Name*>(self)->Name::getSchema(&status2);
}
catch (...)
{
StatusType::catchException(&status2);
return static_cast<const char*>(0);
}
}
};
template <typename Name, typename StatusType, typename Base = IVersionedImpl<Name, StatusType, Inherit<IRoutineMetadata> > >
@ -15568,6 +15759,7 @@ namespace Firebird
virtual IMessageMetadata* getTriggerMetadata(StatusType* status) const = 0;
virtual const char* getTriggerTable(StatusType* status) const = 0;
virtual unsigned getTriggerType(StatusType* status) const = 0;
virtual const char* getSchema(StatusType* status) const = 0;
};
template <typename Name, typename StatusType, typename Base>
@ -15987,6 +16179,7 @@ namespace Firebird
this->getInt128 = &Name::cloopgetInt128Dispatcher;
this->decodeTimeTzEx = &Name::cloopdecodeTimeTzExDispatcher;
this->decodeTimeStampTzEx = &Name::cloopdecodeTimeStampTzExDispatcher;
this->executeCreateDatabase2 = &Name::cloopexecuteCreateDatabase2Dispatcher;
}
} vTable;
@ -16298,6 +16491,21 @@ namespace Firebird
StatusType::catchException(&status2);
}
}
static IAttachment* CLOOP_CARG cloopexecuteCreateDatabase2Dispatcher(IUtil* self, IStatus* status, unsigned stmtLength, const char* creatDBstatement, unsigned dialect, unsigned dpbLength, const unsigned char* dpb, FB_BOOLEAN* stmtIsCreateDb) CLOOP_NOEXCEPT
{
StatusType status2(status);
try
{
return static_cast<Name*>(self)->Name::executeCreateDatabase2(&status2, stmtLength, creatDBstatement, dialect, dpbLength, dpb, stmtIsCreateDb);
}
catch (...)
{
StatusType::catchException(&status2);
return static_cast<IAttachment*>(0);
}
}
};
template <typename Name, typename StatusType, typename Base = IVersionedImpl<Name, StatusType, Inherit<IUtil> > >
@ -16335,6 +16543,7 @@ namespace Firebird
virtual IInt128* getInt128(StatusType* status) = 0;
virtual void decodeTimeTzEx(StatusType* status, const ISC_TIME_TZ_EX* timeTz, unsigned* hours, unsigned* minutes, unsigned* seconds, unsigned* fractions, unsigned timeZoneBufferLength, char* timeZoneBuffer) = 0;
virtual void decodeTimeStampTzEx(StatusType* status, const ISC_TIMESTAMP_TZ_EX* timeStampTz, unsigned* year, unsigned* month, unsigned* day, unsigned* hours, unsigned* minutes, unsigned* seconds, unsigned* fractions, unsigned timeZoneBufferLength, char* timeZoneBuffer) = 0;
virtual IAttachment* executeCreateDatabase2(StatusType* status, unsigned stmtLength, const char* creatDBstatement, unsigned dialect, unsigned dpbLength, const unsigned char* dpb, FB_BOOLEAN* stmtIsCreateDb) = 0;
};
template <typename Name, typename StatusType, typename Base>
@ -20297,11 +20506,15 @@ namespace Firebird
this->startSavepoint = &Name::cloopstartSavepointDispatcher;
this->releaseSavepoint = &Name::cloopreleaseSavepointDispatcher;
this->rollbackSavepoint = &Name::clooprollbackSavepointDispatcher;
this->insertRecord = &Name::cloopinsertRecordDispatcher;
this->updateRecord = &Name::cloopupdateRecordDispatcher;
this->deleteRecord = &Name::cloopdeleteRecordDispatcher;
this->executeSql = &Name::cloopexecuteSqlDispatcher;
this->executeSqlIntl = &Name::cloopexecuteSqlIntlDispatcher;
this->deprecatedInsertRecord = &Name::cloopdeprecatedInsertRecordDispatcher;
this->deprecatedUpdateRecord = &Name::cloopdeprecatedUpdateRecordDispatcher;
this->deprecatedDeleteRecord = &Name::cloopdeprecatedDeleteRecordDispatcher;
this->deprecatedExecuteSql = &Name::cloopdeprecatedExecuteSqlDispatcher;
this->deprecatedExecuteSqlIntl = &Name::cloopdeprecatedExecuteSqlIntlDispatcher;
this->insertRecord2 = &Name::cloopinsertRecord2Dispatcher;
this->updateRecord2 = &Name::cloopupdateRecord2Dispatcher;
this->deleteRecord2 = &Name::cloopdeleteRecord2Dispatcher;
this->executeSqlIntl2 = &Name::cloopexecuteSqlIntl2Dispatcher;
}
} vTable;
@ -20392,13 +20605,13 @@ namespace Firebird
}
}
static void CLOOP_CARG cloopinsertRecordDispatcher(IReplicatedTransaction* self, IStatus* status, const char* name, IReplicatedRecord* record) CLOOP_NOEXCEPT
static void CLOOP_CARG cloopdeprecatedInsertRecordDispatcher(IReplicatedTransaction* self, IStatus* status, const char* name, IReplicatedRecord* record) CLOOP_NOEXCEPT
{
StatusType status2(status);
try
{
static_cast<Name*>(self)->Name::insertRecord(&status2, name, record);
static_cast<Name*>(self)->Name::deprecatedInsertRecord(&status2, name, record);
}
catch (...)
{
@ -20406,13 +20619,13 @@ namespace Firebird
}
}
static void CLOOP_CARG cloopupdateRecordDispatcher(IReplicatedTransaction* self, IStatus* status, const char* name, IReplicatedRecord* orgRecord, IReplicatedRecord* newRecord) CLOOP_NOEXCEPT
static void CLOOP_CARG cloopdeprecatedUpdateRecordDispatcher(IReplicatedTransaction* self, IStatus* status, const char* name, IReplicatedRecord* orgRecord, IReplicatedRecord* newRecord) CLOOP_NOEXCEPT
{
StatusType status2(status);
try
{
static_cast<Name*>(self)->Name::updateRecord(&status2, name, orgRecord, newRecord);
static_cast<Name*>(self)->Name::deprecatedUpdateRecord(&status2, name, orgRecord, newRecord);
}
catch (...)
{
@ -20420,13 +20633,13 @@ namespace Firebird
}
}
static void CLOOP_CARG cloopdeleteRecordDispatcher(IReplicatedTransaction* self, IStatus* status, const char* name, IReplicatedRecord* record) CLOOP_NOEXCEPT
static void CLOOP_CARG cloopdeprecatedDeleteRecordDispatcher(IReplicatedTransaction* self, IStatus* status, const char* name, IReplicatedRecord* record) CLOOP_NOEXCEPT
{
StatusType status2(status);
try
{
static_cast<Name*>(self)->Name::deleteRecord(&status2, name, record);
static_cast<Name*>(self)->Name::deprecatedDeleteRecord(&status2, name, record);
}
catch (...)
{
@ -20434,13 +20647,13 @@ namespace Firebird
}
}
static void CLOOP_CARG cloopexecuteSqlDispatcher(IReplicatedTransaction* self, IStatus* status, const char* sql) CLOOP_NOEXCEPT
static void CLOOP_CARG cloopdeprecatedExecuteSqlDispatcher(IReplicatedTransaction* self, IStatus* status, const char* sql) CLOOP_NOEXCEPT
{
StatusType status2(status);
try
{
static_cast<Name*>(self)->Name::executeSql(&status2, sql);
static_cast<Name*>(self)->Name::deprecatedExecuteSql(&status2, sql);
}
catch (...)
{
@ -20448,13 +20661,69 @@ namespace Firebird
}
}
static void CLOOP_CARG cloopexecuteSqlIntlDispatcher(IReplicatedTransaction* self, IStatus* status, unsigned charset, const char* sql) CLOOP_NOEXCEPT
static void CLOOP_CARG cloopdeprecatedExecuteSqlIntlDispatcher(IReplicatedTransaction* self, IStatus* status, unsigned charset, const char* sql) CLOOP_NOEXCEPT
{
StatusType status2(status);
try
{
static_cast<Name*>(self)->Name::executeSqlIntl(&status2, charset, sql);
static_cast<Name*>(self)->Name::deprecatedExecuteSqlIntl(&status2, charset, sql);
}
catch (...)
{
StatusType::catchException(&status2);
}
}
static void CLOOP_CARG cloopinsertRecord2Dispatcher(IReplicatedTransaction* self, IStatus* status, const char* schemaName, const char* tableName, IReplicatedRecord* record) CLOOP_NOEXCEPT
{
StatusType status2(status);
try
{
static_cast<Name*>(self)->Name::insertRecord2(&status2, schemaName, tableName, record);
}
catch (...)
{
StatusType::catchException(&status2);
}
}
static void CLOOP_CARG cloopupdateRecord2Dispatcher(IReplicatedTransaction* self, IStatus* status, const char* schemaName, const char* tableName, IReplicatedRecord* orgRecord, IReplicatedRecord* newRecord) CLOOP_NOEXCEPT
{
StatusType status2(status);
try
{
static_cast<Name*>(self)->Name::updateRecord2(&status2, schemaName, tableName, orgRecord, newRecord);
}
catch (...)
{
StatusType::catchException(&status2);
}
}
static void CLOOP_CARG cloopdeleteRecord2Dispatcher(IReplicatedTransaction* self, IStatus* status, const char* schemaName, const char* tableName, IReplicatedRecord* record) CLOOP_NOEXCEPT
{
StatusType status2(status);
try
{
static_cast<Name*>(self)->Name::deleteRecord2(&status2, schemaName, tableName, record);
}
catch (...)
{
StatusType::catchException(&status2);
}
}
static void CLOOP_CARG cloopexecuteSqlIntl2Dispatcher(IReplicatedTransaction* self, IStatus* status, unsigned charset, const char* schemaSearchPath, const char* sql) CLOOP_NOEXCEPT
{
StatusType status2(status);
try
{
static_cast<Name*>(self)->Name::executeSqlIntl2(&status2, charset, schemaSearchPath, sql);
}
catch (...)
{
@ -20494,11 +20763,15 @@ namespace Firebird
virtual void startSavepoint(StatusType* status) = 0;
virtual void releaseSavepoint(StatusType* status) = 0;
virtual void rollbackSavepoint(StatusType* status) = 0;
virtual void insertRecord(StatusType* status, const char* name, IReplicatedRecord* record) = 0;
virtual void updateRecord(StatusType* status, const char* name, IReplicatedRecord* orgRecord, IReplicatedRecord* newRecord) = 0;
virtual void deleteRecord(StatusType* status, const char* name, IReplicatedRecord* record) = 0;
virtual void executeSql(StatusType* status, const char* sql) = 0;
virtual void executeSqlIntl(StatusType* status, unsigned charset, const char* sql) = 0;
virtual void deprecatedInsertRecord(StatusType* status, const char* name, IReplicatedRecord* record) = 0;
virtual void deprecatedUpdateRecord(StatusType* status, const char* name, IReplicatedRecord* orgRecord, IReplicatedRecord* newRecord) = 0;
virtual void deprecatedDeleteRecord(StatusType* status, const char* name, IReplicatedRecord* record) = 0;
virtual void deprecatedExecuteSql(StatusType* status, const char* sql) = 0;
virtual void deprecatedExecuteSqlIntl(StatusType* status, unsigned charset, const char* sql) = 0;
virtual void insertRecord2(StatusType* status, const char* schemaName, const char* tableName, IReplicatedRecord* record) = 0;
virtual void updateRecord2(StatusType* status, const char* schemaName, const char* tableName, IReplicatedRecord* orgRecord, IReplicatedRecord* newRecord) = 0;
virtual void deleteRecord2(StatusType* status, const char* schemaName, const char* tableName, IReplicatedRecord* record) = 0;
virtual void executeSqlIntl2(StatusType* status, unsigned charset, const char* schemaSearchPath, const char* sql) = 0;
};
template <typename Name, typename StatusType, typename Base>
@ -20521,7 +20794,8 @@ namespace Firebird
this->init = &Name::cloopinitDispatcher;
this->startTransaction = &Name::cloopstartTransactionDispatcher;
this->cleanupTransaction = &Name::cloopcleanupTransactionDispatcher;
this->setSequence = &Name::cloopsetSequenceDispatcher;
this->deprecatedSetSequence = &Name::cloopdeprecatedSetSequenceDispatcher;
this->setSequence2 = &Name::cloopsetSequence2Dispatcher;
}
} vTable;
@ -20572,13 +20846,27 @@ namespace Firebird
}
}
static void CLOOP_CARG cloopsetSequenceDispatcher(IReplicatedSession* self, IStatus* status, const char* name, ISC_INT64 value) CLOOP_NOEXCEPT
static void CLOOP_CARG cloopdeprecatedSetSequenceDispatcher(IReplicatedSession* self, IStatus* status, const char* name, ISC_INT64 value) CLOOP_NOEXCEPT
{
StatusType status2(status);
try
{
static_cast<Name*>(self)->Name::setSequence(&status2, name, value);
static_cast<Name*>(self)->Name::deprecatedSetSequence(&status2, name, value);
}
catch (...)
{
StatusType::catchException(&status2);
}
}
static void CLOOP_CARG cloopsetSequence2Dispatcher(IReplicatedSession* self, IStatus* status, const char* schemaName, const char* genName, ISC_INT64 value) CLOOP_NOEXCEPT
{
StatusType status2(status);
try
{
static_cast<Name*>(self)->Name::setSequence2(&status2, schemaName, genName, value);
}
catch (...)
{
@ -20653,7 +20941,8 @@ namespace Firebird
virtual FB_BOOLEAN init(StatusType* status, IAttachment* attachment) = 0;
virtual IReplicatedTransaction* startTransaction(StatusType* status, ITransaction* transaction, ISC_INT64 number) = 0;
virtual void cleanupTransaction(StatusType* status, ISC_INT64 number) = 0;
virtual void setSequence(StatusType* status, const char* name, ISC_INT64 value) = 0;
virtual void deprecatedSetSequence(StatusType* status, const char* name, ISC_INT64 value) = 0;
virtual void setSequence2(StatusType* status, const char* schemaName, const char* genName, ISC_INT64 value) = 0;
};
template <typename Name, typename StatusType, typename Base>
@ -20812,7 +21101,7 @@ namespace Firebird
this->getFlags = &Name::cloopgetFlagsDispatcher;
this->cancel = &Name::cloopcancelDispatcher;
this->finish = &Name::cloopfinishDispatcher;
this->defineStatement = &Name::cloopdefineStatementDispatcher;
this->deprecatedDefineStatement = &Name::cloopdeprecatedDefineStatementDispatcher;
this->defineCursor = &Name::cloopdefineCursorDispatcher;
this->defineRecordSource = &Name::cloopdefineRecordSourceDispatcher;
this->onRequestStart = &Name::clooponRequestStartDispatcher;
@ -20823,6 +21112,7 @@ namespace Firebird
this->afterRecordSourceOpen = &Name::cloopafterRecordSourceOpenDispatcher;
this->beforeRecordSourceGetRecord = &Name::cloopbeforeRecordSourceGetRecordDispatcher;
this->afterRecordSourceGetRecord = &Name::cloopafterRecordSourceGetRecordDispatcher;
this->defineStatement2 = &Name::cloopdefineStatement2Dispatcher;
}
} vTable;
@ -20883,13 +21173,13 @@ namespace Firebird
}
}
static void CLOOP_CARG cloopdefineStatementDispatcher(IProfilerSession* self, IStatus* status, ISC_INT64 statementId, ISC_INT64 parentStatementId, const char* type, const char* packageName, const char* routineName, const char* sqlText) CLOOP_NOEXCEPT
static void CLOOP_CARG cloopdeprecatedDefineStatementDispatcher(IProfilerSession* self, IStatus* status, ISC_INT64 statementId, ISC_INT64 parentStatementId, const char* type, const char* packageName, const char* routineName, const char* sqlText) CLOOP_NOEXCEPT
{
StatusType status2(status);
try
{
static_cast<Name*>(self)->Name::defineStatement(&status2, statementId, parentStatementId, type, packageName, routineName, sqlText);
static_cast<Name*>(self)->Name::deprecatedDefineStatement(&status2, statementId, parentStatementId, type, packageName, routineName, sqlText);
}
catch (...)
{
@ -21021,6 +21311,20 @@ namespace Firebird
}
}
static void CLOOP_CARG cloopdefineStatement2Dispatcher(IProfilerSession* self, IStatus* status, ISC_INT64 statementId, ISC_INT64 parentStatementId, const char* type, const char* schemaName, const char* packageName, const char* routineName, const char* sqlText) CLOOP_NOEXCEPT
{
StatusType status2(status);
try
{
static_cast<Name*>(self)->Name::defineStatement2(&status2, statementId, parentStatementId, type, schemaName, packageName, routineName, sqlText);
}
catch (...)
{
StatusType::catchException(&status2);
}
}
static void CLOOP_CARG cloopdisposeDispatcher(IDisposable* self) CLOOP_NOEXCEPT
{
try
@ -21051,7 +21355,7 @@ namespace Firebird
virtual unsigned getFlags() = 0;
virtual void cancel(StatusType* status) = 0;
virtual void finish(StatusType* status, ISC_TIMESTAMP_TZ timestamp) = 0;
virtual void defineStatement(StatusType* status, ISC_INT64 statementId, ISC_INT64 parentStatementId, const char* type, const char* packageName, const char* routineName, const char* sqlText) = 0;
virtual void deprecatedDefineStatement(StatusType* status, ISC_INT64 statementId, ISC_INT64 parentStatementId, const char* type, const char* packageName, const char* routineName, const char* sqlText) = 0;
virtual void defineCursor(ISC_INT64 statementId, unsigned cursorId, const char* name, unsigned line, unsigned column) = 0;
virtual void defineRecordSource(ISC_INT64 statementId, unsigned cursorId, unsigned recSourceId, unsigned level, const char* accessPath, unsigned parentRecSourceId) = 0;
virtual void onRequestStart(StatusType* status, ISC_INT64 statementId, ISC_INT64 requestId, ISC_INT64 callerStatementId, ISC_INT64 callerRequestId, ISC_TIMESTAMP_TZ timestamp) = 0;
@ -21062,6 +21366,7 @@ namespace Firebird
virtual void afterRecordSourceOpen(ISC_INT64 statementId, ISC_INT64 requestId, unsigned cursorId, unsigned recSourceId, IProfilerStats* stats) = 0;
virtual void beforeRecordSourceGetRecord(ISC_INT64 statementId, ISC_INT64 requestId, unsigned cursorId, unsigned recSourceId) = 0;
virtual void afterRecordSourceGetRecord(ISC_INT64 statementId, ISC_INT64 requestId, unsigned cursorId, unsigned recSourceId, IProfilerStats* stats) = 0;
virtual void defineStatement2(StatusType* status, ISC_INT64 statementId, ISC_INT64 parentStatementId, const char* type, const char* schemaName, const char* packageName, const char* routineName, const char* sqlText) = 0;
};
template <typename Name, typename StatusType, typename Base>

View File

@ -74,8 +74,10 @@
#define blr_timestamp_tz (unsigned char)29
#define blr_ex_time_tz (unsigned char)30
#define blr_ex_timestamp_tz (unsigned char)31
#define blr_domain_name3 (unsigned char)32
#define blr_column_name3 (unsigned char)33
// first sub parameter for blr_domain_name[2]
// first sub parameter for blr_column_name* and blr_domain_name*
#define blr_domain_type_of (unsigned char)0
#define blr_domain_full (unsigned char)1
@ -96,6 +98,8 @@
#define blr_exception_msg (unsigned char)6
#define blr_exception_params (unsigned char)7
#define blr_sql_state (unsigned char)8
#define blr_exception2 (unsigned char)9
#define blr_exception3 (unsigned char)10
#define blr_version4 (unsigned char)4
#define blr_version5 (unsigned char)5
@ -257,6 +261,7 @@
#define blr_relation2 (unsigned char)146
#define blr_rid2 (unsigned char)147
#define blr_relation3 (unsigned char)148
// unused codes: 148..149
@ -470,10 +475,11 @@
// FB 6.0 specific BLR
#define blr_invoke_function (unsigned char) 224
#define blr_invoke_function_type (unsigned char) 1
#define blr_invoke_function_type_standalone (unsigned char) 1
#define blr_invoke_function_type_packaged (unsigned char) 2
#define blr_invoke_function_type_sub (unsigned char) 3
#define blr_invoke_function_id (unsigned char) 1
#define blr_invoke_function_id_schema (unsigned char) 1
#define blr_invoke_function_id_package (unsigned char) 2
#define blr_invoke_function_id_name (unsigned char) 3
#define blr_invoke_function_id_sub (unsigned char) 4
#define blr_invoke_function_arg_names (unsigned char) 2
#define blr_invoke_function_args (unsigned char) 3
@ -481,10 +487,11 @@
#define blr_select_procedure (unsigned char) 226
// subcodes of blr_invoke_procedure and blr_select_procedure
#define blr_invsel_procedure_type (unsigned char) 1
#define blr_invsel_procedure_type_standalone (unsigned char) 1
#define blr_invsel_procedure_type_packaged (unsigned char) 2
#define blr_invsel_procedure_type_sub (unsigned char) 3
#define blr_invsel_procedure_id (unsigned char) 1
#define blr_invsel_procedure_id_schema (unsigned char) 1
#define blr_invsel_procedure_id_package (unsigned char) 2
#define blr_invsel_procedure_id_name (unsigned char) 3
#define blr_invsel_procedure_id_sub (unsigned char) 4
#define blr_invsel_procedure_in_arg_names (unsigned char) 2
#define blr_invsel_procedure_in_args (unsigned char) 3
#define blr_invsel_procedure_out_arg_names (unsigned char) 4
@ -498,4 +505,12 @@
#define blr_cast_format (unsigned char) 228
#define blr_gen_id3 (unsigned char) 229
#define blr_default2 (unsigned char) 230
#define blr_current_schema (unsigned char) 231
#define blr_flags (unsigned char) 232
// subcodes of blr_flags
#define blr_flags_search_system_schema (unsigned char) 1
#endif // FIREBIRD_IMPL_BLR_H

View File

@ -133,6 +133,9 @@
#define isc_dpb_parallel_workers 100
#define isc_dpb_worker_attach 101
#define isc_dpb_owner 102
#define isc_dpb_search_path 103
#define isc_dpb_blr_request_search_path 104
#define isc_dpb_gbak_restore_has_schema 105
/**************************************************/
@ -426,6 +429,8 @@
#define isc_spb_bkp_crypt 18
#define isc_spb_bkp_include_data 19
#define isc_spb_bkp_parallel_workers 21
#define isc_spb_bkp_skip_schema_data 22
#define isc_spb_bkp_include_schema_data 23
#define isc_spb_bkp_ignore_checksums 0x01
#define isc_spb_bkp_ignore_limbo 0x02
#define isc_spb_bkp_metadata_only 0x04
@ -552,6 +557,8 @@
#define isc_spb_res_access_mode 12
#define isc_spb_res_fix_fss_data 13
#define isc_spb_res_fix_fss_metadata 14
#define isc_spb_res_skip_schema_data isc_spb_bkp_skip_schema_data
#define isc_spb_res_include_schema_data isc_spb_bkp_include_schema_data
#define isc_spb_res_keyholder isc_spb_bkp_keyholder
#define isc_spb_res_keyname isc_spb_bkp_keyname
#define isc_spb_res_crypt isc_spb_bkp_crypt
@ -577,6 +584,8 @@
#define isc_spb_val_idx_incl 3 // regexp of indices to validate
#define isc_spb_val_idx_excl 4 // regexp of indices to NOT validate
#define isc_spb_val_lock_timeout 5 // how long to wait for table lock
#define isc_spb_val_sch_incl 6 // include schema filter based on regular expression
#define isc_spb_val_sch_excl 7 // exclude schema filter based on regular expression
/******************************************
* Parameters for isc_spb_res_access_mode *
@ -686,6 +695,7 @@
#define isc_sdl_do2 34
#define isc_sdl_do1 35
#define isc_sdl_element 36
#define isc_sdl_schema 37
/********************************************/
/* International text interpretation values */

View File

@ -500,6 +500,7 @@ enum info_db_provider
#define isc_info_sql_stmt_blob_align 30
#define isc_info_sql_exec_path_blr_bytes 31
#define isc_info_sql_exec_path_blr_text 32
#define isc_info_sql_relation_schema 33
/*********************************/
/* SQL information return values */

View File

@ -20,7 +20,7 @@ FB_IMPL_MSG(DSQL, 20, dsql_cursor_exists, -502, "24", "000", "Cursor @1 already
FB_IMPL_MSG(DSQL, 21, dsql_cursor_rel_ambiguous, -502, "34", "000", "Relation @1 is ambiguous in cursor @2")
FB_IMPL_MSG(DSQL, 22, dsql_cursor_rel_not_found, -502, "34", "000", "Relation @1 is not found in cursor @2")
FB_IMPL_MSG(DSQL, 23, dsql_cursor_not_open, -504, "24", "000", "Cursor is not open")
FB_IMPL_MSG(DSQL, 24, dsql_type_not_supp_ext_tab, -607, "HY", "004", "Data type @1 is not supported for EXTERNAL TABLES. Relation '@2', field '@3'")
FB_IMPL_MSG(DSQL, 24, dsql_type_not_supp_ext_tab, -607, "HY", "004", "Data type @1 is not supported for EXTERNAL TABLES. Relation @2, field @3")
FB_IMPL_MSG(DSQL, 25, dsql_feature_not_supported_ods, -804, "0A", "000", "Feature not supported on ODS version older than @1.@2")
FB_IMPL_MSG(DSQL, 26, primary_key_required, -660, "22", "000", "Primary key required on table @1")
FB_IMPL_MSG(DSQL, 27, upd_ins_doesnt_match_pk, -313, "42", "000", "UPDATE OR INSERT field list does not match primary key of table @1")

View File

@ -303,3 +303,11 @@ FB_IMPL_MSG_SYMBOL(DYN, 310, dyn_dup_trigger, "Trigger @1 already exists")
FB_IMPL_MSG_SYMBOL(DYN, 311, dyn_dup_domain, "Domain @1 already exists")
FB_IMPL_MSG_SYMBOL(DYN, 312, dyn_dup_collation, "Collation @1 already exists")
FB_IMPL_MSG_SYMBOL(DYN, 313, dyn_dup_package, "Package @1 already exists")
FB_IMPL_MSG(DYN, 314, dyn_index_schema_must_match_table, -901, "42", "000", "Index schema (@1) must match table schema (@2)")
FB_IMPL_MSG(DYN, 315, dyn_trig_schema_must_match_table, -901, "42", "000", "Trigger schema (@1) must match table schema (@2)")
FB_IMPL_MSG_SYMBOL(DYN, 316, dyn_dup_schema, "Schema @1 already exists")
FB_IMPL_MSG(DYN, 317, dyn_cannot_mod_system_schema, -607, "HY", "000", "Cannot ALTER or DROP SYSTEM schema")
FB_IMPL_MSG(DYN, 318, dyn_cannot_drop_non_emptyschema, -607, "HY", "000", "Cannot DROP schema @1 because it has objects")
FB_IMPL_MSG(DYN, 319, dyn_cannot_mod_obj_sys_schema, -607, "HY", "000", "Cannot CREATE/ALTER/DROP @1 in SYSTEM schema")
FB_IMPL_MSG(DYN, 320, dyn_cannot_create_reserved_schema, -607, "HY", "000", "Schema name @1 is reserved and cannot be created")
FB_IMPL_MSG(DYN, 321, dyn_cannot_infer_schema, -901, "42", "000", "Cannot infer schema name as there is no valid schema in the search path")

View File

@ -406,3 +406,13 @@ FB_IMPL_MSG_SYMBOL(GBAK, 407, gbak_missing_prl_wrks, "parallel workers parameter
FB_IMPL_MSG_SYMBOL(GBAK, 408, gbak_inv_prl_wrks, "expected parallel workers, encountered \"@1\"")
FB_IMPL_MSG_NO_SYMBOL(GBAK, 409, " @1D(IRECT_IO) direct IO for backup file(s)")
FB_IMPL_MSG_NO_SYMBOL(GBAK, 410, "use up to @1 parallel workers")
FB_IMPL_MSG_NO_SYMBOL(GBAK, 411, "writing schema @1")
FB_IMPL_MSG_NO_SYMBOL(GBAK, 412, "writing schemas")
FB_IMPL_MSG_NO_SYMBOL(GBAK, 413, "restoring schema @1")
FB_IMPL_MSG_NO_SYMBOL(GBAK, 414, "schema")
FB_IMPL_MSG_NO_SYMBOL(GBAK, 415, " @1SKIP_SCHEMA_D(ATA) skip data for schema")
FB_IMPL_MSG_NO_SYMBOL(GBAK, 416, " @1INCLUDE_SCHEMA_D(ATA) backup data of schema(s)")
FB_IMPL_MSG_NO_SYMBOL(GBAK, 417, "missing regular expression to skip schemas")
FB_IMPL_MSG_NO_SYMBOL(GBAK, 418, "missing regular expression to include schemas")
FB_IMPL_MSG_NO_SYMBOL(GBAK, 419, "regular expression to skip schemas was already set")
FB_IMPL_MSG_NO_SYMBOL(GBAK, 420, "regular expression to include schemas was already set")

View File

@ -206,3 +206,4 @@ FB_IMPL_MSG_SYMBOL(ISQL, 206, USAGE_AUTOTERM, " -autot(erm) use auto
FB_IMPL_MSG_SYMBOL(ISQL, 207, AUTOTERM_NOT_SUPPORTED, "SET AUTOTERM ON is not supported in engine/server and has been disabled")
FB_IMPL_MSG_SYMBOL(ISQL, 208, HLP_SETAUTOTERM, " SET AUTOTERM -- toggle auto statement terminator")
FB_IMPL_MSG_SYMBOL(ISQL, 209, HLP_SETWIRESTATS, " SET WIRE_stats -- toggle display of wire (network) statistics")
FB_IMPL_MSG_SYMBOL(ISQL, 210, USAGE_SEARCH_PATH, " -(se)arch_path <path> set schema search path")

View File

@ -27,7 +27,7 @@ FB_IMPL_MSG(JRD, 25, lock_conflict, -901, "40", "001", "lock conflict on no wait
FB_IMPL_MSG(JRD, 26, metadata_corrupt, -902, "XX", "001", "corrupt system table")
FB_IMPL_MSG(JRD, 27, not_valid, -625, "23", "000", "validation error for column @1, value \"@2\"")
FB_IMPL_MSG(JRD, 28, no_cur_rec, -508, "22", "000", "no current record for fetch operation")
FB_IMPL_MSG(JRD, 29, no_dup, -803, "23", "000", "attempt to store duplicate value (visible to active transactions) in unique index \"@1\"")
FB_IMPL_MSG(JRD, 29, no_dup, -803, "23", "000", "attempt to store duplicate value (visible to active transactions) in unique index @1")
FB_IMPL_MSG(JRD, 30, no_finish, -901, "HY", "000", "program attempted to exit without finishing database")
FB_IMPL_MSG(JRD, 31, no_meta_update, -607, "42", "000", "unsuccessful metadata update")
FB_IMPL_MSG(JRD, 32, no_priv, -551, "28", "000", "no permission for @1 access to @2 @3")
@ -144,7 +144,7 @@ FB_IMPL_MSG(JRD, 142, cant_start_journal, -923, "HY", "000", "secondary server a
FB_IMPL_MSG(JRD, 143, gennotdef, -204, "42", "000", "generator @1 is not defined")
FB_IMPL_MSG(JRD, 144, cant_start_logging, -923, "HY", "000", "secondary server attachments cannot start logging")
FB_IMPL_MSG(JRD, 145, bad_segstr_type, -685, "42", "000", "invalid BLOB type for operation")
FB_IMPL_MSG(JRD, 146, foreign_key, -530, "23", "000", "violation of FOREIGN KEY constraint \"@1\" on table \"@2\"")
FB_IMPL_MSG(JRD, 146, foreign_key, -530, "23", "000", "violation of FOREIGN KEY constraint @1 on table @2")
FB_IMPL_MSG(JRD, 147, high_minor, -820, "HY", "000", "minor version too high found @1 expected @2")
FB_IMPL_MSG(JRD, 148, tra_state, -901, "00", "000", "transaction @1 is @2")
FB_IMPL_MSG(JRD, 149, trans_invalid, -532, "25", "000", "transaction marked invalid and cannot be committed")
@ -275,7 +275,7 @@ FB_IMPL_MSG(JRD, 273, dsql_max_arr_dim_exceeded, -604, "54", "000", "Array decla
FB_IMPL_MSG(JRD, 274, dsql_arr_range_error, -604, "42", "000", "Illegal array dimension range")
FB_IMPL_MSG(JRD, 275, dsql_trigger_err, -204, "HY", "000", "Trigger unknown")
FB_IMPL_MSG(JRD, 276, dsql_subselect_err, -206, "42", "000", "Subselect illegal in this context")
FB_IMPL_MSG(JRD, 277, dsql_crdb_prepare_err, -531, "42", "000", "Cannot prepare a CREATE DATABASE/SCHEMA statement")
FB_IMPL_MSG(JRD, 277, dsql_crdb_prepare_err, -531, "42", "000", "Cannot prepare a CREATE DATABASE statement")
FB_IMPL_MSG(JRD, 278, specify_field_err, -157, "42", "000", "must specify column name for view select expression")
FB_IMPL_MSG(JRD, 279, num_field_err, -158, "07", "002", "number of columns does not match select list")
FB_IMPL_MSG(JRD, 280, col_name_err, -806, "42", "000", "Only simple column names permitted for VIEW WITH CHECK OPTION")
@ -343,7 +343,7 @@ FB_IMPL_MSG(JRD, 341, index_root_page_full, -904, "54", "000", "cannot add index
FB_IMPL_MSG(JRD, 342, dsql_blob_type_unknown, -204, "42", "000", "BLOB SUB_TYPE @1 is not defined")
FB_IMPL_MSG(JRD, 343, req_max_clones_exceeded, -693, "54", "001", "Too many concurrent executions of the same request")
FB_IMPL_MSG(JRD, 344, dsql_duplicate_spec, -637, "42", "000", "duplicate specification of @1 - not supported")
FB_IMPL_MSG(JRD, 345, unique_key_violation, -803, "23", "000", "violation of PRIMARY or UNIQUE KEY constraint \"@1\" on table \"@2\"")
FB_IMPL_MSG(JRD, 345, unique_key_violation, -803, "23", "000", "violation of PRIMARY or UNIQUE KEY constraint @1 on table @2")
FB_IMPL_MSG(JRD, 346, srvr_version_too_old, -901, "HY", "000", "server version too old to support all CREATE DATABASE options")
FB_IMPL_MSG(JRD, 347, drdb_completed_with_errs, -909, "HY", "000", "drop database completed with errors")
FB_IMPL_MSG(JRD, 348, dsql_procedure_use_err, -84, "42", "000", "procedure @1 does not return any values")
@ -987,3 +987,5 @@ FB_IMPL_MSG(JRD, 984, incompatible_format_patterns, -901, "HY", "000", "@1 incom
FB_IMPL_MSG(JRD, 985, only_one_pattern_can_be_used, -901, "HY", "000", "Can use only one of these patterns @1")
FB_IMPL_MSG(JRD, 986, can_not_use_same_pattern_twice, -901, "HY", "000", "Cannot use the same pattern twice: @1")
FB_IMPL_MSG(JRD, 987, sysf_invalid_gen_uuid_version, -833, "42", "000", "Invalid GEN_UUID version (@1). Must be 4 or 7")
FB_IMPL_MSG(JRD, 988, invalid_name, -901, "HY", "000", "Invalid name: @1")
FB_IMPL_MSG(JRD, 989, invalid_unqualified_name_list, -901, "HY", "000", "Invalid list of unqualified names: @1")

View File

@ -283,3 +283,8 @@ FB_IMPL_MSG(SQLERR, 1043, dsql_string_byte_length, -901, "42", "000", "String li
FB_IMPL_MSG(SQLERR, 1044, dsql_string_char_length, -901, "42", "000", "String literal with @1 characters exceeds the maximum length of @2 characters for the @3 character set")
FB_IMPL_MSG(SQLERR, 1045, dsql_max_nesting, -901, "07", "002", "Too many BEGIN...END nesting. Maximum level is @1")
FB_IMPL_MSG(SQLERR, 1046, dsql_recreate_user_failed, -901, "42", "000", "RECREATE USER @1 failed")
FB_IMPL_MSG(SQLERR, 1047, dsql_create_schema_failed, -901, "42", "000", "CREATE SCHEMA @1 failed")
FB_IMPL_MSG(SQLERR, 1048, dsql_drop_schema_failed, -901, "42", "000", "DROP SCHEMA @1 failed")
FB_IMPL_MSG(SQLERR, 1049, dsql_recreate_schema_failed, -901, "42", "000", "RECREATE SCHEMA @1 failed")
FB_IMPL_MSG(SQLERR, 1050, dsql_alter_schema_failed, -901, "42", "000", "ALTER SCHEMA @1 failed")
FB_IMPL_MSG(SQLERR, 1051, dsql_create_alter_schema_failed, -901, "42", "000", "CREATE OR ALTER SCHEMA @1 failed")

View File

@ -316,6 +316,7 @@ type
IMessageMetadata_getMessageLengthPtr = function(this: IMessageMetadata; status: IStatus): Cardinal; cdecl;
IMessageMetadata_getAlignmentPtr = function(this: IMessageMetadata; status: IStatus): Cardinal; cdecl;
IMessageMetadata_getAlignedLengthPtr = function(this: IMessageMetadata; status: IStatus): Cardinal; cdecl;
IMessageMetadata_getSchemaPtr = function(this: IMessageMetadata; status: IStatus; index: Cardinal): PAnsiChar; cdecl;
IMetadataBuilder_setTypePtr = procedure(this: IMetadataBuilder; status: IStatus; index: Cardinal; type_: Cardinal); cdecl;
IMetadataBuilder_setSubTypePtr = procedure(this: IMetadataBuilder; status: IStatus; index: Cardinal; subType: Integer); cdecl;
IMetadataBuilder_setLengthPtr = procedure(this: IMetadataBuilder; status: IStatus; index: Cardinal; length: Cardinal); cdecl;
@ -330,6 +331,7 @@ type
IMetadataBuilder_setRelationPtr = procedure(this: IMetadataBuilder; status: IStatus; index: Cardinal; relation: PAnsiChar); cdecl;
IMetadataBuilder_setOwnerPtr = procedure(this: IMetadataBuilder; status: IStatus; index: Cardinal; owner: PAnsiChar); cdecl;
IMetadataBuilder_setAliasPtr = procedure(this: IMetadataBuilder; status: IStatus; index: Cardinal; alias: PAnsiChar); cdecl;
IMetadataBuilder_setSchemaPtr = procedure(this: IMetadataBuilder; status: IStatus; index: Cardinal; schema: PAnsiChar); cdecl;
IResultSet_fetchNextPtr = function(this: IResultSet; status: IStatus; message: Pointer): Integer; cdecl;
IResultSet_fetchPriorPtr = function(this: IResultSet; status: IStatus; message: Pointer): Integer; cdecl;
IResultSet_fetchFirstPtr = function(this: IResultSet; status: IStatus; message: Pointer): Integer; cdecl;
@ -527,6 +529,7 @@ type
IRoutineMetadata_getTriggerMetadataPtr = function(this: IRoutineMetadata; status: IStatus): IMessageMetadata; cdecl;
IRoutineMetadata_getTriggerTablePtr = function(this: IRoutineMetadata; status: IStatus): PAnsiChar; cdecl;
IRoutineMetadata_getTriggerTypePtr = function(this: IRoutineMetadata; status: IStatus): Cardinal; cdecl;
IRoutineMetadata_getSchemaPtr = function(this: IRoutineMetadata; status: IStatus): PAnsiChar; cdecl;
IExternalEngine_openPtr = procedure(this: IExternalEngine; status: IStatus; context: IExternalContext; charSet: PAnsiChar; charSetSize: Cardinal); cdecl;
IExternalEngine_openAttachmentPtr = procedure(this: IExternalEngine; status: IStatus; context: IExternalContext); cdecl;
IExternalEngine_closeAttachmentPtr = procedure(this: IExternalEngine; status: IStatus; context: IExternalContext); cdecl;
@ -559,6 +562,7 @@ type
IUtil_getInt128Ptr = function(this: IUtil; status: IStatus): IInt128; cdecl;
IUtil_decodeTimeTzExPtr = procedure(this: IUtil; status: IStatus; timeTz: ISC_TIME_TZ_EXPtr; hours: CardinalPtr; minutes: CardinalPtr; seconds: CardinalPtr; fractions: CardinalPtr; timeZoneBufferLength: Cardinal; timeZoneBuffer: PAnsiChar); cdecl;
IUtil_decodeTimeStampTzExPtr = procedure(this: IUtil; status: IStatus; timeStampTz: ISC_TIMESTAMP_TZ_EXPtr; year: CardinalPtr; month: CardinalPtr; day: CardinalPtr; hours: CardinalPtr; minutes: CardinalPtr; seconds: CardinalPtr; fractions: CardinalPtr; timeZoneBufferLength: Cardinal; timeZoneBuffer: PAnsiChar); cdecl;
IUtil_executeCreateDatabase2Ptr = function(this: IUtil; status: IStatus; stmtLength: Cardinal; creatDBstatement: PAnsiChar; dialect: Cardinal; dpbLength: Cardinal; dpb: BytePtr; stmtIsCreateDb: BooleanPtr): IAttachment; cdecl;
IOffsetsCallback_setOffsetPtr = procedure(this: IOffsetsCallback; status: IStatus; index: Cardinal; offset: Cardinal; nullOffset: Cardinal); cdecl;
IXpbBuilder_clearPtr = procedure(this: IXpbBuilder; status: IStatus); cdecl;
IXpbBuilder_removeCurrentPtr = procedure(this: IXpbBuilder; status: IStatus); cdecl;
@ -723,15 +727,20 @@ type
IReplicatedTransaction_startSavepointPtr = procedure(this: IReplicatedTransaction; status: IStatus); cdecl;
IReplicatedTransaction_releaseSavepointPtr = procedure(this: IReplicatedTransaction; status: IStatus); cdecl;
IReplicatedTransaction_rollbackSavepointPtr = procedure(this: IReplicatedTransaction; status: IStatus); cdecl;
IReplicatedTransaction_insertRecordPtr = procedure(this: IReplicatedTransaction; status: IStatus; name: PAnsiChar; record_: IReplicatedRecord); cdecl;
IReplicatedTransaction_updateRecordPtr = procedure(this: IReplicatedTransaction; status: IStatus; name: PAnsiChar; orgRecord: IReplicatedRecord; newRecord: IReplicatedRecord); cdecl;
IReplicatedTransaction_deleteRecordPtr = procedure(this: IReplicatedTransaction; status: IStatus; name: PAnsiChar; record_: IReplicatedRecord); cdecl;
IReplicatedTransaction_executeSqlPtr = procedure(this: IReplicatedTransaction; status: IStatus; sql: PAnsiChar); cdecl;
IReplicatedTransaction_executeSqlIntlPtr = procedure(this: IReplicatedTransaction; status: IStatus; charset: Cardinal; sql: PAnsiChar); cdecl;
IReplicatedTransaction_deprecatedInsertRecordPtr = procedure(this: IReplicatedTransaction; status: IStatus; name: PAnsiChar; record_: IReplicatedRecord); cdecl;
IReplicatedTransaction_deprecatedUpdateRecordPtr = procedure(this: IReplicatedTransaction; status: IStatus; name: PAnsiChar; orgRecord: IReplicatedRecord; newRecord: IReplicatedRecord); cdecl;
IReplicatedTransaction_deprecatedDeleteRecordPtr = procedure(this: IReplicatedTransaction; status: IStatus; name: PAnsiChar; record_: IReplicatedRecord); cdecl;
IReplicatedTransaction_deprecatedExecuteSqlPtr = procedure(this: IReplicatedTransaction; status: IStatus; sql: PAnsiChar); cdecl;
IReplicatedTransaction_deprecatedExecuteSqlIntlPtr = procedure(this: IReplicatedTransaction; status: IStatus; charset: Cardinal; sql: PAnsiChar); cdecl;
IReplicatedTransaction_insertRecord2Ptr = procedure(this: IReplicatedTransaction; status: IStatus; schemaName: PAnsiChar; tableName: PAnsiChar; record_: IReplicatedRecord); cdecl;
IReplicatedTransaction_updateRecord2Ptr = procedure(this: IReplicatedTransaction; status: IStatus; schemaName: PAnsiChar; tableName: PAnsiChar; orgRecord: IReplicatedRecord; newRecord: IReplicatedRecord); cdecl;
IReplicatedTransaction_deleteRecord2Ptr = procedure(this: IReplicatedTransaction; status: IStatus; schemaName: PAnsiChar; tableName: PAnsiChar; record_: IReplicatedRecord); cdecl;
IReplicatedTransaction_executeSqlIntl2Ptr = procedure(this: IReplicatedTransaction; status: IStatus; charset: Cardinal; schemaSearchPath: PAnsiChar; sql: PAnsiChar); cdecl;
IReplicatedSession_initPtr = function(this: IReplicatedSession; status: IStatus; attachment: IAttachment): Boolean; cdecl;
IReplicatedSession_startTransactionPtr = function(this: IReplicatedSession; status: IStatus; transaction: ITransaction; number: Int64): IReplicatedTransaction; cdecl;
IReplicatedSession_cleanupTransactionPtr = procedure(this: IReplicatedSession; status: IStatus; number: Int64); cdecl;
IReplicatedSession_setSequencePtr = procedure(this: IReplicatedSession; status: IStatus; name: PAnsiChar; value: Int64); cdecl;
IReplicatedSession_deprecatedSetSequencePtr = procedure(this: IReplicatedSession; status: IStatus; name: PAnsiChar; value: Int64); cdecl;
IReplicatedSession_setSequence2Ptr = procedure(this: IReplicatedSession; status: IStatus; schemaName: PAnsiChar; genName: PAnsiChar; value: Int64); cdecl;
IProfilerPlugin_initPtr = procedure(this: IProfilerPlugin; status: IStatus; attachment: IAttachment; ticksFrequency: QWord); cdecl;
IProfilerPlugin_startSessionPtr = function(this: IProfilerPlugin; status: IStatus; description: PAnsiChar; options: PAnsiChar; timestamp: ISC_TIMESTAMP_TZ): IProfilerSession; cdecl;
IProfilerPlugin_flushPtr = procedure(this: IProfilerPlugin; status: IStatus); cdecl;
@ -739,7 +748,7 @@ type
IProfilerSession_getFlagsPtr = function(this: IProfilerSession): Cardinal; cdecl;
IProfilerSession_cancelPtr = procedure(this: IProfilerSession; status: IStatus); cdecl;
IProfilerSession_finishPtr = procedure(this: IProfilerSession; status: IStatus; timestamp: ISC_TIMESTAMP_TZ); cdecl;
IProfilerSession_defineStatementPtr = procedure(this: IProfilerSession; status: IStatus; statementId: Int64; parentStatementId: Int64; type_: PAnsiChar; packageName: PAnsiChar; routineName: PAnsiChar; sqlText: PAnsiChar); cdecl;
IProfilerSession_deprecatedDefineStatementPtr = procedure(this: IProfilerSession; status: IStatus; statementId: Int64; parentStatementId: Int64; type_: PAnsiChar; packageName: PAnsiChar; routineName: PAnsiChar; sqlText: PAnsiChar); cdecl;
IProfilerSession_defineCursorPtr = procedure(this: IProfilerSession; statementId: Int64; cursorId: Cardinal; name: PAnsiChar; line: Cardinal; column: Cardinal); cdecl;
IProfilerSession_defineRecordSourcePtr = procedure(this: IProfilerSession; statementId: Int64; cursorId: Cardinal; recSourceId: Cardinal; level: Cardinal; accessPath: PAnsiChar; parentRecSourceId: Cardinal); cdecl;
IProfilerSession_onRequestStartPtr = procedure(this: IProfilerSession; status: IStatus; statementId: Int64; requestId: Int64; callerStatementId: Int64; callerRequestId: Int64; timestamp: ISC_TIMESTAMP_TZ); cdecl;
@ -750,6 +759,7 @@ type
IProfilerSession_afterRecordSourceOpenPtr = procedure(this: IProfilerSession; statementId: Int64; requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal; stats: IProfilerStats); cdecl;
IProfilerSession_beforeRecordSourceGetRecordPtr = procedure(this: IProfilerSession; statementId: Int64; requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal); cdecl;
IProfilerSession_afterRecordSourceGetRecordPtr = procedure(this: IProfilerSession; statementId: Int64; requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal; stats: IProfilerStats); cdecl;
IProfilerSession_defineStatement2Ptr = procedure(this: IProfilerSession; status: IStatus; statementId: Int64; parentStatementId: Int64; type_: PAnsiChar; schemaName: PAnsiChar; packageName: PAnsiChar; routineName: PAnsiChar; sqlText: PAnsiChar); cdecl;
IProfilerStats_getElapsedTicksPtr = function(this: IProfilerStats): QWord; cdecl;
VersionedVTable = class
@ -1347,10 +1357,11 @@ type
getMessageLength: IMessageMetadata_getMessageLengthPtr;
getAlignment: IMessageMetadata_getAlignmentPtr;
getAlignedLength: IMessageMetadata_getAlignedLengthPtr;
getSchema: IMessageMetadata_getSchemaPtr;
end;
IMessageMetadata = class(IReferenceCounted)
const VERSION = 4;
const VERSION = 5;
function getCount(status: IStatus): Cardinal;
function getField(status: IStatus; index: Cardinal): PAnsiChar;
@ -1369,6 +1380,7 @@ type
function getMessageLength(status: IStatus): Cardinal;
function getAlignment(status: IStatus): Cardinal;
function getAlignedLength(status: IStatus): Cardinal;
function getSchema(status: IStatus; index: Cardinal): PAnsiChar;
end;
IMessageMetadataImpl = class(IMessageMetadata)
@ -1393,6 +1405,7 @@ type
function getMessageLength(status: IStatus): Cardinal; virtual; abstract;
function getAlignment(status: IStatus): Cardinal; virtual; abstract;
function getAlignedLength(status: IStatus): Cardinal; virtual; abstract;
function getSchema(status: IStatus; index: Cardinal): PAnsiChar; virtual; abstract;
end;
MetadataBuilderVTable = class(ReferenceCountedVTable)
@ -1410,10 +1423,11 @@ type
setRelation: IMetadataBuilder_setRelationPtr;
setOwner: IMetadataBuilder_setOwnerPtr;
setAlias: IMetadataBuilder_setAliasPtr;
setSchema: IMetadataBuilder_setSchemaPtr;
end;
IMetadataBuilder = class(IReferenceCounted)
const VERSION = 4;
const VERSION = 5;
procedure setType(status: IStatus; index: Cardinal; type_: Cardinal);
procedure setSubType(status: IStatus; index: Cardinal; subType: Integer);
@ -1429,6 +1443,7 @@ type
procedure setRelation(status: IStatus; index: Cardinal; relation: PAnsiChar);
procedure setOwner(status: IStatus; index: Cardinal; owner: PAnsiChar);
procedure setAlias(status: IStatus; index: Cardinal; alias: PAnsiChar);
procedure setSchema(status: IStatus; index: Cardinal; schema: PAnsiChar);
end;
IMetadataBuilderImpl = class(IMetadataBuilder)
@ -1450,6 +1465,7 @@ type
procedure setRelation(status: IStatus; index: Cardinal; relation: PAnsiChar); virtual; abstract;
procedure setOwner(status: IStatus; index: Cardinal; owner: PAnsiChar); virtual; abstract;
procedure setAlias(status: IStatus; index: Cardinal; alias: PAnsiChar); virtual; abstract;
procedure setSchema(status: IStatus; index: Cardinal; schema: PAnsiChar); virtual; abstract;
end;
ResultSetVTable = class(ReferenceCountedVTable)
@ -2618,10 +2634,11 @@ type
getTriggerMetadata: IRoutineMetadata_getTriggerMetadataPtr;
getTriggerTable: IRoutineMetadata_getTriggerTablePtr;
getTriggerType: IRoutineMetadata_getTriggerTypePtr;
getSchema: IRoutineMetadata_getSchemaPtr;
end;
IRoutineMetadata = class(IVersioned)
const VERSION = 2;
const VERSION = 3;
function getPackage(status: IStatus): PAnsiChar;
function getName(status: IStatus): PAnsiChar;
@ -2632,6 +2649,7 @@ type
function getTriggerMetadata(status: IStatus): IMessageMetadata;
function getTriggerTable(status: IStatus): PAnsiChar;
function getTriggerType(status: IStatus): Cardinal;
function getSchema(status: IStatus): PAnsiChar;
end;
IRoutineMetadataImpl = class(IRoutineMetadata)
@ -2646,6 +2664,7 @@ type
function getTriggerMetadata(status: IStatus): IMessageMetadata; virtual; abstract;
function getTriggerTable(status: IStatus): PAnsiChar; virtual; abstract;
function getTriggerType(status: IStatus): Cardinal; virtual; abstract;
function getSchema(status: IStatus): PAnsiChar; virtual; abstract;
end;
ExternalEngineVTable = class(PluginBaseVTable)
@ -2759,10 +2778,11 @@ type
getInt128: IUtil_getInt128Ptr;
decodeTimeTzEx: IUtil_decodeTimeTzExPtr;
decodeTimeStampTzEx: IUtil_decodeTimeStampTzExPtr;
executeCreateDatabase2: IUtil_executeCreateDatabase2Ptr;
end;
IUtil = class(IVersioned)
const VERSION = 4;
const VERSION = 5;
procedure getFbVersion(status: IStatus; att: IAttachment; callback: IVersionCallback);
procedure loadBlob(status: IStatus; blobId: ISC_QUADPtr; att: IAttachment; tra: ITransaction; file_: PAnsiChar; txt: Boolean);
@ -2786,6 +2806,7 @@ type
function getInt128(status: IStatus): IInt128;
procedure decodeTimeTzEx(status: IStatus; timeTz: ISC_TIME_TZ_EXPtr; hours: CardinalPtr; minutes: CardinalPtr; seconds: CardinalPtr; fractions: CardinalPtr; timeZoneBufferLength: Cardinal; timeZoneBuffer: PAnsiChar);
procedure decodeTimeStampTzEx(status: IStatus; timeStampTz: ISC_TIMESTAMP_TZ_EXPtr; year: CardinalPtr; month: CardinalPtr; day: CardinalPtr; hours: CardinalPtr; minutes: CardinalPtr; seconds: CardinalPtr; fractions: CardinalPtr; timeZoneBufferLength: Cardinal; timeZoneBuffer: PAnsiChar);
function executeCreateDatabase2(status: IStatus; stmtLength: Cardinal; creatDBstatement: PAnsiChar; dialect: Cardinal; dpbLength: Cardinal; dpb: BytePtr; stmtIsCreateDb: BooleanPtr): IAttachment;
end;
IUtilImpl = class(IUtil)
@ -2813,6 +2834,7 @@ type
function getInt128(status: IStatus): IInt128; virtual; abstract;
procedure decodeTimeTzEx(status: IStatus; timeTz: ISC_TIME_TZ_EXPtr; hours: CardinalPtr; minutes: CardinalPtr; seconds: CardinalPtr; fractions: CardinalPtr; timeZoneBufferLength: Cardinal; timeZoneBuffer: PAnsiChar); virtual; abstract;
procedure decodeTimeStampTzEx(status: IStatus; timeStampTz: ISC_TIMESTAMP_TZ_EXPtr; year: CardinalPtr; month: CardinalPtr; day: CardinalPtr; hours: CardinalPtr; minutes: CardinalPtr; seconds: CardinalPtr; fractions: CardinalPtr; timeZoneBufferLength: Cardinal; timeZoneBuffer: PAnsiChar); virtual; abstract;
function executeCreateDatabase2(status: IStatus; stmtLength: Cardinal; creatDBstatement: PAnsiChar; dialect: Cardinal; dpbLength: Cardinal; dpb: BytePtr; stmtIsCreateDb: BooleanPtr): IAttachment; virtual; abstract;
end;
OffsetsCallbackVTable = class(VersionedVTable)
@ -3777,15 +3799,19 @@ type
startSavepoint: IReplicatedTransaction_startSavepointPtr;
releaseSavepoint: IReplicatedTransaction_releaseSavepointPtr;
rollbackSavepoint: IReplicatedTransaction_rollbackSavepointPtr;
insertRecord: IReplicatedTransaction_insertRecordPtr;
updateRecord: IReplicatedTransaction_updateRecordPtr;
deleteRecord: IReplicatedTransaction_deleteRecordPtr;
executeSql: IReplicatedTransaction_executeSqlPtr;
executeSqlIntl: IReplicatedTransaction_executeSqlIntlPtr;
deprecatedInsertRecord: IReplicatedTransaction_deprecatedInsertRecordPtr;
deprecatedUpdateRecord: IReplicatedTransaction_deprecatedUpdateRecordPtr;
deprecatedDeleteRecord: IReplicatedTransaction_deprecatedDeleteRecordPtr;
deprecatedExecuteSql: IReplicatedTransaction_deprecatedExecuteSqlPtr;
deprecatedExecuteSqlIntl: IReplicatedTransaction_deprecatedExecuteSqlIntlPtr;
insertRecord2: IReplicatedTransaction_insertRecord2Ptr;
updateRecord2: IReplicatedTransaction_updateRecord2Ptr;
deleteRecord2: IReplicatedTransaction_deleteRecord2Ptr;
executeSqlIntl2: IReplicatedTransaction_executeSqlIntl2Ptr;
end;
IReplicatedTransaction = class(IDisposable)
const VERSION = 3;
const VERSION = 4;
procedure prepare(status: IStatus);
procedure commit(status: IStatus);
@ -3793,11 +3819,15 @@ type
procedure startSavepoint(status: IStatus);
procedure releaseSavepoint(status: IStatus);
procedure rollbackSavepoint(status: IStatus);
procedure insertRecord(status: IStatus; name: PAnsiChar; record_: IReplicatedRecord);
procedure updateRecord(status: IStatus; name: PAnsiChar; orgRecord: IReplicatedRecord; newRecord: IReplicatedRecord);
procedure deleteRecord(status: IStatus; name: PAnsiChar; record_: IReplicatedRecord);
procedure executeSql(status: IStatus; sql: PAnsiChar);
procedure executeSqlIntl(status: IStatus; charset: Cardinal; sql: PAnsiChar);
procedure deprecatedInsertRecord(status: IStatus; name: PAnsiChar; record_: IReplicatedRecord);
procedure deprecatedUpdateRecord(status: IStatus; name: PAnsiChar; orgRecord: IReplicatedRecord; newRecord: IReplicatedRecord);
procedure deprecatedDeleteRecord(status: IStatus; name: PAnsiChar; record_: IReplicatedRecord);
procedure deprecatedExecuteSql(status: IStatus; sql: PAnsiChar);
procedure deprecatedExecuteSqlIntl(status: IStatus; charset: Cardinal; sql: PAnsiChar);
procedure insertRecord2(status: IStatus; schemaName: PAnsiChar; tableName: PAnsiChar; record_: IReplicatedRecord);
procedure updateRecord2(status: IStatus; schemaName: PAnsiChar; tableName: PAnsiChar; orgRecord: IReplicatedRecord; newRecord: IReplicatedRecord);
procedure deleteRecord2(status: IStatus; schemaName: PAnsiChar; tableName: PAnsiChar; record_: IReplicatedRecord);
procedure executeSqlIntl2(status: IStatus; charset: Cardinal; schemaSearchPath: PAnsiChar; sql: PAnsiChar);
end;
IReplicatedTransactionImpl = class(IReplicatedTransaction)
@ -3810,27 +3840,33 @@ type
procedure startSavepoint(status: IStatus); virtual; abstract;
procedure releaseSavepoint(status: IStatus); virtual; abstract;
procedure rollbackSavepoint(status: IStatus); virtual; abstract;
procedure insertRecord(status: IStatus; name: PAnsiChar; record_: IReplicatedRecord); virtual; abstract;
procedure updateRecord(status: IStatus; name: PAnsiChar; orgRecord: IReplicatedRecord; newRecord: IReplicatedRecord); virtual; abstract;
procedure deleteRecord(status: IStatus; name: PAnsiChar; record_: IReplicatedRecord); virtual; abstract;
procedure executeSql(status: IStatus; sql: PAnsiChar); virtual; abstract;
procedure executeSqlIntl(status: IStatus; charset: Cardinal; sql: PAnsiChar); virtual; abstract;
procedure deprecatedInsertRecord(status: IStatus; name: PAnsiChar; record_: IReplicatedRecord); virtual; abstract;
procedure deprecatedUpdateRecord(status: IStatus; name: PAnsiChar; orgRecord: IReplicatedRecord; newRecord: IReplicatedRecord); virtual; abstract;
procedure deprecatedDeleteRecord(status: IStatus; name: PAnsiChar; record_: IReplicatedRecord); virtual; abstract;
procedure deprecatedExecuteSql(status: IStatus; sql: PAnsiChar); virtual; abstract;
procedure deprecatedExecuteSqlIntl(status: IStatus; charset: Cardinal; sql: PAnsiChar); virtual; abstract;
procedure insertRecord2(status: IStatus; schemaName: PAnsiChar; tableName: PAnsiChar; record_: IReplicatedRecord); virtual; abstract;
procedure updateRecord2(status: IStatus; schemaName: PAnsiChar; tableName: PAnsiChar; orgRecord: IReplicatedRecord; newRecord: IReplicatedRecord); virtual; abstract;
procedure deleteRecord2(status: IStatus; schemaName: PAnsiChar; tableName: PAnsiChar; record_: IReplicatedRecord); virtual; abstract;
procedure executeSqlIntl2(status: IStatus; charset: Cardinal; schemaSearchPath: PAnsiChar; sql: PAnsiChar); virtual; abstract;
end;
ReplicatedSessionVTable = class(PluginBaseVTable)
init: IReplicatedSession_initPtr;
startTransaction: IReplicatedSession_startTransactionPtr;
cleanupTransaction: IReplicatedSession_cleanupTransactionPtr;
setSequence: IReplicatedSession_setSequencePtr;
deprecatedSetSequence: IReplicatedSession_deprecatedSetSequencePtr;
setSequence2: IReplicatedSession_setSequence2Ptr;
end;
IReplicatedSession = class(IPluginBase)
const VERSION = 4;
const VERSION = 5;
function init(status: IStatus; attachment: IAttachment): Boolean;
function startTransaction(status: IStatus; transaction: ITransaction; number: Int64): IReplicatedTransaction;
procedure cleanupTransaction(status: IStatus; number: Int64);
procedure setSequence(status: IStatus; name: PAnsiChar; value: Int64);
procedure deprecatedSetSequence(status: IStatus; name: PAnsiChar; value: Int64);
procedure setSequence2(status: IStatus; schemaName: PAnsiChar; genName: PAnsiChar; value: Int64);
end;
IReplicatedSessionImpl = class(IReplicatedSession)
@ -3843,7 +3879,8 @@ type
function init(status: IStatus; attachment: IAttachment): Boolean; virtual; abstract;
function startTransaction(status: IStatus; transaction: ITransaction; number: Int64): IReplicatedTransaction; virtual; abstract;
procedure cleanupTransaction(status: IStatus; number: Int64); virtual; abstract;
procedure setSequence(status: IStatus; name: PAnsiChar; value: Int64); virtual; abstract;
procedure deprecatedSetSequence(status: IStatus; name: PAnsiChar; value: Int64); virtual; abstract;
procedure setSequence2(status: IStatus; schemaName: PAnsiChar; genName: PAnsiChar; value: Int64); virtual; abstract;
end;
ProfilerPluginVTable = class(PluginBaseVTable)
@ -3877,7 +3914,7 @@ type
getFlags: IProfilerSession_getFlagsPtr;
cancel: IProfilerSession_cancelPtr;
finish: IProfilerSession_finishPtr;
defineStatement: IProfilerSession_defineStatementPtr;
deprecatedDefineStatement: IProfilerSession_deprecatedDefineStatementPtr;
defineCursor: IProfilerSession_defineCursorPtr;
defineRecordSource: IProfilerSession_defineRecordSourcePtr;
onRequestStart: IProfilerSession_onRequestStartPtr;
@ -3888,10 +3925,11 @@ type
afterRecordSourceOpen: IProfilerSession_afterRecordSourceOpenPtr;
beforeRecordSourceGetRecord: IProfilerSession_beforeRecordSourceGetRecordPtr;
afterRecordSourceGetRecord: IProfilerSession_afterRecordSourceGetRecordPtr;
defineStatement2: IProfilerSession_defineStatement2Ptr;
end;
IProfilerSession = class(IDisposable)
const VERSION = 3;
const VERSION = 4;
const FLAG_BEFORE_EVENTS = Cardinal($1);
const FLAG_AFTER_EVENTS = Cardinal($2);
@ -3899,7 +3937,7 @@ type
function getFlags(): Cardinal;
procedure cancel(status: IStatus);
procedure finish(status: IStatus; timestamp: ISC_TIMESTAMP_TZ);
procedure defineStatement(status: IStatus; statementId: Int64; parentStatementId: Int64; type_: PAnsiChar; packageName: PAnsiChar; routineName: PAnsiChar; sqlText: PAnsiChar);
procedure deprecatedDefineStatement(status: IStatus; statementId: Int64; parentStatementId: Int64; type_: PAnsiChar; packageName: PAnsiChar; routineName: PAnsiChar; sqlText: PAnsiChar);
procedure defineCursor(statementId: Int64; cursorId: Cardinal; name: PAnsiChar; line: Cardinal; column: Cardinal);
procedure defineRecordSource(statementId: Int64; cursorId: Cardinal; recSourceId: Cardinal; level: Cardinal; accessPath: PAnsiChar; parentRecSourceId: Cardinal);
procedure onRequestStart(status: IStatus; statementId: Int64; requestId: Int64; callerStatementId: Int64; callerRequestId: Int64; timestamp: ISC_TIMESTAMP_TZ);
@ -3910,6 +3948,7 @@ type
procedure afterRecordSourceOpen(statementId: Int64; requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal; stats: IProfilerStats);
procedure beforeRecordSourceGetRecord(statementId: Int64; requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal);
procedure afterRecordSourceGetRecord(statementId: Int64; requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal; stats: IProfilerStats);
procedure defineStatement2(status: IStatus; statementId: Int64; parentStatementId: Int64; type_: PAnsiChar; schemaName: PAnsiChar; packageName: PAnsiChar; routineName: PAnsiChar; sqlText: PAnsiChar);
end;
IProfilerSessionImpl = class(IProfilerSession)
@ -3920,7 +3959,7 @@ type
function getFlags(): Cardinal; virtual; abstract;
procedure cancel(status: IStatus); virtual; abstract;
procedure finish(status: IStatus; timestamp: ISC_TIMESTAMP_TZ); virtual; abstract;
procedure defineStatement(status: IStatus; statementId: Int64; parentStatementId: Int64; type_: PAnsiChar; packageName: PAnsiChar; routineName: PAnsiChar; sqlText: PAnsiChar); virtual; abstract;
procedure deprecatedDefineStatement(status: IStatus; statementId: Int64; parentStatementId: Int64; type_: PAnsiChar; packageName: PAnsiChar; routineName: PAnsiChar; sqlText: PAnsiChar); virtual; abstract;
procedure defineCursor(statementId: Int64; cursorId: Cardinal; name: PAnsiChar; line: Cardinal; column: Cardinal); virtual; abstract;
procedure defineRecordSource(statementId: Int64; cursorId: Cardinal; recSourceId: Cardinal; level: Cardinal; accessPath: PAnsiChar; parentRecSourceId: Cardinal); virtual; abstract;
procedure onRequestStart(status: IStatus; statementId: Int64; requestId: Int64; callerStatementId: Int64; callerRequestId: Int64; timestamp: ISC_TIMESTAMP_TZ); virtual; abstract;
@ -3931,6 +3970,7 @@ type
procedure afterRecordSourceOpen(statementId: Int64; requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal; stats: IProfilerStats); virtual; abstract;
procedure beforeRecordSourceGetRecord(statementId: Int64; requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal); virtual; abstract;
procedure afterRecordSourceGetRecord(statementId: Int64; requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal; stats: IProfilerStats); virtual; abstract;
procedure defineStatement2(status: IStatus; statementId: Int64; parentStatementId: Int64; type_: PAnsiChar; schemaName: PAnsiChar; packageName: PAnsiChar; routineName: PAnsiChar; sqlText: PAnsiChar); virtual; abstract;
end;
ProfilerStatsVTable = class(VersionedVTable)
@ -4057,6 +4097,9 @@ const
isc_dpb_parallel_workers = byte(100);
isc_dpb_worker_attach = byte(101);
isc_dpb_owner = byte(102);
isc_dpb_search_path = byte(103);
isc_dpb_blr_request_search_path = byte(104);
isc_dpb_gbak_restore_has_schema = byte(105);
isc_dpb_address = byte(1);
isc_dpb_addr_protocol = byte(1);
isc_dpb_addr_endpoint = byte(2);
@ -4215,6 +4258,8 @@ const
isc_spb_bkp_crypt = byte(18);
isc_spb_bkp_include_data = byte(19);
isc_spb_bkp_parallel_workers = byte(21);
isc_spb_bkp_skip_schema_data = byte(22);
isc_spb_bkp_include_schema_data = byte(23);
isc_spb_bkp_ignore_checksums = $01;
isc_spb_bkp_ignore_limbo = $02;
isc_spb_bkp_metadata_only = $04;
@ -4311,6 +4356,8 @@ const
isc_spb_val_idx_incl = byte(3);
isc_spb_val_idx_excl = byte(4);
isc_spb_val_lock_timeout = byte(5);
isc_spb_val_sch_incl = byte(6);
isc_spb_val_sch_excl = byte(7);
isc_spb_num_att = byte(5);
isc_spb_num_db = byte(6);
isc_spb_sts_table = byte(64);
@ -4358,6 +4405,7 @@ const
isc_sdl_do2 = byte(34);
isc_sdl_do1 = byte(35);
isc_sdl_element = byte(36);
isc_sdl_schema = byte(37);
isc_blob_untyped = byte(0);
isc_blob_text = byte(1);
isc_blob_blr = byte(2);
@ -4727,6 +4775,7 @@ const
isc_info_sql_stmt_blob_align = byte(30);
isc_info_sql_exec_path_blr_bytes = byte(31);
isc_info_sql_exec_path_blr_text = byte(32);
isc_info_sql_relation_schema = byte(33);
isc_info_sql_stmt_select = byte(1);
isc_info_sql_stmt_insert = byte(2);
isc_info_sql_stmt_update = byte(3);
@ -5741,6 +5790,8 @@ const
isc_only_one_pattern_can_be_used = 335545305;
isc_can_not_use_same_pattern_twice = 335545306;
isc_sysf_invalid_gen_uuid_version = 335545307;
isc_invalid_name = 335545308;
isc_invalid_unqualified_name_list = 335545309;
isc_gfix_db_name = 335740929;
isc_gfix_invalid_sw = 335740930;
isc_gfix_incmp_sw = 335740932;
@ -5897,6 +5948,13 @@ const
isc_dyn_exc_not_exist = 336068915;
isc_dyn_gen_not_exist = 336068916;
isc_dyn_fld_not_exist = 336068917;
isc_dyn_index_schema_must_match_table = 336068922;
isc_dyn_trig_schema_must_match_table = 336068923;
isc_dyn_cannot_mod_system_schema = 336068925;
isc_dyn_cannot_drop_non_emptyschema = 336068926;
isc_dyn_cannot_mod_obj_sys_schema = 336068927;
isc_dyn_cannot_create_reserved_schema = 336068928;
isc_dyn_cannot_infer_schema = 336068929;
isc_gbak_unknown_switch = 336330753;
isc_gbak_page_size_missing = 336330754;
isc_gbak_page_size_toobig = 336330755;
@ -6125,6 +6183,11 @@ const
isc_dsql_string_char_length = 336397332;
isc_dsql_max_nesting = 336397333;
isc_dsql_recreate_user_failed = 336397334;
isc_dsql_create_schema_failed = 336397335;
isc_dsql_drop_schema_failed = 336397336;
isc_dsql_recreate_schema_failed = 336397337;
isc_dsql_alter_schema_failed = 336397338;
isc_dsql_create_alter_schema_failed = 336397339;
isc_gsec_cant_open_db = 336723983;
isc_gsec_switches_error = 336723984;
isc_gsec_no_op_spec = 336723985;
@ -6907,6 +6970,18 @@ begin
FbException.checkException(status);
end;
function IMessageMetadata.getSchema(status: IStatus; index: Cardinal): PAnsiChar;
begin
if (vTable.version < 5) then begin
FbException.setVersionError(status, 'IMessageMetadata', vTable.version, 5);
Result := nil;
end
else begin
Result := MessageMetadataVTable(vTable).getSchema(Self, status, index);
end;
FbException.checkException(status);
end;
procedure IMetadataBuilder.setType(status: IStatus; index: Cardinal; type_: Cardinal);
begin
MetadataBuilderVTable(vTable).setType(Self, status, index, type_);
@ -7011,6 +7086,17 @@ begin
FbException.checkException(status);
end;
procedure IMetadataBuilder.setSchema(status: IStatus; index: Cardinal; schema: PAnsiChar);
begin
if (vTable.version < 5) then begin
FbException.setVersionError(status, 'IMetadataBuilder', vTable.version, 5);
end
else begin
MetadataBuilderVTable(vTable).setSchema(Self, status, index, schema);
end;
FbException.checkException(status);
end;
function IResultSet.fetchNext(status: IStatus; message: Pointer): Integer;
begin
Result := ResultSetVTable(vTable).fetchNext(Self, status, message);
@ -8371,6 +8457,18 @@ begin
FbException.checkException(status);
end;
function IRoutineMetadata.getSchema(status: IStatus): PAnsiChar;
begin
if (vTable.version < 3) then begin
FbException.setVersionError(status, 'IRoutineMetadata', vTable.version, 3);
Result := nil;
end
else begin
Result := RoutineMetadataVTable(vTable).getSchema(Self, status);
end;
FbException.checkException(status);
end;
procedure IExternalEngine.open(status: IStatus; context: IExternalContext; charSet: PAnsiChar; charSetSize: Cardinal);
begin
ExternalEngineVTable(vTable).open(Self, status, context, charSet, charSetSize);
@ -8604,6 +8702,18 @@ begin
FbException.checkException(status);
end;
function IUtil.executeCreateDatabase2(status: IStatus; stmtLength: Cardinal; creatDBstatement: PAnsiChar; dialect: Cardinal; dpbLength: Cardinal; dpb: BytePtr; stmtIsCreateDb: BooleanPtr): IAttachment;
begin
if (vTable.version < 5) then begin
FbException.setVersionError(status, 'IUtil', vTable.version, 5);
Result := nil;
end
else begin
Result := UtilVTable(vTable).executeCreateDatabase2(Self, status, stmtLength, creatDBstatement, dialect, dpbLength, dpb, stmtIsCreateDb);
end;
FbException.checkException(status);
end;
procedure IOffsetsCallback.setOffset(status: IStatus; index: Cardinal; offset: Cardinal; nullOffset: Cardinal);
begin
OffsetsCallbackVTable(vTable).setOffset(Self, status, index, offset, nullOffset);
@ -9556,33 +9666,77 @@ begin
FbException.checkException(status);
end;
procedure IReplicatedTransaction.insertRecord(status: IStatus; name: PAnsiChar; record_: IReplicatedRecord);
procedure IReplicatedTransaction.deprecatedInsertRecord(status: IStatus; name: PAnsiChar; record_: IReplicatedRecord);
begin
ReplicatedTransactionVTable(vTable).insertRecord(Self, status, name, record_);
ReplicatedTransactionVTable(vTable).deprecatedInsertRecord(Self, status, name, record_);
FbException.checkException(status);
end;
procedure IReplicatedTransaction.updateRecord(status: IStatus; name: PAnsiChar; orgRecord: IReplicatedRecord; newRecord: IReplicatedRecord);
procedure IReplicatedTransaction.deprecatedUpdateRecord(status: IStatus; name: PAnsiChar; orgRecord: IReplicatedRecord; newRecord: IReplicatedRecord);
begin
ReplicatedTransactionVTable(vTable).updateRecord(Self, status, name, orgRecord, newRecord);
ReplicatedTransactionVTable(vTable).deprecatedUpdateRecord(Self, status, name, orgRecord, newRecord);
FbException.checkException(status);
end;
procedure IReplicatedTransaction.deleteRecord(status: IStatus; name: PAnsiChar; record_: IReplicatedRecord);
procedure IReplicatedTransaction.deprecatedDeleteRecord(status: IStatus; name: PAnsiChar; record_: IReplicatedRecord);
begin
ReplicatedTransactionVTable(vTable).deleteRecord(Self, status, name, record_);
ReplicatedTransactionVTable(vTable).deprecatedDeleteRecord(Self, status, name, record_);
FbException.checkException(status);
end;
procedure IReplicatedTransaction.executeSql(status: IStatus; sql: PAnsiChar);
procedure IReplicatedTransaction.deprecatedExecuteSql(status: IStatus; sql: PAnsiChar);
begin
ReplicatedTransactionVTable(vTable).executeSql(Self, status, sql);
ReplicatedTransactionVTable(vTable).deprecatedExecuteSql(Self, status, sql);
FbException.checkException(status);
end;
procedure IReplicatedTransaction.executeSqlIntl(status: IStatus; charset: Cardinal; sql: PAnsiChar);
procedure IReplicatedTransaction.deprecatedExecuteSqlIntl(status: IStatus; charset: Cardinal; sql: PAnsiChar);
begin
ReplicatedTransactionVTable(vTable).executeSqlIntl(Self, status, charset, sql);
ReplicatedTransactionVTable(vTable).deprecatedExecuteSqlIntl(Self, status, charset, sql);
FbException.checkException(status);
end;
procedure IReplicatedTransaction.insertRecord2(status: IStatus; schemaName: PAnsiChar; tableName: PAnsiChar; record_: IReplicatedRecord);
begin
if (vTable.version < 4) then begin
FbException.setVersionError(status, 'IReplicatedTransaction', vTable.version, 4);
end
else begin
ReplicatedTransactionVTable(vTable).insertRecord2(Self, status, schemaName, tableName, record_);
end;
FbException.checkException(status);
end;
procedure IReplicatedTransaction.updateRecord2(status: IStatus; schemaName: PAnsiChar; tableName: PAnsiChar; orgRecord: IReplicatedRecord; newRecord: IReplicatedRecord);
begin
if (vTable.version < 4) then begin
FbException.setVersionError(status, 'IReplicatedTransaction', vTable.version, 4);
end
else begin
ReplicatedTransactionVTable(vTable).updateRecord2(Self, status, schemaName, tableName, orgRecord, newRecord);
end;
FbException.checkException(status);
end;
procedure IReplicatedTransaction.deleteRecord2(status: IStatus; schemaName: PAnsiChar; tableName: PAnsiChar; record_: IReplicatedRecord);
begin
if (vTable.version < 4) then begin
FbException.setVersionError(status, 'IReplicatedTransaction', vTable.version, 4);
end
else begin
ReplicatedTransactionVTable(vTable).deleteRecord2(Self, status, schemaName, tableName, record_);
end;
FbException.checkException(status);
end;
procedure IReplicatedTransaction.executeSqlIntl2(status: IStatus; charset: Cardinal; schemaSearchPath: PAnsiChar; sql: PAnsiChar);
begin
if (vTable.version < 4) then begin
FbException.setVersionError(status, 'IReplicatedTransaction', vTable.version, 4);
end
else begin
ReplicatedTransactionVTable(vTable).executeSqlIntl2(Self, status, charset, schemaSearchPath, sql);
end;
FbException.checkException(status);
end;
@ -9604,9 +9758,20 @@ begin
FbException.checkException(status);
end;
procedure IReplicatedSession.setSequence(status: IStatus; name: PAnsiChar; value: Int64);
procedure IReplicatedSession.deprecatedSetSequence(status: IStatus; name: PAnsiChar; value: Int64);
begin
ReplicatedSessionVTable(vTable).setSequence(Self, status, name, value);
ReplicatedSessionVTable(vTable).deprecatedSetSequence(Self, status, name, value);
FbException.checkException(status);
end;
procedure IReplicatedSession.setSequence2(status: IStatus; schemaName: PAnsiChar; genName: PAnsiChar; value: Int64);
begin
if (vTable.version < 5) then begin
FbException.setVersionError(status, 'IReplicatedSession', vTable.version, 5);
end
else begin
ReplicatedSessionVTable(vTable).setSequence2(Self, status, schemaName, genName, value);
end;
FbException.checkException(status);
end;
@ -9650,9 +9815,9 @@ begin
FbException.checkException(status);
end;
procedure IProfilerSession.defineStatement(status: IStatus; statementId: Int64; parentStatementId: Int64; type_: PAnsiChar; packageName: PAnsiChar; routineName: PAnsiChar; sqlText: PAnsiChar);
procedure IProfilerSession.deprecatedDefineStatement(status: IStatus; statementId: Int64; parentStatementId: Int64; type_: PAnsiChar; packageName: PAnsiChar; routineName: PAnsiChar; sqlText: PAnsiChar);
begin
ProfilerSessionVTable(vTable).defineStatement(Self, status, statementId, parentStatementId, type_, packageName, routineName, sqlText);
ProfilerSessionVTable(vTable).deprecatedDefineStatement(Self, status, statementId, parentStatementId, type_, packageName, routineName, sqlText);
FbException.checkException(status);
end;
@ -9708,6 +9873,17 @@ begin
ProfilerSessionVTable(vTable).afterRecordSourceGetRecord(Self, statementId, requestId, cursorId, recSourceId, stats);
end;
procedure IProfilerSession.defineStatement2(status: IStatus; statementId: Int64; parentStatementId: Int64; type_: PAnsiChar; schemaName: PAnsiChar; packageName: PAnsiChar; routineName: PAnsiChar; sqlText: PAnsiChar);
begin
if (vTable.version < 4) then begin
deprecatedDefineStatement(status, statementId, parentStatementId, type, packageName, routineName, sqlText);
end
else begin
ProfilerSessionVTable(vTable).defineStatement2(Self, status, statementId, parentStatementId, type_, schemaName, packageName, routineName, sqlText);
end;
FbException.checkException(status);
end;
function IProfilerStats.getElapsedTicks(): QWord;
begin
Result := ProfilerStatsVTable(vTable).getElapsedTicks(Self);
@ -11098,6 +11274,16 @@ begin
end
end;
function IMessageMetadataImpl_getSchemaDispatcher(this: IMessageMetadata; status: IStatus; index: Cardinal): PAnsiChar; cdecl;
begin
Result := nil;
try
Result := IMessageMetadataImpl(this).getSchema(status, index);
except
on e: Exception do FbException.catchException(status, e);
end
end;
var
IMessageMetadataImpl_vTable: MessageMetadataVTable;
@ -11253,6 +11439,15 @@ begin
end
end;
procedure IMetadataBuilderImpl_setSchemaDispatcher(this: IMetadataBuilder; status: IStatus; index: Cardinal; schema: PAnsiChar); cdecl;
begin
try
IMetadataBuilderImpl(this).setSchema(status, index, schema);
except
on e: Exception do FbException.catchException(status, e);
end
end;
var
IMetadataBuilderImpl_vTable: MetadataBuilderVTable;
@ -14051,6 +14246,16 @@ begin
end
end;
function IRoutineMetadataImpl_getSchemaDispatcher(this: IRoutineMetadata; status: IStatus): PAnsiChar; cdecl;
begin
Result := nil;
try
Result := IRoutineMetadataImpl(this).getSchema(status);
except
on e: Exception do FbException.catchException(status, e);
end
end;
var
IRoutineMetadataImpl_vTable: RoutineMetadataVTable;
@ -14449,6 +14654,16 @@ begin
end
end;
function IUtilImpl_executeCreateDatabase2Dispatcher(this: IUtil; status: IStatus; stmtLength: Cardinal; creatDBstatement: PAnsiChar; dialect: Cardinal; dpbLength: Cardinal; dpb: BytePtr; stmtIsCreateDb: BooleanPtr): IAttachment; cdecl;
begin
Result := nil;
try
Result := IUtilImpl(this).executeCreateDatabase2(status, stmtLength, creatDBstatement, dialect, dpbLength, dpb, stmtIsCreateDb);
except
on e: Exception do FbException.catchException(status, e);
end
end;
var
IUtilImpl_vTable: UtilVTable;
@ -16646,46 +16861,82 @@ begin
end
end;
procedure IReplicatedTransactionImpl_insertRecordDispatcher(this: IReplicatedTransaction; status: IStatus; name: PAnsiChar; record_: IReplicatedRecord); cdecl;
procedure IReplicatedTransactionImpl_deprecatedInsertRecordDispatcher(this: IReplicatedTransaction; status: IStatus; name: PAnsiChar; record_: IReplicatedRecord); cdecl;
begin
try
IReplicatedTransactionImpl(this).insertRecord(status, name, record_);
IReplicatedTransactionImpl(this).deprecatedInsertRecord(status, name, record_);
except
on e: Exception do FbException.catchException(status, e);
end
end;
procedure IReplicatedTransactionImpl_updateRecordDispatcher(this: IReplicatedTransaction; status: IStatus; name: PAnsiChar; orgRecord: IReplicatedRecord; newRecord: IReplicatedRecord); cdecl;
procedure IReplicatedTransactionImpl_deprecatedUpdateRecordDispatcher(this: IReplicatedTransaction; status: IStatus; name: PAnsiChar; orgRecord: IReplicatedRecord; newRecord: IReplicatedRecord); cdecl;
begin
try
IReplicatedTransactionImpl(this).updateRecord(status, name, orgRecord, newRecord);
IReplicatedTransactionImpl(this).deprecatedUpdateRecord(status, name, orgRecord, newRecord);
except
on e: Exception do FbException.catchException(status, e);
end
end;
procedure IReplicatedTransactionImpl_deleteRecordDispatcher(this: IReplicatedTransaction; status: IStatus; name: PAnsiChar; record_: IReplicatedRecord); cdecl;
procedure IReplicatedTransactionImpl_deprecatedDeleteRecordDispatcher(this: IReplicatedTransaction; status: IStatus; name: PAnsiChar; record_: IReplicatedRecord); cdecl;
begin
try
IReplicatedTransactionImpl(this).deleteRecord(status, name, record_);
IReplicatedTransactionImpl(this).deprecatedDeleteRecord(status, name, record_);
except
on e: Exception do FbException.catchException(status, e);
end
end;
procedure IReplicatedTransactionImpl_executeSqlDispatcher(this: IReplicatedTransaction; status: IStatus; sql: PAnsiChar); cdecl;
procedure IReplicatedTransactionImpl_deprecatedExecuteSqlDispatcher(this: IReplicatedTransaction; status: IStatus; sql: PAnsiChar); cdecl;
begin
try
IReplicatedTransactionImpl(this).executeSql(status, sql);
IReplicatedTransactionImpl(this).deprecatedExecuteSql(status, sql);
except
on e: Exception do FbException.catchException(status, e);
end
end;
procedure IReplicatedTransactionImpl_executeSqlIntlDispatcher(this: IReplicatedTransaction; status: IStatus; charset: Cardinal; sql: PAnsiChar); cdecl;
procedure IReplicatedTransactionImpl_deprecatedExecuteSqlIntlDispatcher(this: IReplicatedTransaction; status: IStatus; charset: Cardinal; sql: PAnsiChar); cdecl;
begin
try
IReplicatedTransactionImpl(this).executeSqlIntl(status, charset, sql);
IReplicatedTransactionImpl(this).deprecatedExecuteSqlIntl(status, charset, sql);
except
on e: Exception do FbException.catchException(status, e);
end
end;
procedure IReplicatedTransactionImpl_insertRecord2Dispatcher(this: IReplicatedTransaction; status: IStatus; schemaName: PAnsiChar; tableName: PAnsiChar; record_: IReplicatedRecord); cdecl;
begin
try
IReplicatedTransactionImpl(this).insertRecord2(status, schemaName, tableName, record_);
except
on e: Exception do FbException.catchException(status, e);
end
end;
procedure IReplicatedTransactionImpl_updateRecord2Dispatcher(this: IReplicatedTransaction; status: IStatus; schemaName: PAnsiChar; tableName: PAnsiChar; orgRecord: IReplicatedRecord; newRecord: IReplicatedRecord); cdecl;
begin
try
IReplicatedTransactionImpl(this).updateRecord2(status, schemaName, tableName, orgRecord, newRecord);
except
on e: Exception do FbException.catchException(status, e);
end
end;
procedure IReplicatedTransactionImpl_deleteRecord2Dispatcher(this: IReplicatedTransaction; status: IStatus; schemaName: PAnsiChar; tableName: PAnsiChar; record_: IReplicatedRecord); cdecl;
begin
try
IReplicatedTransactionImpl(this).deleteRecord2(status, schemaName, tableName, record_);
except
on e: Exception do FbException.catchException(status, e);
end
end;
procedure IReplicatedTransactionImpl_executeSqlIntl2Dispatcher(this: IReplicatedTransaction; status: IStatus; charset: Cardinal; schemaSearchPath: PAnsiChar; sql: PAnsiChar); cdecl;
begin
try
IReplicatedTransactionImpl(this).executeSqlIntl2(status, charset, schemaSearchPath, sql);
except
on e: Exception do FbException.catchException(status, e);
end
@ -16766,10 +17017,19 @@ begin
end
end;
procedure IReplicatedSessionImpl_setSequenceDispatcher(this: IReplicatedSession; status: IStatus; name: PAnsiChar; value: Int64); cdecl;
procedure IReplicatedSessionImpl_deprecatedSetSequenceDispatcher(this: IReplicatedSession; status: IStatus; name: PAnsiChar; value: Int64); cdecl;
begin
try
IReplicatedSessionImpl(this).setSequence(status, name, value);
IReplicatedSessionImpl(this).deprecatedSetSequence(status, name, value);
except
on e: Exception do FbException.catchException(status, e);
end
end;
procedure IReplicatedSessionImpl_setSequence2Dispatcher(this: IReplicatedSession; status: IStatus; schemaName: PAnsiChar; genName: PAnsiChar; value: Int64); cdecl;
begin
try
IReplicatedSessionImpl(this).setSequence2(status, schemaName, genName, value);
except
on e: Exception do FbException.catchException(status, e);
end
@ -16904,10 +17164,10 @@ begin
end
end;
procedure IProfilerSessionImpl_defineStatementDispatcher(this: IProfilerSession; status: IStatus; statementId: Int64; parentStatementId: Int64; type_: PAnsiChar; packageName: PAnsiChar; routineName: PAnsiChar; sqlText: PAnsiChar); cdecl;
procedure IProfilerSessionImpl_deprecatedDefineStatementDispatcher(this: IProfilerSession; status: IStatus; statementId: Int64; parentStatementId: Int64; type_: PAnsiChar; packageName: PAnsiChar; routineName: PAnsiChar; sqlText: PAnsiChar); cdecl;
begin
try
IProfilerSessionImpl(this).defineStatement(status, statementId, parentStatementId, type_, packageName, routineName, sqlText);
IProfilerSessionImpl(this).deprecatedDefineStatement(status, statementId, parentStatementId, type_, packageName, routineName, sqlText);
except
on e: Exception do FbException.catchException(status, e);
end
@ -17003,6 +17263,15 @@ begin
end
end;
procedure IProfilerSessionImpl_defineStatement2Dispatcher(this: IProfilerSession; status: IStatus; statementId: Int64; parentStatementId: Int64; type_: PAnsiChar; schemaName: PAnsiChar; packageName: PAnsiChar; routineName: PAnsiChar; sqlText: PAnsiChar); cdecl;
begin
try
IProfilerSessionImpl(this).defineStatement2(status, statementId, parentStatementId, type_, schemaName, packageName, routineName, sqlText);
except
on e: Exception do FbException.catchException(status, e);
end
end;
var
IProfilerSessionImpl_vTable: ProfilerSessionVTable;
@ -17261,7 +17530,7 @@ initialization
ITransactionImpl_vTable.disconnect := @ITransactionImpl_disconnectDispatcher;
IMessageMetadataImpl_vTable := MessageMetadataVTable.create;
IMessageMetadataImpl_vTable.version := 4;
IMessageMetadataImpl_vTable.version := 5;
IMessageMetadataImpl_vTable.addRef := @IMessageMetadataImpl_addRefDispatcher;
IMessageMetadataImpl_vTable.release := @IMessageMetadataImpl_releaseDispatcher;
IMessageMetadataImpl_vTable.getCount := @IMessageMetadataImpl_getCountDispatcher;
@ -17281,9 +17550,10 @@ initialization
IMessageMetadataImpl_vTable.getMessageLength := @IMessageMetadataImpl_getMessageLengthDispatcher;
IMessageMetadataImpl_vTable.getAlignment := @IMessageMetadataImpl_getAlignmentDispatcher;
IMessageMetadataImpl_vTable.getAlignedLength := @IMessageMetadataImpl_getAlignedLengthDispatcher;
IMessageMetadataImpl_vTable.getSchema := @IMessageMetadataImpl_getSchemaDispatcher;
IMetadataBuilderImpl_vTable := MetadataBuilderVTable.create;
IMetadataBuilderImpl_vTable.version := 4;
IMetadataBuilderImpl_vTable.version := 5;
IMetadataBuilderImpl_vTable.addRef := @IMetadataBuilderImpl_addRefDispatcher;
IMetadataBuilderImpl_vTable.release := @IMetadataBuilderImpl_releaseDispatcher;
IMetadataBuilderImpl_vTable.setType := @IMetadataBuilderImpl_setTypeDispatcher;
@ -17300,6 +17570,7 @@ initialization
IMetadataBuilderImpl_vTable.setRelation := @IMetadataBuilderImpl_setRelationDispatcher;
IMetadataBuilderImpl_vTable.setOwner := @IMetadataBuilderImpl_setOwnerDispatcher;
IMetadataBuilderImpl_vTable.setAlias := @IMetadataBuilderImpl_setAliasDispatcher;
IMetadataBuilderImpl_vTable.setSchema := @IMetadataBuilderImpl_setSchemaDispatcher;
IResultSetImpl_vTable := ResultSetVTable.create;
IResultSetImpl_vTable.version := 5;
@ -17662,7 +17933,7 @@ initialization
IExternalTriggerImpl_vTable.execute := @IExternalTriggerImpl_executeDispatcher;
IRoutineMetadataImpl_vTable := RoutineMetadataVTable.create;
IRoutineMetadataImpl_vTable.version := 2;
IRoutineMetadataImpl_vTable.version := 3;
IRoutineMetadataImpl_vTable.getPackage := @IRoutineMetadataImpl_getPackageDispatcher;
IRoutineMetadataImpl_vTable.getName := @IRoutineMetadataImpl_getNameDispatcher;
IRoutineMetadataImpl_vTable.getEntryPoint := @IRoutineMetadataImpl_getEntryPointDispatcher;
@ -17672,6 +17943,7 @@ initialization
IRoutineMetadataImpl_vTable.getTriggerMetadata := @IRoutineMetadataImpl_getTriggerMetadataDispatcher;
IRoutineMetadataImpl_vTable.getTriggerTable := @IRoutineMetadataImpl_getTriggerTableDispatcher;
IRoutineMetadataImpl_vTable.getTriggerType := @IRoutineMetadataImpl_getTriggerTypeDispatcher;
IRoutineMetadataImpl_vTable.getSchema := @IRoutineMetadataImpl_getSchemaDispatcher;
IExternalEngineImpl_vTable := ExternalEngineVTable.create;
IExternalEngineImpl_vTable.version := 4;
@ -17702,7 +17974,7 @@ initialization
IVersionCallbackImpl_vTable.callback := @IVersionCallbackImpl_callbackDispatcher;
IUtilImpl_vTable := UtilVTable.create;
IUtilImpl_vTable.version := 4;
IUtilImpl_vTable.version := 5;
IUtilImpl_vTable.getFbVersion := @IUtilImpl_getFbVersionDispatcher;
IUtilImpl_vTable.loadBlob := @IUtilImpl_loadBlobDispatcher;
IUtilImpl_vTable.dumpBlob := @IUtilImpl_dumpBlobDispatcher;
@ -17725,6 +17997,7 @@ initialization
IUtilImpl_vTable.getInt128 := @IUtilImpl_getInt128Dispatcher;
IUtilImpl_vTable.decodeTimeTzEx := @IUtilImpl_decodeTimeTzExDispatcher;
IUtilImpl_vTable.decodeTimeStampTzEx := @IUtilImpl_decodeTimeStampTzExDispatcher;
IUtilImpl_vTable.executeCreateDatabase2 := @IUtilImpl_executeCreateDatabase2Dispatcher;
IOffsetsCallbackImpl_vTable := OffsetsCallbackVTable.create;
IOffsetsCallbackImpl_vTable.version := 2;
@ -18009,7 +18282,7 @@ initialization
IReplicatedRecordImpl_vTable.getRawData := @IReplicatedRecordImpl_getRawDataDispatcher;
IReplicatedTransactionImpl_vTable := ReplicatedTransactionVTable.create;
IReplicatedTransactionImpl_vTable.version := 3;
IReplicatedTransactionImpl_vTable.version := 4;
IReplicatedTransactionImpl_vTable.dispose := @IReplicatedTransactionImpl_disposeDispatcher;
IReplicatedTransactionImpl_vTable.prepare := @IReplicatedTransactionImpl_prepareDispatcher;
IReplicatedTransactionImpl_vTable.commit := @IReplicatedTransactionImpl_commitDispatcher;
@ -18017,14 +18290,18 @@ initialization
IReplicatedTransactionImpl_vTable.startSavepoint := @IReplicatedTransactionImpl_startSavepointDispatcher;
IReplicatedTransactionImpl_vTable.releaseSavepoint := @IReplicatedTransactionImpl_releaseSavepointDispatcher;
IReplicatedTransactionImpl_vTable.rollbackSavepoint := @IReplicatedTransactionImpl_rollbackSavepointDispatcher;
IReplicatedTransactionImpl_vTable.insertRecord := @IReplicatedTransactionImpl_insertRecordDispatcher;
IReplicatedTransactionImpl_vTable.updateRecord := @IReplicatedTransactionImpl_updateRecordDispatcher;
IReplicatedTransactionImpl_vTable.deleteRecord := @IReplicatedTransactionImpl_deleteRecordDispatcher;
IReplicatedTransactionImpl_vTable.executeSql := @IReplicatedTransactionImpl_executeSqlDispatcher;
IReplicatedTransactionImpl_vTable.executeSqlIntl := @IReplicatedTransactionImpl_executeSqlIntlDispatcher;
IReplicatedTransactionImpl_vTable.deprecatedInsertRecord := @IReplicatedTransactionImpl_deprecatedInsertRecordDispatcher;
IReplicatedTransactionImpl_vTable.deprecatedUpdateRecord := @IReplicatedTransactionImpl_deprecatedUpdateRecordDispatcher;
IReplicatedTransactionImpl_vTable.deprecatedDeleteRecord := @IReplicatedTransactionImpl_deprecatedDeleteRecordDispatcher;
IReplicatedTransactionImpl_vTable.deprecatedExecuteSql := @IReplicatedTransactionImpl_deprecatedExecuteSqlDispatcher;
IReplicatedTransactionImpl_vTable.deprecatedExecuteSqlIntl := @IReplicatedTransactionImpl_deprecatedExecuteSqlIntlDispatcher;
IReplicatedTransactionImpl_vTable.insertRecord2 := @IReplicatedTransactionImpl_insertRecord2Dispatcher;
IReplicatedTransactionImpl_vTable.updateRecord2 := @IReplicatedTransactionImpl_updateRecord2Dispatcher;
IReplicatedTransactionImpl_vTable.deleteRecord2 := @IReplicatedTransactionImpl_deleteRecord2Dispatcher;
IReplicatedTransactionImpl_vTable.executeSqlIntl2 := @IReplicatedTransactionImpl_executeSqlIntl2Dispatcher;
IReplicatedSessionImpl_vTable := ReplicatedSessionVTable.create;
IReplicatedSessionImpl_vTable.version := 4;
IReplicatedSessionImpl_vTable.version := 5;
IReplicatedSessionImpl_vTable.addRef := @IReplicatedSessionImpl_addRefDispatcher;
IReplicatedSessionImpl_vTable.release := @IReplicatedSessionImpl_releaseDispatcher;
IReplicatedSessionImpl_vTable.setOwner := @IReplicatedSessionImpl_setOwnerDispatcher;
@ -18032,7 +18309,8 @@ initialization
IReplicatedSessionImpl_vTable.init := @IReplicatedSessionImpl_initDispatcher;
IReplicatedSessionImpl_vTable.startTransaction := @IReplicatedSessionImpl_startTransactionDispatcher;
IReplicatedSessionImpl_vTable.cleanupTransaction := @IReplicatedSessionImpl_cleanupTransactionDispatcher;
IReplicatedSessionImpl_vTable.setSequence := @IReplicatedSessionImpl_setSequenceDispatcher;
IReplicatedSessionImpl_vTable.deprecatedSetSequence := @IReplicatedSessionImpl_deprecatedSetSequenceDispatcher;
IReplicatedSessionImpl_vTable.setSequence2 := @IReplicatedSessionImpl_setSequence2Dispatcher;
IProfilerPluginImpl_vTable := ProfilerPluginVTable.create;
IProfilerPluginImpl_vTable.version := 4;
@ -18045,13 +18323,13 @@ initialization
IProfilerPluginImpl_vTable.flush := @IProfilerPluginImpl_flushDispatcher;
IProfilerSessionImpl_vTable := ProfilerSessionVTable.create;
IProfilerSessionImpl_vTable.version := 3;
IProfilerSessionImpl_vTable.version := 4;
IProfilerSessionImpl_vTable.dispose := @IProfilerSessionImpl_disposeDispatcher;
IProfilerSessionImpl_vTable.getId := @IProfilerSessionImpl_getIdDispatcher;
IProfilerSessionImpl_vTable.getFlags := @IProfilerSessionImpl_getFlagsDispatcher;
IProfilerSessionImpl_vTable.cancel := @IProfilerSessionImpl_cancelDispatcher;
IProfilerSessionImpl_vTable.finish := @IProfilerSessionImpl_finishDispatcher;
IProfilerSessionImpl_vTable.defineStatement := @IProfilerSessionImpl_defineStatementDispatcher;
IProfilerSessionImpl_vTable.deprecatedDefineStatement := @IProfilerSessionImpl_deprecatedDefineStatementDispatcher;
IProfilerSessionImpl_vTable.defineCursor := @IProfilerSessionImpl_defineCursorDispatcher;
IProfilerSessionImpl_vTable.defineRecordSource := @IProfilerSessionImpl_defineRecordSourceDispatcher;
IProfilerSessionImpl_vTable.onRequestStart := @IProfilerSessionImpl_onRequestStartDispatcher;
@ -18062,6 +18340,7 @@ initialization
IProfilerSessionImpl_vTable.afterRecordSourceOpen := @IProfilerSessionImpl_afterRecordSourceOpenDispatcher;
IProfilerSessionImpl_vTable.beforeRecordSourceGetRecord := @IProfilerSessionImpl_beforeRecordSourceGetRecordDispatcher;
IProfilerSessionImpl_vTable.afterRecordSourceGetRecord := @IProfilerSessionImpl_afterRecordSourceGetRecordDispatcher;
IProfilerSessionImpl_vTable.defineStatement2 := @IProfilerSessionImpl_defineStatement2Dispatcher;
IProfilerStatsImpl_vTable := ProfilerStatsVTable.create;
IProfilerStatsImpl_vTable.version := 2;

View File

@ -55,7 +55,7 @@ FrontendParser::AnyNode FrontendParser::internalParse()
if (command == TOKEN_ADD)
{
if (auto tableName = parseName())
if (auto tableName = parseQualifiedName())
{
AddNode node;
node.tableName = std::move(tableName.value());
@ -120,15 +120,15 @@ FrontendParser::AnyNode FrontendParser::internalParse()
} while(true);
}
else if (command == TOKEN_COPY)
{
{
CopyNode node;
if (auto source = parseName())
if (auto source = parseQualifiedName())
node.source = std::move(source.value());
else
return InvalidNode();
if (auto destination = parseName())
if (auto destination = parseQualifiedName())
node.destination = std::move(destination.value());
else
return InvalidNode();
@ -344,7 +344,7 @@ FrontendParser::AnySetNode FrontendParser::parseSet()
else if (text == TOKEN_NAMES)
{
SetNamesNode node;
node.name = parseName();
node.name = parseQualifiedName();
if (parseEof())
return node;
@ -496,11 +496,11 @@ FrontendParser::AnyShowNode FrontendParser::parseShow()
{
const auto& text = showCommandToken.processedText;
if (const auto parsed = parseShowOptName<ShowChecksNode>(text, TOKEN_CHECKS, 5))
if (const auto parsed = parseShowOptQualifiedName<ShowChecksNode>(text, TOKEN_CHECKS, 5))
return parsed.value();
else if (const auto parsed = parseShowOptName<ShowCollationsNode>(text, TOKEN_COLLATES, 7))
else if (const auto parsed = parseShowOptQualifiedName<ShowCollationsNode>(text, TOKEN_COLLATES, 7))
return parsed.value();
else if (const auto parsed = parseShowOptName<ShowCollationsNode>(text, TOKEN_COLLATIONS, 9))
else if (const auto parsed = parseShowOptQualifiedName<ShowCollationsNode>(text, TOKEN_COLLATIONS, 9))
return parsed.value();
else if (text.length() >= 7 && TOKEN_COMMENTS.find(text) == 0)
{
@ -512,74 +512,42 @@ FrontendParser::AnyShowNode FrontendParser::parseShow()
if (parseEof())
return ShowDatabaseNode();
}
else if (const auto parsed = parseShowOptName<ShowDependenciesNode>(text, TOKEN_DEPENDENCIES, 5))
else if (const auto parsed = parseShowOptQualifiedName<ShowDependenciesNode>(text, TOKEN_DEPENDENCIES, 5))
return parsed.value();
else if (const auto parsed = parseShowOptName<ShowDependenciesNode>(text, TOKEN_DEPENDENCY, 5))
else if (const auto parsed = parseShowOptQualifiedName<ShowDependenciesNode>(text, TOKEN_DEPENDENCY, 5))
return parsed.value();
else if (const auto parsed = parseShowOptName<ShowDomainsNode>(text, TOKEN_DOMAINS, 6))
else if (const auto parsed = parseShowOptQualifiedName<ShowDomainsNode>(text, TOKEN_DOMAINS, 6))
return parsed.value();
else if (const auto parsed = parseShowOptName<ShowExceptionsNode>(text, TOKEN_EXCEPTIONS, 5))
else if (const auto parsed = parseShowOptQualifiedName<ShowExceptionsNode>(text, TOKEN_EXCEPTIONS, 5))
return parsed.value();
else if (const auto parsed = parseShowOptName<ShowFiltersNode>(text, TOKEN_FILTERS, 6))
return parsed.value();
else if (text.length() >= 4 && TOKEN_FUNCTIONS.find(text) == 0)
{
ShowFunctionsNode node;
node.name = parseName();
node.name = parseQualifiedName(); // FIXME: package
if (node.name)
{
if (const auto token = lexer.getToken();
token.type == Token::TYPE_OTHER && token.rawText == ".")
{
node.package = node.name;
node.name = parseName();
if (parseEof())
return node;
}
else if (token.type == Token::TYPE_EOF)
{
return node;
}
}
else
if (parseEof())
return node;
}
else if (const auto parsed = parseShowOptName<ShowIndexesNode>(text, TOKEN_INDEXES, 3))
else if (const auto parsed = parseShowOptQualifiedName<ShowIndexesNode>(text, TOKEN_INDEXES, 3))
return parsed.value();
else if (const auto parsed = parseShowOptName<ShowIndexesNode>(text, TOKEN_INDICES, 0))
else if (const auto parsed = parseShowOptQualifiedName<ShowIndexesNode>(text, TOKEN_INDICES, 0))
return parsed.value();
else if (const auto parsed = parseShowOptName<ShowGeneratorsNode>(text, TOKEN_GENERATORS, 3))
else if (const auto parsed = parseShowOptQualifiedName<ShowGeneratorsNode>(text, TOKEN_GENERATORS, 3))
return parsed.value();
else if (const auto parsed = parseShowOptName<ShowGrantsNode>(text, TOKEN_GRANTS, 5))
else if (const auto parsed = parseShowOptQualifiedName<ShowGrantsNode>(text, TOKEN_GRANTS, 5))
return parsed.value();
else if (const auto parsed = parseShowOptName<ShowMappingsNode>(text, TOKEN_MAPPINGS, 3))
return parsed.value();
else if (const auto parsed = parseShowOptName<ShowPackagesNode>(text, TOKEN_PACKAGES, 4))
else if (const auto parsed = parseShowOptQualifiedName<ShowPackagesNode>(text, TOKEN_PACKAGES, 4))
return parsed.value();
else if (text.length() >= 4 && TOKEN_PROCEDURES.find(text) == 0)
{
ShowProceduresNode node;
node.name = parseName();
node.name = parseQualifiedName(); // FIXME: package
if (node.name)
{
if (const auto token = lexer.getToken();
token.type == Token::TYPE_OTHER && token.rawText == ".")
{
node.package = node.name;
node.name = parseName();
if (parseEof())
return node;
}
else if (token.type == Token::TYPE_EOF)
{
return node;
}
}
else
if (parseEof())
return node;
}
else if (const auto parsed = parseShowOptName<ShowPublicationsNode>(text, TOKEN_PUBLICATIONS, 3))
@ -596,7 +564,7 @@ FrontendParser::AnyShowNode FrontendParser::parseShow()
if (!(token.type == Token::TYPE_OTHER && token.rawText == "*"))
{
lexer.setPos(lexerPos);
node.name = parseName();
node.name = parseQualifiedName();
if (!node.name)
return InvalidNode();
@ -611,7 +579,7 @@ FrontendParser::AnyShowNode FrontendParser::parseShow()
if (parseEof())
return node;
}
else if (const auto parsed = parseShowOptName<ShowGeneratorsNode>(text, TOKEN_SEQUENCES, 3))
else if (const auto parsed = parseShowOptQualifiedName<ShowGeneratorsNode>(text, TOKEN_SEQUENCES, 3))
return parsed.value();
else if (text == TOKEN_SQL)
{
@ -656,9 +624,9 @@ FrontendParser::AnyShowNode FrontendParser::parseShow()
return node;
}
else if (const auto parsed = parseShowOptName<ShowTablesNode>(text, TOKEN_TABLES, 5))
else if (const auto parsed = parseShowOptQualifiedName<ShowTablesNode>(text, TOKEN_TABLES, 5))
return parsed.value();
else if (const auto parsed = parseShowOptName<ShowTriggersNode>(text, TOKEN_TRIGGERS, 4))
else if (const auto parsed = parseShowOptQualifiedName<ShowTriggersNode>(text, TOKEN_TRIGGERS, 4))
return parsed.value();
else if (text == TOKEN_USERS)
{
@ -670,7 +638,7 @@ FrontendParser::AnyShowNode FrontendParser::parseShow()
if (parseEof())
return ShowVersionNode();
}
else if (const auto parsed = parseShowOptName<ShowViewsNode>(text, TOKEN_VIEWS, 4))
else if (const auto parsed = parseShowOptQualifiedName<ShowViewsNode>(text, TOKEN_VIEWS, 4))
return parsed.value();
else if (text.length() >= 9 && TOKEN_WIRE_STATISTICS.find(text) == 0 ||
text == TOKEN_WIRE_STATS)
@ -706,6 +674,26 @@ std::optional<FrontendParser::AnyShowNode> FrontendParser::parseShowOptName(std:
return std::nullopt;
}
template <typename Node>
std::optional<FrontendParser::AnyShowNode> FrontendParser::parseShowOptQualifiedName(std::string_view showCommand,
std::string_view testCommand, unsigned testCommandMinLen)
{
if (showCommand == testCommand ||
(testCommandMinLen && showCommand.length() >= testCommandMinLen &&
std::string(testCommand).find(showCommand) == 0))
{
Node node;
node.name = parseQualifiedName();
if (!parseEof())
return InvalidNode();
return node;
}
return std::nullopt;
}
std::optional<std::string> FrontendParser::parseUtilEof()
{
const auto startIt = lexer.getPos();

View File

@ -27,6 +27,7 @@
#include "../isql/FrontendLexer.h"
#include "../jrd/obj.h"
#include "../common/classes/MetaString.h"
#include "../common/classes/QualifiedMetaString.h"
#include <optional>
#include <string>
#include <string_view>
@ -46,10 +47,10 @@ public:
struct InvalidNode {};
struct AddNode { Firebird::MetaString tableName; };
struct AddNode { Firebird::QualifiedMetaString tableName; };
struct BlobDumpViewNode { ISC_QUAD blobId; std::optional<std::string> file; };
struct ConnectNode { std::vector<Token> args; };
struct CopyNode { Firebird::MetaString source; Firebird::MetaString destination; std::string database; };
struct CopyNode { Firebird::QualifiedMetaString source; Firebird::QualifiedMetaString destination; std::string database; };
struct CreateDatabaseNode { std::vector<Token> args; };
struct DropDatabaseNode {};
struct EditNode { std::optional<std::string> file; };
@ -76,7 +77,7 @@ public:
struct SetListNode { std::string arg; };
struct SetLocalTimeoutNode { std::string arg; };
struct SetMaxRowsNode { std::string arg; };
struct SetNamesNode { std::optional<Firebird::MetaString> name; };
struct SetNamesNode { std::optional<Firebird::QualifiedMetaString> name; };
struct SetPerTableStatsNode { std::string arg; };
struct SetPlanNode { std::string arg; };
struct SetPlanOnlyNode { std::string arg; };
@ -91,31 +92,31 @@ public:
struct SetWireStatsNode { std::string arg; };
struct ShowNode {};
struct ShowChecksNode { std::optional<Firebird::MetaString> name; };
struct ShowCollationsNode { std::optional<Firebird::MetaString> name; };
struct ShowChecksNode { std::optional<Firebird::QualifiedMetaString> name; };
struct ShowCollationsNode { std::optional<Firebird::QualifiedMetaString> name; };
struct ShowCommentsNode {};
struct ShowDatabaseNode {};
struct ShowDomainsNode { std::optional<Firebird::MetaString> name; };
struct ShowDependenciesNode { std::optional<Firebird::MetaString> name; };
struct ShowExceptionsNode { std::optional<Firebird::MetaString> name; };
struct ShowDomainsNode { std::optional<Firebird::QualifiedMetaString> name; };
struct ShowDependenciesNode { std::optional<Firebird::QualifiedMetaString> name; };
struct ShowExceptionsNode { std::optional<Firebird::QualifiedMetaString> name; };
struct ShowFiltersNode { std::optional<Firebird::MetaString> name; };
struct ShowFunctionsNode { std::optional<Firebird::MetaString> name; std::optional<Firebird::MetaString> package; };
struct ShowGeneratorsNode { std::optional<Firebird::MetaString> name; };
struct ShowGrantsNode { std::optional<Firebird::MetaString> name; };
struct ShowIndexesNode { std::optional<Firebird::MetaString> name; };
struct ShowFunctionsNode { std::optional<Firebird::QualifiedMetaString> name; };
struct ShowGeneratorsNode { std::optional<Firebird::QualifiedMetaString> name; };
struct ShowGrantsNode { std::optional<Firebird::QualifiedMetaString> name; };
struct ShowIndexesNode { std::optional<Firebird::QualifiedMetaString> name; };
struct ShowMappingsNode { std::optional<Firebird::MetaString> name; };
struct ShowPackagesNode { std::optional<Firebird::MetaString> name; };
struct ShowProceduresNode { std::optional<Firebird::MetaString> name; std::optional<Firebird::MetaString> package; };
struct ShowPackagesNode { std::optional<Firebird::QualifiedMetaString> name; };
struct ShowProceduresNode { std::optional<Firebird::QualifiedMetaString> name; };
struct ShowPublicationsNode { std::optional<Firebird::MetaString> name; };
struct ShowRolesNode { std::optional<Firebird::MetaString> name; };
struct ShowSecClassesNode { std::optional<Firebird::MetaString> name; bool detail = false; };
struct ShowSecClassesNode { std::optional<Firebird::QualifiedMetaString> name; bool detail = false; };
struct ShowSqlDialectNode {};
struct ShowSystemNode { std::optional<ObjectType> objType; };
struct ShowTablesNode { std::optional<Firebird::MetaString> name; };
struct ShowTriggersNode { std::optional<Firebird::MetaString> name; };
struct ShowTablesNode { std::optional<Firebird::QualifiedMetaString> name; };
struct ShowTriggersNode { std::optional<Firebird::QualifiedMetaString> name; };
struct ShowUsersNode {};
struct ShowVersionNode {};
struct ShowViewsNode { std::optional<Firebird::MetaString> name; };
struct ShowViewsNode { std::optional<Firebird::QualifiedMetaString> name; };
struct ShowWireStatsNode {};
using AnySetNode = std::variant<
@ -249,6 +250,10 @@ private:
std::optional<AnyShowNode> parseShowOptName(std::string_view showCommand,
std::string_view testCommand, unsigned testCommandMinLen = 0);
template <typename Node>
std::optional<AnyShowNode> parseShowOptQualifiedName(std::string_view showCommand,
std::string_view testCommand, unsigned testCommandMinLen = 0);
bool parseEof()
{
return lexer.getToken().type == Token::TYPE_EOF;
@ -264,6 +269,27 @@ private:
return std::nullopt;
}
std::optional<Firebird::QualifiedMetaString> parseQualifiedName()
{
if (const auto name = parseName())
{
const auto lexerPos = lexer.getPos();
const auto token = lexer.getToken();
if (token.type == Token::TYPE_OTHER && token.rawText == ".")
{
if (const auto name2 = parseName())
return Firebird::QualifiedMetaString(name2.value(), name.value());
}
lexer.setPos(lexerPos);
return Firebird::QualifiedMetaString(name.value());
}
return std::nullopt;
}
std::optional<std::string> parseFileName()
{
const auto token = lexer.getToken();

View File

@ -24,8 +24,15 @@
#ifndef ISQL_EXTRA_PROTO_H
#define ISQL_EXTRA_PROTO_H
int EXTRACT_ddl(LegacyTables, const SCHAR*);
int EXTRACT_list_table(const SCHAR*, const SCHAR*, bool, SSHORT);
#include <functional>
#include "../common/classes/MetaString.h"
#include "../common/classes/QualifiedMetaString.h"
using GetDefaultCharSetForSchemaFunc = std::function<SSHORT (const Firebird::MetaString& schemaName)>;
int EXTRACT_ddl(LegacyTables, const Firebird::QualifiedMetaString&);
int EXTRACT_list_table(const Firebird::QualifiedMetaString&, const Firebird::QualifiedMetaString&, bool,
GetDefaultCharSetForSchemaFunc getDefaultCharSetForSchemaFunc);
processing_state EXTRACT_list_grants (const SCHAR*);
#endif // ISQL_EXTRA_PROTO_H

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -99,7 +99,6 @@ const size_t CHARSET_COLLATE_SIZE =
1; // null terminator
static const char* const DEFTERM = ";";
static const char* const DEFCHARSET = "NONE";
const unsigned NULL_DISP_LEN = 6;
@ -234,6 +233,7 @@ public:
size_t Termlen;
SCHAR User[128];
SCHAR Role[256];
SCHAR SearchPath[512];
USHORT SQL_dialect;
USHORT db_SQL_dialect;
// from isql.epp

View File

@ -25,10 +25,14 @@
#define ISQL_ISQL_PROTO_H
#include <firebird/Interface.h>
#include "../common/classes/fb_string.h"
#include "../common/classes/MetaString.h"
#include "../common/classes/QualifiedMetaString.h"
#include <optional>
struct IsqlVar;
void ISQL_array_dimensions(const TEXT*);
void ISQL_array_dimensions(const Firebird::QualifiedMetaString&);
//void ISQL_build_table_list(void**, FILE*, FILE*, FILE*);
//void ISQL_build_view_list(void**, FILE*, FILE*, FILE*);
//int ISQL_commit_work(int, FILE*, FILE*, FILE*);
@ -40,7 +44,7 @@ void ISQL_exit_db();
// CVC: Not found.
//int ISQL_extract(TEXT*, int, FILE*, FILE*, FILE*);
int ISQL_frontend_command(TEXT*, FILE*, FILE*, FILE*);
bool ISQL_get_base_column_null_flag(const TEXT*, const SSHORT, const TEXT*);
bool ISQL_get_base_column_null_flag(const Firebird::QualifiedMetaString&, const SSHORT, const Firebird::MetaString&);
// Shall become obsolete when collation become a part of data type as in SQL standard
enum class Get
{
@ -51,24 +55,23 @@ enum class Get
void ISQL_get_character_sets(
SSHORT char_set_id, SSHORT collation,
SSHORT default_char_set_id, Get what,
bool not_null, bool quote, TEXT* string);
bool not_null, Firebird::string& text);
SSHORT ISQL_get_default_char_set_id();
void ISQL_get_default_source(const TEXT*, TEXT*, ISC_QUAD*);
SSHORT ISQL_get_field_length(const TEXT*);
void ISQL_get_domain_default_source(const Firebird::QualifiedMetaString&, ISC_QUAD*);
SSHORT ISQL_get_field_length(const Firebird::QualifiedMetaString&);
SSHORT ISQL_get_char_length(
SSHORT fieldLength,
SSHORT characterLengthNull, SSHORT characterLength,
SSHORT characterSetIdNull, SSHORT characterSetId);
SLONG ISQL_get_index_segments(TEXT*, const size_t, const TEXT*, bool);
bool ISQL_get_null_flag(const TEXT*, TEXT*);
SLONG ISQL_get_index_segments(TEXT*, const size_t, const Firebird::QualifiedMetaString&, bool);
bool ISQL_get_null_flag(const Firebird::QualifiedMetaString&, const Firebird::MetaString&);
void ISQL_get_version(bool);
SSHORT ISQL_init(FILE*, FILE*);
#ifdef NOT_USED_OR_REPLACED
bool ISQL_is_domain(const TEXT*);
#endif
int ISQL_main(int, char**);
bool ISQL_printNumericType(const char* fieldName, const int fieldType, const int fieldSubType,
const int fieldPrecision, const int fieldScale);
Firebird::string ISQL_name_to_string(const Firebird::MetaString& name);
Firebird::string ISQL_name_to_string(const Firebird::QualifiedMetaString& name);
bool ISQL_printNumericType(const Firebird::QualifiedMetaString& fieldName, const int fieldType,
const int fieldSubType, const int fieldPrecision, const int fieldScale);
void ISQL_print_validation(FILE*, ISC_QUAD*, bool, Firebird::ITransaction*);
//void ISQL_query_database(SSHORT*, FILE*, FILE*, FILE*);
//void ISQL_reset_settings();

View File

@ -52,17 +52,18 @@ enum isql_switches
IN_SW_ISQL_QUIET = 19,
IN_SW_ISQL_ROLE = 20,
IN_SW_ISQL_ROLE2 = 21,
IN_SW_ISQL_SQLDIALECT = 22,
IN_SW_ISQL_TERM = 23,
IN_SW_ISQL_SEARCH_PATH = 22,
IN_SW_ISQL_SQLDIALECT = 23,
IN_SW_ISQL_TERM = 24,
#ifdef TRUSTED_AUTH
IN_SW_ISQL_TRUSTED = 24,
IN_SW_ISQL_TRUSTED = 25,
#endif
IN_SW_ISQL_USER = 25,
IN_SW_ISQL_VERSION = 26,
IN_SW_ISQL_USER = 26,
IN_SW_ISQL_VERSION = 27,
#ifdef DEV_BUILD
IN_SW_ISQL_EXTRACTTBL = 27,
IN_SW_ISQL_EXTRACTTBL = 28,
#endif
IN_SW_ISQL_HELP = 28
IN_SW_ISQL_HELP = 29
};
@ -91,6 +92,7 @@ static const Switches::in_sw_tab_t isql_in_sw_table[] =
{IN_SW_ISQL_QUIET , 0, "QUIET" , 0, 0, 0, false, false, 134 , 1, NULL, iqoArgNone},
{IN_SW_ISQL_ROLE , 0, "ROLE" , 0, 0, 0, false, false, 135 , 1, NULL, iqoArgString},
{IN_SW_ISQL_ROLE2 , 0, "R2" , 0, 0, 0, false, false, 136 , 2, NULL, iqoArgString},
{IN_SW_ISQL_SEARCH_PATH , 0, "SEARCH_PATH" , 0, 0, 0, false, false, 210 , 2, NULL, iqoArgString},
{IN_SW_ISQL_SQLDIALECT , 0, "SQLDIALECT" , 0, 0, 0, false, false, 137 , 1, NULL, iqoArgInteger},
{IN_SW_ISQL_SQLDIALECT , 0, "SQL_DIALECT" , 0, 0, 0, false, false, 0 , 1, NULL, iqoArgInteger},
{IN_SW_ISQL_TERM , 0, "TERMINATOR" , 0, 0, 0, false, false, 138 , 1, NULL, iqoArgString},

View File

@ -159,6 +159,33 @@ string IUTILS_name_to_string(const MetaString& name)
}
string IUTILS_name_to_string(const QualifiedMetaString& name)
{
if (isqlGlob.db_SQL_dialect > SQL_DIALECT_V6_TRANSITION)
return name.toQuotedString();
else
{
string str(name.schema.c_str());
if (name.package.hasData())
{
if (str.hasData())
str += ".";
str += name.package.c_str();
}
if (name.object.hasData())
{
if (str.hasData())
str += ".";
str += name.object.c_str();
}
return str;
}
}
void IUTILS_printf(FILE* fp, const char* buffer)
{
/**************************************

View File

@ -25,6 +25,7 @@
#define ISQL_IUTILS_PROTO_H
#include "../common/classes/MetaString.h"
#include "../common/classes/QualifiedMetaString.h"
#include "../common/classes/SafeArg.h"
#include <stdio.h>
@ -35,6 +36,7 @@ void IUTILS_msg_get(USHORT number, TEXT* msg,
void IUTILS_msg_get(USHORT number, USHORT size, TEXT* msg,
const MsgFormat::SafeArg& args = MsgFormat::SafeArg());
Firebird::string IUTILS_name_to_string(const Firebird::MetaString& name);
Firebird::string IUTILS_name_to_string(const Firebird::QualifiedMetaString& name);
void IUTILS_printf(FILE*, const char*);
void IUTILS_printf2(FILE*, const char*, ...);
void IUTILS_put_errmsg(USHORT number, const MsgFormat::SafeArg& args);

File diff suppressed because it is too large Load Diff

View File

@ -25,22 +25,23 @@
#define ISQL_SHOW_PROTO_H
#include "../common/classes/fb_string.h"
#include "../common/classes/QualifiedMetaString.h"
#include <firebird/Interface.h>
#include "../isql/FrontendParser.h"
#include "../jrd/obj.h"
#include <optional>
void SHOW_comments(bool force);
void SHOW_dbb_parameters (Firebird::IAttachment*, const UCHAR*, unsigned, bool, const char*);
processing_state SHOW_grants (const SCHAR*, const SCHAR*, ObjectType);
processing_state SHOW_grants2 (const SCHAR*, const SCHAR*, ObjectType, const TEXT*, bool);
void SHOW_grant_roles (const SCHAR*, bool*);
void SHOW_grant_roles2 (const SCHAR*, bool*, const TEXT*, bool);
processing_state SHOW_grants(const std::optional<Firebird::QualifiedMetaString>&, const SCHAR*, ObjectType);
processing_state SHOW_grants2(const Firebird::QualifiedMetaString&, const SCHAR*, ObjectType, const TEXT*, bool);
void SHOW_grant_roles(const SCHAR*, bool*, const TEXT*, bool);
void SHOW_print_metadata_text_blob(FILE*, ISC_QUAD*, bool escape_squote = false,
bool avoid_end_in_single_line_comment = false);
processing_state SHOW_metadata(const FrontendParser::AnyShowNode& node);
void SHOW_read_owner();
const Firebird::string SHOW_trigger_action(SINT64);
processing_state SHOW_maps(bool extract, const SCHAR* map_name);
bool SHOW_system_privileges(const char* role, const char* prfx, bool lf);
processing_state SHOW_maps(bool extract, const std::optional<Firebird::MetaString>& name);
bool SHOW_system_privileges(const Firebird::MetaString& name, const char* prfx, bool lf);
#endif // ISQL_SHOW_PROTO_H

Some files were not shown because too many files have changed in this diff Show More