8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-22 22: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,6 +11,16 @@ database
# #
# plugin = # 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 # Pattern (regular expression) that defines what tables must be included into
# replication. By default, all tables are replicated. # replication. By default, all tables are replicated.
# #
@ -202,6 +212,14 @@ database
# then reconnects back and tries to re-apply the latest segments from the point of failure. # then reconnects back and tries to re-apply the latest segments from the point of failure.
# #
# apply_error_timeout = 60 # 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\NoThrowTimeStamp.h" />
<ClInclude Include="..\..\..\src\common\classes\objects_array.h" /> <ClInclude Include="..\..\..\src\common\classes\objects_array.h" />
<ClInclude Include="..\..\..\src\common\classes\ParsedList.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\RefCounted.h" />
<ClInclude Include="..\..\..\src\common\classes\RefMutex.h" /> <ClInclude Include="..\..\..\src\common\classes\RefMutex.h" />
<ClInclude Include="..\..\..\src\common\classes\rwlock.h" /> <ClInclude Include="..\..\..\src\common\classes\rwlock.h" />

View File

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

View File

@ -181,7 +181,11 @@
<ClCompile Include="..\..\..\src\common\tests\StringTest.cpp" /> <ClCompile Include="..\..\..\src\common\tests\StringTest.cpp" />
<ClCompile Include="..\..\..\src\common\classes\tests\AlignerTest.cpp" /> <ClCompile Include="..\..\..\src\common\classes\tests\AlignerTest.cpp" />
<ClCompile Include="..\..\..\src\common\classes\tests\ArrayTest.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\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" /> <ClCompile Include="..\..\..\src\yvalve\gds.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -30,9 +30,21 @@
<ClCompile Include="..\..\..\src\common\classes\tests\ArrayTest.cpp"> <ClCompile Include="..\..\..\src\common\classes\tests\ArrayTest.cpp">
<Filter>source</Filter> <Filter>source</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\src\common\classes\tests\ClumpletTest.cpp">
<Filter>source</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\common\classes\tests\DoublyLinkedListTest.cpp"> <ClCompile Include="..\..\..\src\common\classes\tests\DoublyLinkedListTest.cpp">
<Filter>source</Filter> <Filter>source</Filter>
</ClCompile> </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"> <ClCompile Include="..\..\..\src\yvalve\gds.cpp">
<Filter>source</Filter> <Filter>source</Filter>
</ClCompile> </ClCompile>

View File

@ -47,7 +47,8 @@ ALTER DATABASE EXCLUDE ALL FROM PUBLICATION
-- to disable replication of specific tables: -- to disable replication of specific tables:
ALTER DATABASE EXCLUDE TABLE T1, T2, T3 FROM PUBLICATION 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. 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) - EVENT_TYPE: event type (CREATE, ALTER, DROP)
- OBJECT_TYPE: object type (TABLE, VIEW, etc) - OBJECT_TYPE: object type (TABLE, VIEW, etc)
- DDL_EVENT: event name (<ddl event item>), where <ddl_event_item> is EVENT_TYPE || ' ' || OBJECT_TYPE - 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 - OBJECT_NAME: metadata object name
- OLD_OBJECT_NAME: metadata object name before a rename - OLD_OBJECT_NAME: metadata object name before a rename
- NEW_OBJECT_NAME: metadata object name after a rename - NEW_OBJECT_NAME: metadata object name after a rename

View File

@ -109,6 +109,8 @@ execute procedure rdb$profiler.finish_session(true);
-- Data analysis -- Data analysis
set search_path to plg$profiler, public, system;
set transaction read committed; set transaction read committed;
select * from plg$prof_sessions; select * from plg$prof_sessions;
@ -243,7 +245,9 @@ Input parameters:
# Snapshot tables # 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. 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 - `RECORD_SOURCE_ID` type `BIGINT NOT NULL` - record source id
- `PARENT_RECORD_SOURCE_ID` type `BIGINT` - parent 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) - `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 - `PACKAGE_NAME` type `RDB$PACKAGE_NAME` - package name of a stored procedure
- `OBJECT_NAME` type `RDB$RELATION_NAME` - object (table, procedure) name - `OBJECT_NAME` type `RDB$RELATION_NAME` - object (table, procedure) name
- `ALIAS` type `RDB$SHORT_DESCRIPTION` - alias name - `ALIAS` type `RDB$SHORT_DESCRIPTION` - alias name

View File

@ -35,7 +35,8 @@ public:
void setAttachment(IAttachment* attachment) override; void setAttachment(IAttachment* attachment) override;
IReplicatedTransaction* startTransaction(ITransaction* transaction, ISC_INT64 number) override; IReplicatedTransaction* startTransaction(ITransaction* transaction, ISC_INT64 number) override;
FB_BOOLEAN cleanupTransaction(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: private:
friend class ReplTransaction; friend class ReplTransaction;
@ -64,11 +65,17 @@ public:
FB_BOOLEAN startSavepoint() override; FB_BOOLEAN startSavepoint() override;
FB_BOOLEAN releaseSavepoint() override; FB_BOOLEAN releaseSavepoint() override;
FB_BOOLEAN rollbackSavepoint() override; FB_BOOLEAN rollbackSavepoint() override;
FB_BOOLEAN insertRecord(const char* name, IReplicatedRecord* record) override; FB_BOOLEAN deprecatedInsertRecord(const char* name, IReplicatedRecord* record) override;
FB_BOOLEAN updateRecord(const char* name, IReplicatedRecord* orgRecord, IReplicatedRecord* newRecord) override; FB_BOOLEAN insertRecord2(const char* schemaName, const char* tableName, IReplicatedRecord* record) override;
FB_BOOLEAN deleteRecord(const char* name, IReplicatedRecord* record) override; FB_BOOLEAN deprecatedUpdateRecord(const char* name,
FB_BOOLEAN executeSql(const char* sql) override; IReplicatedRecord* orgRecord, IReplicatedRecord* newRecord) override;
FB_BOOLEAN executeSqlIntl(unsigned charset, const char* sql) 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: private:
ReplPlugin* parent; ReplPlugin* parent;
@ -245,9 +252,15 @@ FB_BOOLEAN ReplPlugin::cleanupTransaction(ISC_INT64 number)
return FB_TRUE; 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; return FB_TRUE;
} }
@ -506,9 +519,9 @@ bool ReplTransaction::dumpData(IReplicatedRecord* record)
return true; 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 try
{ {
return dumpData(record) ? FB_TRUE : FB_FALSE; 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 try
{ {
if (!dumpData(orgRecord)) 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 try
{ {
return dumpData(record) ? FB_TRUE : FB_FALSE; 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; 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; return FB_TRUE;
} }

View File

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

View File

@ -68,28 +68,28 @@ private:
void prepareDataStructures() void prepareDataStructures()
{ {
const char* script[] = { 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$VERIFIER VARCHAR(128) CHARACTER SET OCTETS NOT NULL, "
"PLG$SALT VARCHAR(32) CHARACTER SET OCTETS NOT NULL, " "PLG$SALT VARCHAR(32) CHARACTER SET OCTETS NOT NULL, "
"PLG$COMMENT RDB$DESCRIPTION, PLG$FIRST SEC$NAME_PART, " "PLG$COMMENT SYSTEM.RDB$DESCRIPTION, PLG$FIRST SYSTEM.SEC$NAME_PART, "
"PLG$MIDDLE SEC$NAME_PART, PLG$LAST SEC$NAME_PART, " "PLG$MIDDLE SYSTEM.SEC$NAME_PART, PLG$LAST SYSTEM.SEC$NAME_PART, "
"PLG$ATTRIBUTES RDB$DESCRIPTION, " "PLG$ATTRIBUTES SYSTEM.RDB$DESCRIPTION, "
"PLG$ACTIVE BOOLEAN)" "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, " "SELECT PLG$USER_NAME, PLG$VERIFIER, PLG$SALT, PLG$COMMENT, "
" PLG$FIRST, PLG$MIDDLE, PLG$LAST, PLG$ATTRIBUTES, PLG$ACTIVE " " 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" " 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, " "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 NULL
}; };
@ -160,7 +160,7 @@ private:
Firebird::string userName2(user->userName()->get()); Firebird::string userName2(user->userName()->get());
prepareName(userName2, '\''); prepareName(userName2, '\'');
Firebird::string selGrantor; 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'", "WHERE RDB$USER = '%s' AND RDB$RELATION_NAME = '%s' AND RDB$PRIVILEGE = 'M'",
userName2.c_str(), ADMIN_ROLE); userName2.c_str(), ADMIN_ROLE);
Message out; Message out;
@ -353,7 +353,7 @@ public:
case Firebird::IUser::OP_USER_ADD: case Firebird::IUser::OP_USER_ADD:
{ {
const char* insert = 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(?, ?, ?, ?, ?, ?, ?, ?, ?)"; "PLG$COMMENT, PLG$ATTRIBUTES, PLG$ACTIVE) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)";
Firebird::IStatement* stmt = NULL; Firebird::IStatement* stmt = NULL;
@ -455,7 +455,7 @@ public:
case Firebird::IUser::OP_USER_MODIFY: 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; Firebird::AutoPtr<Varfield> verifier, slt;
if (user->password()->entered()) if (user->password()->entered())
@ -558,7 +558,7 @@ public:
case Firebird::IUser::OP_USER_DELETE: 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; Firebird::IStatement* stmt = NULL;
try try
{ {
@ -601,11 +601,11 @@ public:
case Firebird::IUser::OP_USER_DISPLAY: case Firebird::IUser::OP_USER_DISPLAY:
{ {
Firebird::string disp = 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) " " 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, " "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 " " 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 "; " ON PLG$SRP_VIEW.PLG$USER_NAME = ADMINS.RDB$USER ";
if (user->userName()->entered()) if (user->userName()->entered())
{ {

View File

@ -196,7 +196,7 @@ public:
HANDSHAKE_DEBUG(fprintf(stderr, "Srv: SRP1: started transaction\n")); HANDSHAKE_DEBUG(fprintf(stderr, "Srv: SRP1: started transaction\n"));
const char* sql = 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); stmt = att->prepare(&status, tra, 0, sql, 3, IStatement::PREPARE_PREFETCH_METADATA);
if (status->getState() & IStatus::STATE_ERRORS) 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); Firebird::ClumpletWriter dpb(Firebird::ClumpletReader::dpbList, MAX_DPB_SIZE);
dpb.insertByte(isc_dpb_sec_attach, TRUE); dpb.insertByte(isc_dpb_sec_attach, TRUE);
dpb.insertString(isc_dpb_config, Firebird::ParsedList::getNonLoopbackProviders(secDbName)); 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; unsigned int authBlockSize;
const unsigned char* authBlock = logonInfo->authBlock(&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) // this checks the "entered" flags for each parameter (except the name)
// and makes all non-entered parameters null valued // 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 STORE (TRANSACTION_HANDLE transaction REQUEST_HANDLE request) U IN PLG$VIEW_USERS USING
STR_STORE(U.PLG$USER_NAME, user->userName()->get()); STR_STORE(U.PLG$USER_NAME, user->userName()->get());

View File

@ -64,7 +64,11 @@ const UCHAR PWD_REQUEST[] =
blr_begin, blr_begin,
blr_for, blr_for,
blr_rse, 1, 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_first,
blr_literal, blr_short, 0, 1, 0, blr_literal, blr_short, 0, 1, 0,
blr_boolean, blr_boolean,

View File

@ -561,7 +561,7 @@ bool BackupRelationTask::fileWriter(Item& item)
BurpGlobals* tdgbl = item.m_gbl; BurpGlobals* tdgbl = item.m_gbl;
fb_assert(tdgbl == m_masterGbl); 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 // msg 142 writing data for relation %s
IOBuffer*& buf = item.m_buffer = NULL; IOBuffer*& buf = item.m_buffer = NULL;

View File

@ -45,6 +45,7 @@ namespace
{"RDB$ROLES", 0, DB_VERSION_DDL9}, // IB5 {"RDB$ROLES", 0, DB_VERSION_DDL9}, // IB5
{"RDB$PACKAGES", 0, DB_VERSION_DDL12}, // FB3 {"RDB$PACKAGES", 0, DB_VERSION_DDL12}, // FB3
{"RDB$PUBLICATIONS", 0, DB_VERSION_DDL13}, // FB4 {"RDB$PUBLICATIONS", 0, DB_VERSION_DDL13}, // FB4
{"RDB$SCHEMAS", 0, DB_VERSION_DDL14}, // FB6
{0, 0, 0} {0, 0, 0}
}; };
@ -102,13 +103,16 @@ void detectRuntimeODS()
Firebird::IRequest* req_handle = nullptr; Firebird::IRequest* req_handle = nullptr;
FOR (REQUEST_HANDLE req_handle) FOR (REQUEST_HANDLE req_handle)
RFR IN RDB$RELATION_FIELDS RFR IN RDB$RELATION_FIELDS
WITH (RFR.RDB$RELATION_NAME = 'RDB$RELATIONS' OR RFR.RDB$RELATION_NAME = 'RDB$RELATION_FIELDS') WITH (RFR.RDB$RELATION_NAME = 'RDB$RELATIONS' OR RFR.RDB$RELATION_NAME = 'RDB$RELATION_FIELDS') AND
AND RFR.RDB$FIELD_NAME = 'RDB$SYSTEM_FLAG' RFR.RDB$FIELD_NAME = 'RDB$SYSTEM_FLAG' AND
(RFR.RDB$SCHEMA_NAME MISSING OR RFR.RDB$SCHEMA_NAME = SYSTEM_SCHEMA)
{
++count; ++count;
END_FOR; }
END_FOR
ON_ERROR ON_ERROR
general_on_error(); general_on_error();
END_ERROR; END_ERROR
MISC_release_request_silent(req_handle); MISC_release_request_silent(req_handle);
if (count != 2) if (count != 2)
@ -119,14 +123,17 @@ void detectRuntimeODS()
{ {
FOR (REQUEST_HANDLE req_handle2) FOR (REQUEST_HANDLE req_handle2)
FIRST 1 X IN RDB$RELATIONS FIRST 1 X IN RDB$RELATIONS
WITH X.RDB$RELATION_NAME = rel->relation WITH X.RDB$RELATION_NAME = rel->relation AND
AND X.RDB$SYSTEM_FLAG = 1 X.RDB$SYSTEM_FLAG = 1 AND
(X.RDB$SCHEMA_NAME MISSING OR X.RDB$SCHEMA_NAME = SYSTEM_SCHEMA)
{
if (tdgbl->runtimeODS < rel->ods_version) if (tdgbl->runtimeODS < rel->ods_version)
tdgbl->runtimeODS = rel->ods_version; tdgbl->runtimeODS = rel->ods_version;
END_FOR; }
END_FOR
ON_ERROR ON_ERROR
general_on_error(); general_on_error();
END_ERROR; END_ERROR
} }
MISC_release_request_silent(req_handle2); MISC_release_request_silent(req_handle2);
@ -138,15 +145,18 @@ void detectRuntimeODS()
{ {
FOR (REQUEST_HANDLE req_handle3) FOR (REQUEST_HANDLE req_handle3)
FIRST 1 X2 IN RDB$RELATION_FIELDS FIRST 1 X2 IN RDB$RELATION_FIELDS
WITH X2.RDB$RELATION_NAME = rf->relation WITH X2.RDB$RELATION_NAME = rf->relation AND
AND X2.RDB$FIELD_NAME = rf->field X2.RDB$FIELD_NAME = rf->field AND
AND X2.RDB$SYSTEM_FLAG = 1 X2.RDB$SYSTEM_FLAG = 1 AND
(X2.RDB$SCHEMA_NAME MISSING OR X2.RDB$SCHEMA_NAME = SYSTEM_SCHEMA)
{
if (tdgbl->runtimeODS < rf->ods_version) if (tdgbl->runtimeODS < rf->ods_version)
tdgbl->runtimeODS = rf->ods_version; tdgbl->runtimeODS = rf->ods_version;
END_FOR; }
END_FOR
ON_ERROR ON_ERROR
general_on_error(); general_on_error();
END_ERROR; END_ERROR
} }
MISC_release_request_silent(req_handle3); 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_DDL12 = 120; // ods12.0 db, FB3.0
const int DB_VERSION_DDL13 = 130; // ods13.0 db, FB4.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_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 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]; tdgbl->gbl_sw_user = argv[itr];
break; 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: case IN_SW_BURP_SKIP_DATA:
if (++itr >= argc) if (++itr >= argc)
{ {
BURP_error(354, true); BURP_error(354, true);
// missing regular expression to skip tables // 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; break;
case IN_SW_BURP_INCLUDE_DATA: case IN_SW_BURP_INCLUDE_DATA:
if (++itr >= argc) if (++itr >= argc)
@ -779,7 +801,9 @@ int gbak(Firebird::UtilSvc* uSvc)
BURP_error(389, true); BURP_error(389, true);
// missing regular expression to include tables // 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; break;
case IN_SW_BURP_ROLE: case IN_SW_BURP_ROLE:
if (++itr >= argc) if (++itr >= argc)
@ -1153,6 +1177,8 @@ int gbak(Firebird::UtilSvc* uSvc)
dpb.insertBytes(isc_dpb_auth_block, authBlock, authSize); 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, // 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. // 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(); for (const Switches::in_sw_tab_t* in_sw_tab = switches.getTableMod();
@ -2664,59 +2690,25 @@ void close_platf(DESC file)
#endif // WIN_NT #endif // WIN_NT
void BurpGlobals::setupSkipData(const Firebird::string& regexp) void BurpGlobals::setupSkipIncludePattern(const string& regexp, USHORT alreadySetErrorCode,
AutoPtr<SimilarToRegex>& matcher)
{ {
if (skipDataMatcher) if (matcher)
{ BURP_error(alreadySetErrorCode, true);
BURP_error(356, true);
// msg 356 regular expression to skip tables was already set
}
// Compile skip relation expressions // Compile expressions
try try
{ {
if (regexp.hasData()) if (regexp.hasData())
{ {
Firebird::string filter(regexp); string filter(regexp);
if (!uSvc->utf8FileNames()) if (!uSvc->utf8FileNames())
ISC_systemToUtf8(filter); ISC_systemToUtf8(filter);
BurpGlobals* tdgbl = BurpGlobals::getSpecific(); BurpGlobals* tdgbl = BurpGlobals::getSpecific();
skipDataMatcher.reset(FB_NEW_POOL(tdgbl->getPool()) Firebird::SimilarToRegex( matcher.reset(FB_NEW_POOL(tdgbl->getPool()) SimilarToRegex(
tdgbl->getPool(), Firebird::SimilarToFlag::CASE_INSENSITIVE, tdgbl->getPool(), 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,
filter.c_str(), filter.length(), filter.c_str(), filter.length(),
"\\", 1)); "\\", 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) if (gbl_sw_meta)
return true; return true;
@ -2764,10 +2756,12 @@ bool BurpGlobals::skipRelation(const char* name)
{ false, false, true} // NM p { false, false, true} // NM p
}; };
const enum Pattern res1 = checkPattern(skipDataMatcher, name); const enum Pattern res1sch = checkPattern(skipSchemaDataMatcher, name.schema.c_str());
const enum Pattern res2 = checkPattern(includeDataMatcher, name); 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) void BurpGlobals::read_stats(SINT64* stats)
@ -2888,24 +2882,6 @@ void BurpGlobals::print_stats_header()
burp_output(false, "\n"); 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) static void processFetchPass(const SCHAR*& password, int& itr, const int argc, Firebird::UtilSvc::ArgvType& argv)
{ {
if (++itr >= argc) if (++itr >= argc)

View File

@ -42,7 +42,9 @@
#include "../common/UtilSvc.h" #include "../common/UtilSvc.h"
#include "../common/classes/array.h" #include "../common/classes/array.h"
#include "../common/classes/fb_pair.h" #include "../common/classes/fb_pair.h"
#include "../common/classes/GenericMap.h"
#include "../common/classes/MetaString.h" #include "../common/classes/MetaString.h"
#include "../common/classes/QualifiedMetaString.h"
#include "../common/SimilarToRegex.h" #include "../common/SimilarToRegex.h"
#include "../common/status.h" #include "../common/status.h"
#include "../common/sha.h" #include "../common/sha.h"
@ -120,7 +122,8 @@ enum rec_type {
rec_package, // Package rec_package, // Package
rec_db_creator, // Database creator rec_db_creator, // Database creator
rec_publication, // Publication 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. Version 11: FB4.0.
SQL SECURITY feature, tables RDB$PUBLICATIONS/RDB$PUBLICATION_TABLES. 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 // max array dimension
@ -259,6 +265,7 @@ enum att_type {
att_database_sql_security, // default sql security value att_database_sql_security, // default sql security value
att_default_pub_active, // default publication status att_default_pub_active, // default publication status
att_default_pub_auto_enable, att_default_pub_auto_enable,
att_database_dfl_charset_schema_name, // default character set schema name
// Relation attributes // Relation attributes
@ -282,6 +289,7 @@ enum att_type {
att_relation_type, att_relation_type,
att_relation_sql_security_deprecated, // can be removed later att_relation_sql_security_deprecated, // can be removed later
att_relation_sql_security, att_relation_sql_security,
att_relation_schema_name,
// Field attributes (used for both global and local fields) // 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_owner_name, // FB3.0, ODS12_0,
att_field_generator_name, att_field_generator_name,
att_field_identity_type, att_field_identity_type,
att_field_schema_name,
// Index attributes // Index attributes
@ -357,6 +366,7 @@ enum att_type {
att_index_expression_blr, att_index_expression_blr,
att_index_condition_source, att_index_condition_source,
att_index_condition_blr, att_index_condition_blr,
att_index_foreign_key_schema_name,
// Data record // Data record
@ -381,6 +391,7 @@ enum att_type {
// Security class attributes // Security class attributes
// FIXME: SERIES + ... ?
att_class_security_class = SERIES + 10, att_class_security_class = SERIES + 10,
att_class_acl, att_class_acl,
att_class_description, att_class_description,
@ -396,7 +407,9 @@ enum att_type {
att_xdr_length = SERIES + 16, att_xdr_length = SERIES + 16,
att_xdr_array, att_xdr_array,
att_class_description2, att_class_description2,
att_view_relation_schema_name,
// Trigger attributes // Trigger attributes
@ -419,6 +432,7 @@ enum att_type {
att_trig_type2, att_trig_type2,
att_trig_sql_security_deprecated, // can be removed later att_trig_sql_security_deprecated, // can be removed later
att_trig_sql_security, att_trig_sql_security,
att_trig_schema_name,
// Function attributes // Function attributes
@ -444,6 +458,7 @@ enum att_type {
att_function_deterministic_flag, att_function_deterministic_flag,
att_function_sql_security_deprecated, // can be removed later att_function_sql_security_deprecated, // can be removed later
att_function_sql_security, att_function_sql_security,
att_function_schema_name,
// Function argument attributes // Function argument attributes
@ -467,6 +482,9 @@ enum att_type {
att_functionarg_field_name, att_functionarg_field_name,
att_functionarg_relation_name, att_functionarg_relation_name,
att_functionarg_description, att_functionarg_description,
att_functionarg_schema_name,
att_functionarg_field_source_schema_name,
att_functionarg_relation_schema_name,
// TYPE relation attributes // TYPE relation attributes
att_type_name = SERIES, att_type_name = SERIES,
@ -490,6 +508,7 @@ enum att_type {
att_trigmsg_name = SERIES, att_trigmsg_name = SERIES,
att_trigmsg_number, att_trigmsg_number,
att_trigmsg_text, att_trigmsg_text,
att_trigmsg_schema_name,
// User privilege attributes // User privilege attributes
att_priv_user = SERIES, att_priv_user = SERIES,
@ -500,6 +519,8 @@ enum att_type {
att_priv_field_name, att_priv_field_name,
att_priv_user_type, att_priv_user_type,
att_priv_obj_type, att_priv_obj_type,
att_priv_user_schema_name,
att_priv_object_schema_name,
// files for shadowing purposes // files for shadowing purposes
att_file_filename = SERIES, att_file_filename = SERIES,
@ -519,6 +540,7 @@ enum att_type {
att_gen_sysflag, att_gen_sysflag,
att_gen_init_val, att_gen_init_val,
att_gen_id_increment, att_gen_id_increment,
att_gen_schema_name,
// Stored procedure attributes // Stored procedure attributes
@ -541,6 +563,7 @@ enum att_type {
att_procedure_private_flag, att_procedure_private_flag,
att_procedure_sql_security_deprecated, // can be removed later att_procedure_sql_security_deprecated, // can be removed later
att_procedure_sql_security, att_procedure_sql_security,
att_procedure_schema_name,
// Stored procedure parameter attributes // Stored procedure parameter attributes
@ -557,6 +580,8 @@ enum att_type {
att_procedureprm_mechanism, att_procedureprm_mechanism,
att_procedureprm_field_name, att_procedureprm_field_name,
att_procedureprm_relation_name, att_procedureprm_relation_name,
att_procedureprm_field_source_schema_name,
att_procedureprm_relation_schema_name,
// Exception attributes // Exception attributes
@ -567,6 +592,7 @@ enum att_type {
att_exception_msg2, att_exception_msg2,
att_exception_security_class, // FB3.0, ODS12_0 att_exception_security_class, // FB3.0, ODS12_0
att_exception_owner_name, att_exception_owner_name,
att_exception_schema_name, // FB6.0, ODS14_0
// Relation constraints attributes // Relation constraints attributes
@ -576,6 +602,7 @@ enum att_type {
att_rel_constraint_defer, att_rel_constraint_defer,
att_rel_constraint_init, att_rel_constraint_init,
att_rel_constraint_index, att_rel_constraint_index,
att_rel_constraint_schema_name,
// Referential constraints attributes // Referential constraints attributes
@ -584,6 +611,8 @@ enum att_type {
att_ref_match_option, att_ref_match_option,
att_ref_update_rule, att_ref_update_rule,
att_ref_delete_rule, att_ref_delete_rule,
att_ref_schema_name,
att_ref_unique_const_schema_name,
// SQL roles attributes // SQL roles attributes
att_role_name = SERIES, att_role_name = SERIES,
@ -594,6 +623,7 @@ enum att_type {
// Check constraints attributes // Check constraints attributes
att_chk_constraint_name = SERIES, att_chk_constraint_name = SERIES,
att_chk_trigger_name, att_chk_trigger_name,
att_chk_schema_name,
// Character Set attributes // Character Set attributes
att_charset_name = SERIES, att_charset_name = SERIES,
@ -607,6 +637,8 @@ enum att_type {
att_charset_bytes_char, att_charset_bytes_char,
att_charset_security_class, // FB3.0, ODS12_0 att_charset_security_class, // FB3.0, ODS12_0
att_charset_owner_name, att_charset_owner_name,
att_charset_schema_name,
att_charset_coll_schema_name,
att_coll_name = SERIES, att_coll_name = SERIES,
att_coll_id, att_coll_id,
@ -620,6 +652,7 @@ enum att_type {
att_coll_specific_attr, att_coll_specific_attr,
att_coll_security_class, // FB3.0, ODS12_0 att_coll_security_class, // FB3.0, ODS12_0
att_coll_owner_name, att_coll_owner_name,
att_coll_schema_name,
// Names mapping // Names mapping
att_map_name = SERIES, att_map_name = SERIES,
@ -643,6 +676,7 @@ enum att_type {
att_package_description, att_package_description,
att_package_sql_security_deprecated, // can be removed later att_package_sql_security_deprecated, // can be removed later
att_package_sql_security, att_package_sql_security,
att_package_schema_name,
// Database creators // Database creators
att_dbc_user = SERIES, att_dbc_user = SERIES,
@ -656,7 +690,16 @@ enum att_type {
// Publication tables // Publication tables
att_ptab_pub_name = SERIES, 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_system_flag;
SSHORT fld_name_length; SSHORT fld_name_length;
TEXT fld_name [GDS_NAME_LEN]; TEXT fld_name [GDS_NAME_LEN];
TEXT fld_source [GDS_NAME_LEN]; Firebird::QualifiedMetaString fld_source;
TEXT fld_base [GDS_NAME_LEN]; TEXT fld_base [GDS_NAME_LEN];
TEXT fld_query_name [GDS_NAME_LEN]; TEXT fld_query_name [GDS_NAME_LEN];
TEXT fld_security_class [GDS_NAME_LEN]; TEXT fld_security_class [GDS_NAME_LEN];
@ -748,8 +791,7 @@ struct burp_rel
burp_fld* rel_fields; burp_fld* rel_fields;
SSHORT rel_flags; SSHORT rel_flags;
SSHORT rel_id; SSHORT rel_id;
SSHORT rel_name_length; Firebird::QualifiedMetaString rel_name;
GDS_NAME rel_name;
GDS_NAME rel_owner; // relation owner, if not us GDS_NAME rel_owner; // relation owner, if not us
ULONG rel_max_pp; // max pointer page sequence number ULONG rel_max_pp; // max pointer page sequence number
}; };
@ -763,7 +805,7 @@ enum burp_rel_flags_vals {
struct burp_pkg struct burp_pkg
{ {
burp_pkg* pkg_next; burp_pkg* pkg_next;
GDS_NAME pkg_name; Firebird::QualifiedMetaString pkg_name;
GDS_NAME pkg_owner; GDS_NAME pkg_owner;
}; };
@ -772,16 +814,14 @@ struct burp_pkg
struct burp_prc struct burp_prc
{ {
burp_prc* prc_next; burp_prc* prc_next;
//SSHORT prc_name_length; // Currently useless, but didn't want to delete it. Firebird::QualifiedMetaString prc_name;
GDS_NAME prc_package;
GDS_NAME prc_name;
GDS_NAME prc_owner; // relation owner, if not us GDS_NAME prc_owner; // relation owner, if not us
}; };
struct gfld struct gfld
{ {
TEXT gfld_name [GDS_NAME_LEN]; Firebird::QualifiedMetaString gfld_name;
ISC_QUAD gfld_vb; ISC_QUAD gfld_vb;
ISC_QUAD gfld_vs; ISC_QUAD gfld_vs;
ISC_QUAD gfld_vs2; ISC_QUAD gfld_vs2;
@ -806,7 +846,7 @@ struct burp_meta_obj
{ {
burp_meta_obj* obj_next; burp_meta_obj* obj_next;
USHORT obj_type; USHORT obj_type;
GDS_NAME obj_name; Firebird::QualifiedMetaString obj_name;
bool obj_class; bool obj_class;
}; };
@ -1144,6 +1184,7 @@ public:
Firebird::IRequest* handles_get_ref_constraint_req_handle1; Firebird::IRequest* handles_get_ref_constraint_req_handle1;
Firebird::IRequest* handles_get_rel_constraint_req_handle1; Firebird::IRequest* handles_get_rel_constraint_req_handle1;
Firebird::IRequest* handles_get_relation_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_security_class_req_handle1;
Firebird::IRequest* handles_get_sql_roles_req_handle1; Firebird::IRequest* handles_get_sql_roles_req_handle1;
Firebird::IRequest* handles_get_trigger_message_req_handle1; Firebird::IRequest* handles_get_trigger_message_req_handle1;
@ -1189,9 +1230,9 @@ public:
{ {
ThreadData::restoreSpecific(); ThreadData::restoreSpecific();
} }
void setupSkipData(const Firebird::string& regexp); void setupSkipIncludePattern(const Firebird::string& regexp, USHORT alreadySetErrorCode,
void setupIncludeData(const Firebird::string& regexp); Firebird::AutoPtr<Firebird::SimilarToRegex>& matcher);
bool skipRelation(const char* name); bool skipRelation(const Firebird::QualifiedMetaString& name);
char veryEnd; char veryEnd;
//starting after this members must be initialized in constructor explicitly //starting after this members must be initialized in constructor explicitly
@ -1199,9 +1240,8 @@ public:
Firebird::FbLocalStatus status_vector; Firebird::FbLocalStatus status_vector;
Firebird::ThrowLocalStatus throwStatus; Firebird::ThrowLocalStatus throwStatus;
Firebird::Array<Firebird::Pair<Firebird::NonPooled<Firebird::MetaString, Firebird::MetaString> > > Firebird::NonPooledMap<Firebird::QualifiedMetaString, Firebird::QualifiedMetaString> defaultCollations;
defaultCollations; Firebird::SortedArray<Firebird::QualifiedMetaString> systemFields;
Firebird::SortedArray<Firebird::MetaString> systemFields;
Firebird::Array<UCHAR> gbl_dpb_data; Firebird::Array<UCHAR> gbl_dpb_data;
Firebird::UtilSvc* uSvc; Firebird::UtilSvc* uSvc;
bool master; // set for master thread only bool master; // set for master thread only
@ -1211,7 +1251,9 @@ public:
bool firstMap; // this is the first time we entered get_mapping() bool firstMap; // this is the first time we entered get_mapping()
bool firstDbc; // this is the first time we entered get_db_creators() bool firstDbc; // this is the first time we entered get_db_creators()
bool stdIoMode; // stdin or stdout is used as backup file bool stdIoMode; // stdin or stdout is used as backup file
Firebird::AutoPtr<Firebird::SimilarToRegex> skipSchemaDataMatcher;
Firebird::AutoPtr<Firebird::SimilarToRegex> skipDataMatcher; Firebird::AutoPtr<Firebird::SimilarToRegex> skipDataMatcher;
Firebird::AutoPtr<Firebird::SimilarToRegex> includeSchemaDataMatcher;
Firebird::AutoPtr<Firebird::SimilarToRegex> includeDataMatcher; Firebird::AutoPtr<Firebird::SimilarToRegex> includeDataMatcher;
public: 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 MsgFormat::SafeArg& arg = MsgFormat::SafeArg());
void BURP_error(USHORT, bool, const char* str); void BURP_error(USHORT, bool, const char* str);
void BURP_error_redirect(Firebird::IStatus*, USHORT, const MsgFormat::SafeArg& arg = MsgFormat::SafeArg()); 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_partial(bool, USHORT, const MsgFormat::SafeArg& arg = MsgFormat::SafeArg());
void BURP_msg_put(bool, USHORT, const MsgFormat::SafeArg& arg); 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. 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_PARALLEL_WORKERS = 54; // parallel workers
const int IN_SW_BURP_DIRECT_IO = 55; // direct IO for backup files 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"; 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_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}, {IN_SW_BURP_SE, 0, "SERVICE", 0, 0, 0, false, false, 277, 2, NULL, boGeneral},
// msg 277: @1SE(RVICE) use services manager // 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}, {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 // 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}, {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) // 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}, {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_host_name);
FB_IPB_TAG(isc_dpb_os_user); FB_IPB_TAG(isc_dpb_os_user);
FB_IPB_TAG(isc_dpb_owner); FB_IPB_TAG(isc_dpb_owner);
FB_IPB_TAG(isc_dpb_search_path);
return TAG_STRING; return TAG_STRING;
} }
@ -324,6 +325,8 @@ IntlParametersBlock::TagType IntlSpbStart::checkTag(UCHAR tag, const char** tagN
case isc_action_svc_validate: case isc_action_svc_validate:
switch (tag) 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_incl);
FB_IPB_TAG(isc_spb_val_tab_excl); FB_IPB_TAG(isc_spb_val_tab_excl);
FB_IPB_TAG(isc_spb_val_idx_incl); 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) void MetadataBuilder::setRelation(CheckStatusWrapper* status, unsigned index, const char* relation)
{ {
try try
@ -407,6 +422,9 @@ void MsgMetadata::assign(IMessageMetadata* from)
items[index].field = from->getField(&status, index); items[index].field = from->getField(&status, index);
check(&status); check(&status);
items[index].schema = from->getSchema(&status, index);
check(&status);
items[index].relation = from->getRelation(&status, index); items[index].relation = from->getRelation(&status, index);
check(&status); check(&status);

View File

@ -50,6 +50,7 @@ public:
{ {
explicit Item(MemoryPool& pool) explicit Item(MemoryPool& pool)
: field(pool), : field(pool),
schema(pool),
relation(pool), relation(pool),
owner(pool), owner(pool),
alias(pool), alias(pool),
@ -67,6 +68,7 @@ public:
Item(MemoryPool& pool, const Item& v) Item(MemoryPool& pool, const Item& v)
: field(pool, v.field), : field(pool, v.field),
schema(pool, v.schema),
relation(pool, v.relation), relation(pool, v.relation),
owner(pool, v.owner), owner(pool, v.owner),
alias(pool, v.alias), alias(pool, v.alias),
@ -83,6 +85,7 @@ public:
} }
string field; string field;
string schema;
string relation; string relation;
string owner; string owner;
string alias; string alias;
@ -165,6 +168,15 @@ public:
return NULL; 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) const char* getRelation(CheckStatusWrapper* status, unsigned index)
{ {
if (index < items.getCount()) if (index < items.getCount())
@ -329,6 +341,7 @@ public:
unsigned addField(CheckStatusWrapper* status); unsigned addField(CheckStatusWrapper* status);
IMessageMetadata* getMetadata(CheckStatusWrapper* status); IMessageMetadata* getMetadata(CheckStatusWrapper* status);
void setField(CheckStatusWrapper* status, unsigned index, const char* field); 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 setRelation(CheckStatusWrapper* status, unsigned index, const char* relation);
void setOwner(CheckStatusWrapper* status, unsigned index, const char* owner); void setOwner(CheckStatusWrapper* status, unsigned index, const char* owner);
void setAlias(CheckStatusWrapper* status, unsigned index, const char* alias); 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_BOOLEAN, "BOOLEAN", false)
PARSER_TOKEN(TOK_BOTH, "BOTH", false) PARSER_TOKEN(TOK_BOTH, "BOTH", false)
PARSER_TOKEN(TOK_BREAK, "BREAK", true) PARSER_TOKEN(TOK_BREAK, "BREAK", true)
PARSER_TOKEN(TOK_BTRIM, "BTRIM", false)
PARSER_TOKEN(TOK_BY, "BY", false) PARSER_TOKEN(TOK_BY, "BY", false)
PARSER_TOKEN(TOK_CALL, "CALL", false) PARSER_TOKEN(TOK_CALL, "CALL", false)
PARSER_TOKEN(TOK_CALLER, "CALLER", true) 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_CONNECTION, "CURRENT_CONNECTION", false)
PARSER_TOKEN(TOK_CURRENT_DATE, "CURRENT_DATE", false) PARSER_TOKEN(TOK_CURRENT_DATE, "CURRENT_DATE", false)
PARSER_TOKEN(TOK_CURRENT_ROLE, "CURRENT_ROLE", 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_TIME, "CURRENT_TIME", false)
PARSER_TOKEN(TOK_CURRENT_TIMESTAMP, "CURRENT_TIMESTAMP", false) PARSER_TOKEN(TOK_CURRENT_TIMESTAMP, "CURRENT_TIMESTAMP", false)
PARSER_TOKEN(TOK_CURRENT_TRANSACTION, "CURRENT_TRANSACTION", 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_LOWER, "LOWER", false)
PARSER_TOKEN(TOK_LPAD, "LPAD", true) PARSER_TOKEN(TOK_LPAD, "LPAD", true)
PARSER_TOKEN(TOK_LPARAM, "LPARAM", true) PARSER_TOKEN(TOK_LPARAM, "LPARAM", true)
PARSER_TOKEN(TOK_LTRIM, "LTRIM", false)
PARSER_TOKEN(TOK_MAKE_DBKEY, "MAKE_DBKEY", true) PARSER_TOKEN(TOK_MAKE_DBKEY, "MAKE_DBKEY", true)
PARSER_TOKEN(TOK_MANUAL, "MANUAL", true) PARSER_TOKEN(TOK_MANUAL, "MANUAL", true)
PARSER_TOKEN(TOK_MAPPING, "MAPPING", 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_PUBLIC, "RSA_PUBLIC", true)
PARSER_TOKEN(TOK_RSA_SIGN_HASH, "RSA_SIGN_HASH", true) PARSER_TOKEN(TOK_RSA_SIGN_HASH, "RSA_SIGN_HASH", true)
PARSER_TOKEN(TOK_RSA_VERIFY_HASH, "RSA_VERIFY_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_SALT_LENGTH, "SALT_LENGTH", true)
PARSER_TOKEN(TOK_SAVEPOINT, "SAVEPOINT", false) PARSER_TOKEN(TOK_SAVEPOINT, "SAVEPOINT", false)
PARSER_TOKEN(TOK_SCALAR_ARRAY, "SCALAR_ARRAY", true) 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_SCROLL, "SCROLL", false)
PARSER_TOKEN(TOK_SEARCH_PATH, "SEARCH_PATH", true)
PARSER_TOKEN(TOK_SECOND, "SECOND", false) PARSER_TOKEN(TOK_SECOND, "SECOND", false)
PARSER_TOKEN(TOK_SECURITY, "SECURITY", true) PARSER_TOKEN(TOK_SECURITY, "SECURITY", true)
PARSER_TOKEN(TOK_SEGMENT, "SEGMENT", 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_TRAPS, "TRAPS", true)
PARSER_TOKEN(TOK_TRIGGER, "TRIGGER", false) PARSER_TOKEN(TOK_TRIGGER, "TRIGGER", false)
PARSER_TOKEN(TOK_TRIM, "TRIM", 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_TRUE, "TRUE", false)
PARSER_TOKEN(TOK_TRUNC, "TRUNC", true) PARSER_TOKEN(TOK_TRUNC, "TRUNC", true)
PARSER_TOKEN(TOK_TRUSTED, "TRUSTED", 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_scale,
isc_info_sql_length, isc_info_sql_length,
isc_info_sql_field, isc_info_sql_field,
isc_info_sql_relation_schema,
isc_info_sql_relation, isc_info_sql_relation,
isc_info_sql_owner, isc_info_sql_owner,
isc_info_sql_alias, isc_info_sql_alias,
@ -337,6 +338,10 @@ void StatementMetadata::parse(unsigned bufferLength, const UCHAR* buffer)
getStringInfo(&buffer, bufferEnd, &param->field); getStringInfo(&buffer, bufferEnd, &param->field);
break; break;
case isc_info_sql_relation_schema:
getStringInfo(&buffer, bufferEnd, &param->schema);
break;
case isc_info_sql_relation: case isc_info_sql_relation:
getStringInfo(&buffer, bufferEnd, &param->relation); getStringInfo(&buffer, bufferEnd, &param->relation);
break; break;

View File

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

View File

@ -33,6 +33,12 @@ namespace Firebird {
class BlrReader class BlrReader
{ {
public:
struct Flags
{
bool searchSystemSchema = false;
};
public: public:
BlrReader(const UCHAR* buffer, unsigned maxLen) BlrReader(const UCHAR* buffer, unsigned maxLen)
: start(buffer), : start(buffer),
@ -121,6 +127,50 @@ public:
return (b4 << 24) | (b3 << 16) | (b2 << 8) | b1; 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 checkByte(UCHAR expected)
{ {
UCHAR byte = getByte(); UCHAR byte = getByte();

View File

@ -490,6 +490,8 @@ ClumpletReader::ClumpletType ClumpletReader::getClumpletType(UCHAR tag) const
case isc_action_svc_validate: case isc_action_svc_validate:
switch (tag) 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_incl:
case isc_spb_val_tab_excl: case isc_spb_val_tab_excl:
case isc_spb_val_idx_incl: case isc_spb_val_idx_incl:

View File

@ -31,7 +31,11 @@
#include "../common/classes/fb_string.h" #include "../common/classes/fb_string.h"
#include "../common/classes/fb_pair.h" #include "../common/classes/fb_pair.h"
#include "../common/classes/objects_array.h"
#include "../common/StatusArg.h"
#include "../jrd/constants.h" #include "../jrd/constants.h"
#include <algorithm>
#include <cctype>
#ifdef SFIO #ifdef SFIO
#include <stdio.h> #include <stdio.h>
@ -68,6 +72,119 @@ public:
MetaString(MemoryPool&, const MetaString& m) { set(m); } MetaString(MemoryPool&, const MetaString& m) { set(m); }
MetaString(MemoryPool&, const AbstractString& s) { assign(s.c_str(), s.length()); } 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, FB_SIZE_T l);
MetaString& assign(const char* s) { return assign(s, s ? fb_strlen(s) : 0); } MetaString& assign(const char* s) { return assign(s, s ? fb_strlen(s) : 0); }
MetaString& clear() { return assign(nullptr, 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); add(item);
} }
Array(std::initializer_list<T> items)
: Array()
{
for (auto& item : items)
add(item);
}
~Array() ~Array()
{ {
freeData(); freeData();

View File

@ -306,12 +306,24 @@ namespace Firebird
return iterator(this, getCount()); return iterator(this, getCount());
} }
const T& front() const
{
fb_assert(getCount() > 0);
return *begin();
}
T& front() T& front()
{ {
fb_assert(getCount() > 0); fb_assert(getCount() > 0);
return *begin(); return *begin();
} }
const T& back() const
{
fb_assert(getCount() > 0);
return *iterator(this, getCount() - 1);
}
T& back() T& back()
{ {
fb_assert(getCount() > 0); fb_assert(getCount() > 0);
@ -372,6 +384,13 @@ namespace Firebird
add(item); add(item);
} }
ObjectsArray(std::initializer_list<T> items)
: A()
{
for (auto& item : items)
add(item);
}
ObjectsArray() : ObjectsArray() :
A() 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; return 0;
case isc_sdl_field: case isc_sdl_field:
case isc_sdl_schema:
case isc_sdl_relation: case isc_sdl_relation:
print_string(control, offset); print_string(control, offset);
break; break;

View File

@ -175,7 +175,8 @@ ISC_STATUS SDL_info(CheckStatusWrapper* status_vector,
const UCHAR* p = sdl; const UCHAR* p = sdl;
info->sdl_info_fid = info->sdl_info_rid = 0; 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) if (*p++ != isc_sdl_version1)
return error(status_vector, Arg::Gds(isc_invalid_sdl) << Arg::Num(0)); 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; p += n;
break; 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: case isc_sdl_relation:
n = *p++; 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; p += n;
break; break;
@ -281,6 +288,7 @@ int SDL_walk(CheckStatusWrapper* status_vector,
break; break;
case isc_sdl_field: case isc_sdl_field:
case isc_sdl_schema:
case isc_sdl_relation: case isc_sdl_relation:
n = *p++; n = *p++;
p += n; p += n;

View File

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

View File

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

View File

@ -142,7 +142,7 @@ void BlrDebugWriter::putDebugSubFunction(DeclareSubFuncNode* subFuncNode)
debugData.add(fb_dbg_subfunc); debugData.add(fb_dbg_subfunc);
dsql_udf* subFunc = subFuncNode->dsqlFunction; 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); USHORT len = MIN(name.length(), MAX_UCHAR);
debugData.add(len); debugData.add(len);
@ -162,7 +162,7 @@ void BlrDebugWriter::putDebugSubProcedure(DeclareSubProcNode* subProcNode)
debugData.add(fb_dbg_subproc); debugData.add(fb_dbg_subproc);
dsql_prc* subProc = subProcNode->dsqlProcedure; 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); USHORT len = MIN(name.length(), MAX_UCHAR);
debugData.add(len); 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_context,
(context->ctx_flags & CTX_system) != 0, (context->ctx_flags & CTX_system) != 0,
(context->ctx_flags & CTX_returning) != 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_alias[0].toQuotedString().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_internal_alias.toQuotedString().c_str());
} }
} }
#endif #endif
@ -99,40 +99,88 @@ void DsqlCompilerScratch::putDtype(const TypeClause* field, bool useSubType)
if (field->notNull) if (field->notNull)
appendUChar(blr_not_nullable); 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) if (field->explicitCollation)
{ {
appendUChar(blr_column_name2); if (field->typeOfTable.schema != ddlSchema)
appendUChar(field->fullDomain ? blr_domain_full : blr_domain_type_of); {
appendMetaString(field->typeOfTable.c_str()); appendUChar(blr_column_name3);
appendMetaString(field->typeOfName.c_str()); appendUChar(field->fullDomain ? blr_domain_full : blr_domain_type_of);
appendUShort(field->textType); 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 else
{ {
appendUChar(blr_column_name); if (field->typeOfTable.schema != ddlSchema)
appendUChar(field->fullDomain ? blr_domain_full : blr_domain_type_of); {
appendMetaString(field->typeOfTable.c_str()); appendUChar(blr_column_name3);
appendMetaString(field->typeOfName.c_str()); 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 else
{ {
if (field->explicitCollation) if (field->explicitCollation)
{ {
appendUChar(blr_domain_name2); if (field->typeOfName.schema != ddlSchema)
appendUChar(field->fullDomain ? blr_domain_full : blr_domain_type_of); {
appendMetaString(field->typeOfName.c_str()); appendUChar(blr_domain_name3);
appendUShort(field->textType); 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 else
{ {
appendUChar(blr_domain_name); if (field->typeOfName.schema != ddlSchema)
appendUChar(field->fullDomain ? blr_domain_full : blr_domain_type_of); {
appendMetaString(field->typeOfName.c_str()); 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) if (type->notNull)
appendUChar(blr_not_nullable); 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); if (type->typeOfTable.schema != ddlSchema)
appendUChar(type->fullDomain ? blr_domain_full : blr_domain_type_of); {
appendMetaString(type->typeOfTable.c_str()); appendUChar(blr_column_name3);
appendMetaString(type->typeOfName.c_str()); appendUChar(type->fullDomain ? blr_domain_full : blr_domain_type_of);
appendUShort(type->textType); 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 else
{ {
appendUChar(blr_column_name); if (type->typeOfTable.schema != ddlSchema)
appendUChar(type->fullDomain ? blr_domain_full : blr_domain_type_of); {
appendMetaString(type->typeOfTable.c_str()); appendUChar(blr_column_name3);
appendMetaString(type->typeOfName.c_str()); 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 else
{ {
if (type->collate.hasData()) if (type->collate.object.hasData())
{ {
appendUChar(blr_domain_name2); if (type->typeOfName.schema != ddlSchema)
appendUChar(type->fullDomain ? blr_domain_full : blr_domain_type_of); {
appendMetaString(type->typeOfName.c_str()); appendUChar(blr_domain_name3);
appendUShort(type->textType); 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 else
{ {
appendUChar(blr_domain_name); if (type->typeOfName.schema != ddlSchema)
appendUChar(type->fullDomain ? blr_domain_full : blr_domain_type_of); {
appendMetaString(type->typeOfName.c_str()); 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. // Write out local variable field data type.
void DsqlCompilerScratch::putLocalVariableDecl(dsql_var* variable, DeclareVariableNode* hostParam, void DsqlCompilerScratch::putLocalVariableDecl(dsql_var* variable, DeclareVariableNode* hostParam,
const MetaName& collationName) QualifiedName& collationName)
{ {
const auto field = variable->field; 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) for (FB_SIZE_T i = 0; i < parameters.getCount(); ++i)
{ {
ParameterClause* parameter = parameters[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); putType(parameter->type, true);
// Add slot for null flag (parameter2). // Add slot for null flag (parameter2).
appendUChar(blr_short); appendUChar(blr_short);
appendUChar(0); 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); 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) for (FB_SIZE_T i = 0; i < returns.getCount(); ++i)
{ {
ParameterClause* parameter = returns[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); putType(parameter->type, true);
// Add slot for null flag (parameter2). // Add slot for null flag (parameter2).
appendUChar(blr_short); appendUChar(blr_short);
appendUChar(0); 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); 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 // Add CTE name into CTE aliases stack. It allows later to search for
// aliases of given CTE. // aliases of given CTE.
addCTEAlias((*cte)->alias); addCTEAlias((*cte)->alias.c_str());
} }
else else
ctes.add(*cte); 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. // Check if table reference is recursive i.e. its name is equal to the name of current processing CTE.
bool DsqlCompilerScratch::pass1RelProcIsRecursive(RecordSourceNode* input) bool DsqlCompilerScratch::pass1RelProcIsRecursive(RecordSourceNode* input)
{ {
MetaName relName; QualifiedName relName;
string relAlias; string relAlias;
if (auto procNode = nodeAs<ProcedureSourceNode>(input)) if (auto procNode = nodeAs<ProcedureSourceNode>(input))
{ {
relName = procNode->dsqlName.identifier; relName = procNode->dsqlName;
relAlias = procNode->alias; relAlias = procNode->alias;
} }
else if (auto relNode = nodeAs<RelationSourceNode>(input)) else if (auto relNode = nodeAs<RelationSourceNode>(input))
@ -951,10 +1047,10 @@ bool DsqlCompilerScratch::pass1RelProcIsRecursive(RecordSourceNode* input)
fb_assert(currCtes.hasData()); fb_assert(currCtes.hasData());
const SelectExprNode* currCte = currCtes.object(); 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) if (recursive)
addCTEAlias(relAlias.hasData() ? relAlias.c_str() : relName.c_str()); addCTEAlias(relAlias.hasData() ? relAlias.c_str() : relName.object.c_str());
return recursive; return recursive;
} }

View File

@ -96,6 +96,7 @@ public:
mainScratch(aMainScratch), mainScratch(aMainScratch),
outerMessagesMap(p), outerMessagesMap(p),
outerVarsMap(p), outerVarsMap(p),
ddlSchema(p),
ctes(p), ctes(p),
cteAliases(p), cteAliases(p),
subFunctions(p), subFunctions(p),
@ -151,16 +152,49 @@ public:
dsqlStatement = aDsqlStatement; 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 putBlrMarkers(ULONG marks);
void putDtype(const TypeClause* field, bool useSubType); void putDtype(const TypeClause* field, bool useSubType);
void putType(const TypeClause* type, 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 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); QualifiedName dummyCollationName;
putLocalVariableInit(variable, hostParam); putLocalVariableDecl(variable, nullptr, dummyCollationName);
putLocalVariableInit(variable, nullptr);
} }
void putOuterMaps(); void putOuterMaps();
@ -301,8 +335,8 @@ public:
USHORT errorHandlers = 0; // count of active error handlers USHORT errorHandlers = 0; // count of active error handlers
USHORT clientDialect = 0; // dialect passed into the API call USHORT clientDialect = 0; // dialect passed into the API call
USHORT inOuterJoin = 0; // processing inside outer-join part USHORT inOuterJoin = 0; // processing inside outer-join part
Firebird::string aliasRelationPrefix; // prefix for every relation-alias. Firebird::ObjectsArray<QualifiedName> aliasRelationPrefix; // prefix for every relation-alias.
MetaName package; // package being defined QualifiedName package; // package being defined
Firebird::Stack<SelectExprNode*> currCtes; // current processing CTE's Firebird::Stack<SelectExprNode*> currCtes; // current processing CTE's
dsql_ctx* recursiveCtx = nullptr; // context of recursive CTE dsql_ctx* recursiveCtx = nullptr; // context of recursive CTE
USHORT recursiveCtxId = 0; // id of recursive union stream context USHORT recursiveCtxId = 0; // id of recursive union stream context
@ -317,6 +351,7 @@ public:
DsqlCompilerScratch* mainScratch = nullptr; DsqlCompilerScratch* mainScratch = nullptr;
Firebird::NonPooledMap<USHORT, USHORT> outerMessagesMap; // <outer, inner> Firebird::NonPooledMap<USHORT, USHORT> outerMessagesMap; // <outer, inner>
Firebird::NonPooledMap<USHORT, USHORT> outerVarsMap; // <outer, inner> Firebird::NonPooledMap<USHORT, USHORT> outerVarsMap; // <outer, inner>
MetaName ddlSchema;
private: private:
Firebird::HalfStaticArray<SelectExprNode*, 4> ctes; // common table expressions 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); (internalScratch->flags & DsqlCompilerScratch::FLAG_INTERNAL_REQUEST);
if (!isInternalRequest && node->mustBeReplicated()) 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) 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 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 SSHORT charSetId = isInternalRequest ? CS_METADATA : attachment->att_charset;
const int debugOptions = (int) attachment->getDebugOptions().getDsqlKeepBlr(); const int debugOptions = (int) attachment->getDebugOptions().getDsqlKeepBlr();
key = FB_NEW_POOL(getPool()) RefString(getPool()); 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(); char* p = key->begin();
*p = (clientDialect << 2) | (int(isInternalRequest) << 1) | debugOptions; *p++ = (clientDialect << 2) | (int(isInternalRequest) << 1) | debugOptions;
memcpy(p + 1, &charSetId, sizeof(charSetId)); memcpy(p, &charSetId, sizeof(charSetId));
memcpy(p + 1 + sizeof(charSetId), text.c_str(), text.length()); 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) void DsqlStatementCache::buildVerifyKey(thread_db* tdbb, string& key, bool isInternalRequest)

View File

@ -36,6 +36,16 @@ using namespace Jrd;
// Class DsqlStatement // 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. // Rethrow an exception with isc_no_meta_update and prefix codes.
void DsqlStatement::rethrowDdlException(status_exception& ex, bool metadataUpdate, DdlNode* node) void DsqlStatement::rethrowDdlException(status_exception& ex, bool metadataUpdate, DdlNode* node)
{ {
@ -80,6 +90,7 @@ int DsqlStatement::release()
void DsqlStatement::doRelease() void DsqlStatement::doRelease()
{ {
fb_assert(!cacheKey.hasData());
setSqlText(nullptr); setSqlText(nullptr);
setOrgText(nullptr, 0); setOrgText(nullptr, 0);

View File

@ -68,16 +68,7 @@ public:
static void rethrowDdlException(Firebird::status_exception& ex, bool metadataUpdate, DdlNode* node); static void rethrowDdlException(Firebird::status_exception& ex, bool metadataUpdate, DdlNode* node);
public: public:
DsqlStatement(MemoryPool& pool, dsql_dbb* aDsqlAttachment) DsqlStatement(MemoryPool& pool, dsql_dbb* aDsqlAttachment);
: PermanentStorage(pool),
dsqlAttachment(aDsqlAttachment),
type(TYPE_SELECT),
flags(0),
blrVersion(5),
ports(pool)
{
pool.setStatsGroup(memoryStats);
}
protected: protected:
virtual ~DsqlStatement() = default; virtual ~DsqlStatement() = default;
@ -139,6 +130,8 @@ public:
void setCacheKey(Firebird::RefStrPtr& value) { cacheKey = value; } void setCacheKey(Firebird::RefStrPtr& value) { cacheKey = value; }
void resetCacheKey() { cacheKey = nullptr; } void resetCacheKey() { cacheKey = nullptr; }
const auto getSchemaSearchPath() const { return schemaSearchPath; }
public: public:
virtual bool isDml() const virtual bool isDml() const
{ {
@ -174,9 +167,9 @@ protected:
protected: protected:
dsql_dbb* dsqlAttachment; dsql_dbb* dsqlAttachment;
Firebird::MemoryStats memoryStats; Firebird::MemoryStats memoryStats;
Type type; // Type of statement Type type = TYPE_SELECT; // Type of statement
ULONG flags; // generic flag ULONG flags = 0; // generic flag
unsigned blrVersion; unsigned blrVersion = 5;
Firebird::RefStrPtr sqlText; Firebird::RefStrPtr sqlText;
Firebird::RefStrPtr orgText; Firebird::RefStrPtr orgText;
Firebird::RefStrPtr cacheKey; Firebird::RefStrPtr cacheKey;
@ -185,6 +178,7 @@ protected:
dsql_msg* receiveMsg = nullptr; // Per record message to be received dsql_msg* receiveMsg = nullptr; // Per record message to be received
dsql_par* eof = nullptr; // End of file parameter dsql_par* eof = nullptr; // End of file parameter
DsqlCompilerScratch* scratch = nullptr; DsqlCompilerScratch* scratch = nullptr;
Firebird::RefPtr<Firebird::AnyRef<Firebird::ObjectsArray<Firebird::MetaString>>> schemaSearchPath;
private: private:
Firebird::AtomicCounter refCounter; 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> class CollateNode final : public TypedNode<ValueExprNode, ExprNode::TYPE_COLLATE>
{ {
public: 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 virtual void getChildren(NodeRefsHolder& holder, bool dsql) const
{ {
@ -353,7 +353,7 @@ public:
virtual ValueExprNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual ValueExprNode* dsqlPass(DsqlCompilerScratch* dsqlScratch);
static ValueExprNode* pass1Collate(DsqlCompilerScratch* dsqlScratch, ValueExprNode* input, 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. // This class is used only in the parser. It turns in a CastNode in dsqlPass.
@ -394,7 +394,7 @@ private:
public: public:
NestConst<ValueExprNode> arg; 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> class CurrentUserNode final : public TypedNode<ValueExprNode, ExprNode::TYPE_CURRENT_USER>
{ {
public: public:
@ -612,7 +635,7 @@ public:
class DefaultNode : public DsqlNode<DefaultNode, ExprNode::TYPE_DEFAULT> class DefaultNode : public DsqlNode<DefaultNode, ExprNode::TYPE_DEFAULT>
{ {
public: public:
explicit DefaultNode(MemoryPool& pool, const MetaName& aRelationName, explicit DefaultNode(MemoryPool& pool, const QualifiedName& aRelationName,
const MetaName& aFieldName); const MetaName& aFieldName);
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp); 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); virtual ValueExprNode* pass1(thread_db* tdbb, CompilerScratch* csb);
public: public:
const MetaName relationName; const QualifiedName relationName;
const MetaName fieldName; const MetaName fieldName;
private: private:
@ -839,10 +862,10 @@ public:
private: private:
static dsql_fld* resolveContext(DsqlCompilerScratch* dsqlScratch, static dsql_fld* resolveContext(DsqlCompilerScratch* dsqlScratch,
const MetaName& qualifier, dsql_ctx* context); const QualifiedName& qualifier, dsql_ctx* context);
public: public:
MetaName dsqlQualifier; QualifiedName dsqlQualifier;
MetaName dsqlName; MetaName dsqlName;
dsql_ctx* const dsqlContext; dsql_ctx* const dsqlContext;
dsql_fld* const dsqlField; dsql_fld* const dsqlField;
@ -860,7 +883,7 @@ class GenIdNode final : public TypedNode<ValueExprNode, ExprNode::TYPE_GEN_ID>
{ {
public: public:
GenIdNode(MemoryPool& pool, bool aDialect1, GenIdNode(MemoryPool& pool, bool aDialect1,
const MetaName& name, const QualifiedName& name,
ValueExprNode* aArg, ValueExprNode* aArg,
bool aImplicit, bool aIdentity); bool aImplicit, bool aIdentity);
@ -987,7 +1010,7 @@ public:
void fixMinSInt128(MemoryPool& pool); void fixMinSInt128(MemoryPool& pool);
public: public:
const IntlString* dsqlStr = nullptr; NestConst<IntlString> dsqlStr;
dsc litDesc; dsc litDesc;
USHORT litNumStringLength = 0; USHORT litNumStringLength = 0;
}; };
@ -1671,7 +1694,7 @@ public:
class RecordKeyNode final : public TypedNode<ValueExprNode, ExprNode::TYPE_RECORD_KEY> class RecordKeyNode final : public TypedNode<ValueExprNode, ExprNode::TYPE_RECORD_KEY>
{ {
public: 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); static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp);
@ -1748,7 +1771,7 @@ private:
void raiseError(dsql_ctx* context) const; void raiseError(dsql_ctx* context) const;
public: public:
MetaName dsqlQualifier; QualifiedName dsqlQualifier;
NestConst<RecordSourceNode> dsqlRelation; NestConst<RecordSourceNode> dsqlRelation;
StreamType recStream; StreamType recStream;
const UCHAR blrOp; const UCHAR blrOp;

View File

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

View File

@ -173,8 +173,6 @@ public:
}; };
class DdlNode;
class DdlNode : public Node class DdlNode : public Node
{ {
public: 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, static bool deleteSecurityClass(thread_db* tdbb, jrd_tra* transaction,
const MetaName& secClass); const MetaName& secClass);
static void storePrivileges(thread_db* tdbb, jrd_tra* transaction, 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, static void deletePrivilegesByRelName(thread_db* tdbb, jrd_tra* transaction,
const MetaName& name, int type); const QualifiedName& name, int type);
public: public:
// Check permission on DDL operation. Return true if everything is OK. // Check permission on DDL operation. Return true if everything is OK.
@ -221,8 +229,8 @@ public:
enum DdlTriggerWhen { DTW_BEFORE, DTW_AFTER }; enum DdlTriggerWhen { DTW_BEFORE, DTW_AFTER };
static void executeDdlTrigger(thread_db* tdbb, jrd_tra* transaction, static void executeDdlTrigger(thread_db* tdbb, jrd_tra* transaction,
DdlTriggerWhen when, int action, const MetaName& objectName, DdlTriggerWhen when, int action, const QualifiedName& objectName,
const MetaName& oldNewObjectName, const Firebird::string& sqlText); const QualifiedName& oldNewObjectName, const Firebird::string& sqlText);
protected: protected:
typedef Firebird::Pair<Firebird::Left<MetaName, bid> > MetaNameBidPair; typedef Firebird::Pair<Firebird::Left<MetaName, bid> > MetaNameBidPair;
@ -246,9 +254,9 @@ protected:
} }
void executeDdlTrigger(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction, void executeDdlTrigger(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction,
DdlTriggerWhen when, int action, const MetaName& objectName, DdlTriggerWhen when, int action, const QualifiedName& objectName,
const MetaName& oldNewObjectName); const QualifiedName& oldNewObjectName);
void storeGlobalField(thread_db* tdbb, jrd_tra* transaction, MetaName& name, void storeGlobalField(thread_db* tdbb, jrd_tra* transaction, QualifiedName& name,
const TypeClause* field, const TypeClause* field,
const Firebird::string& computedSource = "", const Firebird::string& computedSource = "",
const BlrDebugWriter::BlrData& computedValue = BlrDebugWriter::BlrData()); const BlrDebugWriter::BlrData& computedValue = BlrDebugWriter::BlrData());
@ -468,6 +476,7 @@ public:
TYPE_CURRENT_TIME, TYPE_CURRENT_TIME,
TYPE_CURRENT_TIMESTAMP, TYPE_CURRENT_TIMESTAMP,
TYPE_CURRENT_ROLE, TYPE_CURRENT_ROLE,
TYPE_CURRENT_SCHEMA,
TYPE_CURRENT_USER, TYPE_CURRENT_USER,
TYPE_DERIVED_EXPR, TYPE_DERIVED_EXPR,
TYPE_DECODE, TYPE_DECODE,
@ -1655,7 +1664,7 @@ public:
class GeneratorItem : public Printable class GeneratorItem : public Printable
{ {
public: public:
GeneratorItem(Firebird::MemoryPool& pool, const MetaName& name) GeneratorItem(Firebird::MemoryPool& pool, const QualifiedName& name)
: id(0), name(pool, name), secName(pool) : id(0), name(pool, name), secName(pool)
{} {}
@ -1672,8 +1681,8 @@ public:
public: public:
SLONG id; SLONG id;
MetaName name; QualifiedName name;
MetaName secName; QualifiedName secName;
}; };
typedef Firebird::Array<StreamType> StreamMap; 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 // Return function and procedure names (in the user charset) and optionally its details for a
// given package. // 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>& functions,
SortedObjectsArray<Signature>& procedures, bool details) SortedObjectsArray<Signature>& procedures, bool details)
{ {
@ -64,7 +64,8 @@ namespace
FOR (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction) FOR (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction)
FUN IN RDB$FUNCTIONS 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); Signature function(FUN.RDB$FUNCTION_NAME);
function.defined = !FUN.RDB$FUNCTION_BLR.NULL || !FUN.RDB$ENTRYPOINT.NULL; function.defined = !FUN.RDB$FUNCTION_BLR.NULL || !FUN.RDB$ENTRYPOINT.NULL;
@ -77,21 +78,23 @@ namespace
FOR (REQUEST_HANDLE requestHandle2 TRANSACTION_HANDLE transaction) FOR (REQUEST_HANDLE requestHandle2 TRANSACTION_HANDLE transaction)
ARG IN RDB$FUNCTION_ARGUMENTS CROSS ARG IN RDB$FUNCTION_ARGUMENTS CROSS
FLD IN RDB$FIELDS 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 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 FLD.RDB$FIELD_NAME EQ ARG.RDB$FIELD_SOURCE
{ {
SignatureParameter parameter(*getDefaultMemoryPool()); SignatureParameter parameter(*getDefaultMemoryPool());
parameter.number = ARG.RDB$ARGUMENT_POSITION; parameter.number = ARG.RDB$ARGUMENT_POSITION;
parameter.name = ARG.RDB$ARGUMENT_NAME; 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; parameter.mechanism = ARG.RDB$ARGUMENT_MECHANISM;
if (!ARG.RDB$FIELD_NAME.NULL) 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) 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) if (!ARG.RDB$COLLATION_ID.NULL)
parameter.collationId = ARG.RDB$COLLATION_ID; parameter.collationId = ARG.RDB$COLLATION_ID;
if (!ARG.RDB$NULL_FLAG.NULL) if (!ARG.RDB$NULL_FLAG.NULL)
@ -132,7 +135,8 @@ namespace
FOR (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction) FOR (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction)
PRC IN RDB$PROCEDURES 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); Signature procedure(PRC.RDB$PROCEDURE_NAME);
procedure.defined = !PRC.RDB$PROCEDURE_BLR.NULL || !PRC.RDB$ENTRYPOINT.NULL; procedure.defined = !PRC.RDB$PROCEDURE_BLR.NULL || !PRC.RDB$ENTRYPOINT.NULL;
@ -142,21 +146,23 @@ namespace
FOR (REQUEST_HANDLE requestHandle2 TRANSACTION_HANDLE transaction) FOR (REQUEST_HANDLE requestHandle2 TRANSACTION_HANDLE transaction)
PRM IN RDB$PROCEDURE_PARAMETERS CROSS PRM IN RDB$PROCEDURE_PARAMETERS CROSS
FLD IN RDB$FIELDS 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 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 FLD.RDB$FIELD_NAME EQ PRM.RDB$FIELD_SOURCE
{ {
SignatureParameter parameter(*getDefaultMemoryPool()); SignatureParameter parameter(*getDefaultMemoryPool());
parameter.type = PRM.RDB$PARAMETER_TYPE; parameter.type = PRM.RDB$PARAMETER_TYPE;
parameter.number = PRM.RDB$PARAMETER_NUMBER; parameter.number = PRM.RDB$PARAMETER_NUMBER;
parameter.name = PRM.RDB$PARAMETER_NAME; 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; parameter.mechanism = PRM.RDB$PARAMETER_MECHANISM;
if (!PRM.RDB$FIELD_NAME.NULL) 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) 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) if (!PRM.RDB$COLLATION_ID.NULL)
parameter.collationId = PRM.RDB$COLLATION_ID; parameter.collationId = PRM.RDB$COLLATION_ID;
if (!PRM.RDB$NULL_FLAG.NULL) if (!PRM.RDB$NULL_FLAG.NULL)
@ -216,6 +222,14 @@ string CreateAlterPackageNode::internalPrint(NodePrinter& printer) const
DdlNode* CreateAlterPackageNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) 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) if (alter && !items)
return DdlNode::dsqlPass(dsqlScratch); return DdlNode::dsqlPass(dsqlScratch);
@ -235,18 +249,19 @@ DdlNode* CreateAlterPackageNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
CreateAlterFunctionNode* const fun = (*items)[i].function; CreateAlterFunctionNode* const fun = (*items)[i].function;
ddlNode = fun; ddlNode = fun;
if (functionNames.exist(fun->name)) if (functionNames.exist(fun->name.object))
{ {
status_exception::raise( status_exception::raise(
Arg::Gds(isc_no_meta_update) << Arg::Gds(isc_no_meta_update) <<
Arg::Gds(isc_dyn_duplicate_package_item) << 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->alter = true;
fun->package = name; fun->name.schema = name.schema;
fun->name.package = name.object;
break; break;
} }
@ -255,18 +270,19 @@ DdlNode* CreateAlterPackageNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
CreateAlterProcedureNode* const proc = (*items)[i].procedure; CreateAlterProcedureNode* const proc = (*items)[i].procedure;
ddlNode = proc; ddlNode = proc;
if (procedureNames.exist(proc->name)) if (procedureNames.exist(proc->name.object))
{ {
status_exception::raise( status_exception::raise(
Arg::Gds(isc_no_meta_update) << Arg::Gds(isc_no_meta_update) <<
Arg::Gds(isc_dyn_duplicate_package_item) << 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->alter = true;
proc->package = name; proc->name.schema = name.schema;
proc->name.package = name.object;
break; break;
} }
@ -280,6 +296,7 @@ DdlNode* CreateAlterPackageNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
FB_NEW_POOL(pool) DsqlCompilerScratch(pool, dsqlScratch->getAttachment(), FB_NEW_POOL(pool) DsqlCompilerScratch(pool, dsqlScratch->getAttachment(),
dsqlScratch->getTransaction(), itemStatement); dsqlScratch->getTransaction(), itemStatement);
itemScratch->ddlSchema = name.schema;
itemScratch->clientDialect = dsqlScratch->clientDialect; itemScratch->clientDialect = dsqlScratch->clientDialect;
itemScratch->flags |= DsqlCompilerScratch::FLAG_DDL; itemScratch->flags |= DsqlCompilerScratch::FLAG_DDL;
itemScratch->package = name; itemScratch->package = name;
@ -298,16 +315,13 @@ DdlNode* CreateAlterPackageNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
void CreateAlterPackageNode::checkPermission(thread_db* tdbb, jrd_tra* transaction) void CreateAlterPackageNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
{ {
dsc dscName;
dscName.makeText(name.length(), CS_METADATA, (UCHAR*) name.c_str());
if (alter) if (alter)
{ {
if (SCL_check_package(tdbb, &dscName, SCL_alter) || !create) if (SCL_check_package(tdbb, name, SCL_alter) || !create)
return; 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)) if (!executeAlterIndividualParameters(tdbb, dsqlScratch, transaction))
status_exception::raise( status_exception::raise(
Arg::Gds(isc_no_meta_update) << 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)) else if (!executeAlter(tdbb, dsqlScratch, transaction))
{ {
@ -342,14 +356,14 @@ void CreateAlterPackageNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlS
{ {
status_exception::raise( status_exception::raise(
Arg::Gds(isc_no_meta_update) << 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; dsc schemaDesc, nameDesc;
desc.makeText(name.length(), ttype_metadata, schemaDesc.makeText(name.schema.length(), ttype_metadata, (UCHAR*) const_cast<char*>(name.schema.c_str()));
(UCHAR*) const_cast<char*>(name.c_str())); // safe const_cast nameDesc.makeText(name.object.length(), ttype_metadata, (UCHAR*) const_cast<char*>(name.object.c_str()));
DFW_post_work(transaction, dfw_modify_package_header, &desc, 0); DFW_post_work(transaction, dfw_modify_package_header, &nameDesc, &schemaDesc, 0);
} }
else else
executeCreate(tdbb, dsqlScratch, transaction); 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)) if (createIfNotExistsOnly && !DYN_UTIL_check_unique_name_nothrow(tdbb, transaction, name, obj_package_header))
return; return;
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE, executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE, DDL_TRIGGER_CREATE_PACKAGE, name, {});
DDL_TRIGGER_CREATE_PACKAGE, name, NULL);
DYN_UTIL_check_unique_name(tdbb, transaction, name, obj_package_header); 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) STORE (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction)
PKG IN RDB$PACKAGES USING 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; 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.NULL = FALSE;
PKG.RDB$SYSTEM_FLAG = 0; PKG.RDB$SYSTEM_FLAG = 0;
@ -405,8 +421,7 @@ void CreateAlterPackageNode::executeCreate(thread_db* tdbb, DsqlCompilerScratch*
executeItems(tdbb, dsqlScratch, transaction); executeItems(tdbb, dsqlScratch, transaction);
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER, DDL_TRIGGER_CREATE_PACKAGE, executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER, DDL_TRIGGER_CREATE_PACKAGE, name, {});
name, NULL);
} }
@ -420,12 +435,12 @@ bool CreateAlterPackageNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch*
FOR (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction) FOR (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction)
PKG IN RDB$PACKAGES 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; modified = true;
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE, executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE, DDL_TRIGGER_ALTER_PACKAGE, name, {});
DDL_TRIGGER_ALTER_PACKAGE, name, NULL);
SortedObjectsArray<Signature> existingFuncs(pool); SortedObjectsArray<Signature> existingFuncs(pool);
SortedObjectsArray<Signature> existingProcs(pool); SortedObjectsArray<Signature> existingProcs(pool);
@ -436,8 +451,7 @@ bool CreateAlterPackageNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch*
{ {
if (!functionNames.exist(i->name)) if (!functionNames.exist(i->name))
{ {
DropFunctionNode dropNode(pool, i->name); DropFunctionNode dropNode(pool, QualifiedName(i->name, name.schema, name.object));
dropNode.package = name;
dropNode.dsqlPass(dsqlScratch); dropNode.dsqlPass(dsqlScratch);
dropNode.executeDdl(tdbb, dsqlScratch, transaction, true); dropNode.executeDdl(tdbb, dsqlScratch, transaction, true);
} }
@ -448,8 +462,7 @@ bool CreateAlterPackageNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch*
{ {
if (!procedureNames.exist(i->name)) if (!procedureNames.exist(i->name))
{ {
DropProcedureNode dropNode(pool, i->name); DropProcedureNode dropNode(pool, QualifiedName(i->name, name.schema, name.object));
dropNode.package = name;
dropNode.dsqlPass(dsqlScratch); dropNode.dsqlPass(dsqlScratch);
dropNode.executeDdl(tdbb, dsqlScratch, transaction, true); dropNode.executeDdl(tdbb, dsqlScratch, transaction, true);
} }
@ -474,10 +487,10 @@ bool CreateAlterPackageNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch*
owner = PKG.RDB$OWNER_NAME; owner = PKG.RDB$OWNER_NAME;
dsc desc; dsc schemaDesc, nameDesc;
desc.makeText(name.length(), ttype_metadata, schemaDesc.makeText(name.schema.length(), ttype_metadata, (UCHAR*) const_cast<char*>(name.schema.c_str()));
(UCHAR*) const_cast<char*>(name.c_str())); // safe const_cast nameDesc.makeText(name.object.length(), ttype_metadata, (UCHAR*) const_cast<char*>(name.object.c_str()));
DFW_post_work(transaction, dfw_drop_package_body, &desc, 0); DFW_post_work(transaction, dfw_drop_package_body, &nameDesc, &schemaDesc, 0);
} }
END_FOR END_FOR
@ -485,8 +498,7 @@ bool CreateAlterPackageNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch*
{ {
executeItems(tdbb, dsqlScratch, transaction); executeItems(tdbb, dsqlScratch, transaction);
executeDdlTrigger(tdbb, dsqlScratch, transaction, executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER, DDL_TRIGGER_ALTER_PACKAGE, name, {});
DTW_AFTER, DDL_TRIGGER_ALTER_PACKAGE, name, NULL);
} }
return modified; return modified;
@ -500,12 +512,12 @@ bool CreateAlterPackageNode::executeAlterIndividualParameters(thread_db* tdbb, D
FOR (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction) FOR (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction)
PKG IN RDB$PACKAGES 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; modified = true;
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE, executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE, DDL_TRIGGER_ALTER_PACKAGE, name, {});
DDL_TRIGGER_ALTER_PACKAGE, name, NULL);
MODIFY PKG MODIFY PKG
if (ssDefiner.has_value()) if (ssDefiner.has_value())
@ -523,10 +535,7 @@ bool CreateAlterPackageNode::executeAlterIndividualParameters(thread_db* tdbb, D
END_FOR END_FOR
if (modified) if (modified)
{ executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER, DDL_TRIGGER_ALTER_PACKAGE, name, {});
executeDdlTrigger(tdbb, dsqlScratch, transaction,
DTW_AFTER, DDL_TRIGGER_ALTER_PACKAGE, name, NULL);
}
return modified; return modified;
} }
@ -568,14 +577,11 @@ string DropPackageNode::internalPrint(NodePrinter& printer) const
void DropPackageNode::checkPermission(thread_db* tdbb, jrd_tra* transaction) void DropPackageNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
{ {
dsc dscName; SCL_check_package(tdbb, name, SCL_drop);
dscName.makeText(name.length(), CS_METADATA, (UCHAR*) name.c_str());
SCL_check_package(tdbb, &dscName, SCL_drop);
} }
void DropPackageNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, void DropPackageNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction)
jrd_tra* transaction)
{ {
MemoryPool& pool = dsqlScratch->getPool(); MemoryPool& pool = dsqlScratch->getPool();
@ -587,22 +593,22 @@ void DropPackageNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
FOR (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction) FOR (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction)
PKG IN RDB$PACKAGES 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; found = true;
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE, executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE, DDL_TRIGGER_DROP_PACKAGE, name, {});
DDL_TRIGGER_DROP_PACKAGE, name, NULL);
ERASE PKG; ERASE PKG;
if (!PKG.RDB$SECURITY_CLASS.NULL) if (!PKG.RDB$SECURITY_CLASS.NULL)
deleteSecurityClass(tdbb, transaction, PKG.RDB$SECURITY_CLASS); deleteSecurityClass(tdbb, transaction, PKG.RDB$SECURITY_CLASS);
dsc desc; dsc schemaDesc, nameDesc;
desc.makeText(name.length(), ttype_metadata, schemaDesc.makeText(name.schema.length(), ttype_metadata, (UCHAR*) const_cast<char*>(name.schema.c_str()));
(UCHAR*) const_cast<char*>(name.c_str())); // safe const_cast nameDesc.makeText(name.object.length(), ttype_metadata, (UCHAR*) const_cast<char*>(name.object.c_str()));
DFW_post_work(transaction, dfw_drop_package_header, &desc, 0); DFW_post_work(transaction, dfw_drop_package_header, &nameDesc, &schemaDesc, 0);
} }
END_FOR END_FOR
@ -610,7 +616,7 @@ void DropPackageNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
{ {
status_exception::raise( status_exception::raise(
Arg::Gds(isc_no_meta_update) << 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); SortedObjectsArray<Signature> existingFuncs(pool);
@ -620,8 +626,7 @@ void DropPackageNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
for (SortedObjectsArray<Signature>::iterator i = existingFuncs.begin(); for (SortedObjectsArray<Signature>::iterator i = existingFuncs.begin();
i != existingFuncs.end(); ++i) i != existingFuncs.end(); ++i)
{ {
DropFunctionNode dropNode(pool, i->name); DropFunctionNode dropNode(pool, QualifiedName(i->name, name.schema, name.object));
dropNode.package = name;
dropNode.dsqlPass(dsqlScratch); dropNode.dsqlPass(dsqlScratch);
dropNode.executeDdl(tdbb, dsqlScratch, transaction, true); 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(); for (SortedObjectsArray<Signature>::iterator i = existingProcs.begin();
i != existingProcs.end(); ++i) i != existingProcs.end(); ++i)
{ {
DropProcedureNode dropNode(pool, i->name); DropProcedureNode dropNode(pool, QualifiedName(i->name, name.schema, name.object));
dropNode.package = name;
dropNode.dsqlPass(dsqlScratch); dropNode.dsqlPass(dsqlScratch);
dropNode.executeDdl(tdbb, dsqlScratch, transaction, true); 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) FOR (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction)
PRIV IN RDB$USER_PRIVILEGES PRIV IN RDB$USER_PRIVILEGES
WITH ((PRIV.RDB$RELATION_NAME EQ name.c_str() AND WITH ((PRIV.RDB$RELATION_SCHEMA_NAME EQ name.schema.c_str() AND
PRIV.RDB$OBJECT_TYPE = obj_package_header) OR PRIV.RDB$RELATION_NAME EQ name.object.c_str() AND
(PRIV.RDB$USER EQ name.c_str() AND PRIV.RDB$USER_TYPE = obj_package_header)) 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 PRIV.RDB$GRANTOR NOT MISSING
{ {
ERASE PRIV; ERASE PRIV;
@ -649,10 +656,7 @@ void DropPackageNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
END_FOR END_FOR
if (found) if (found)
{ executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER, DDL_TRIGGER_DROP_PACKAGE, name, {});
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER, DDL_TRIGGER_DROP_PACKAGE,
name, NULL);
}
savePoint.release(); // everything is ok savePoint.release(); // everything is ok
} }
@ -676,6 +680,10 @@ string CreatePackageBodyNode::internalPrint(NodePrinter& printer) const
DdlNode* CreatePackageBodyNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) 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(); MemoryPool& pool = dsqlScratch->getPool();
source.ltrim("\n\r\t "); source.ltrim("\n\r\t ");
@ -701,17 +709,18 @@ DdlNode* CreatePackageBodyNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
CreateAlterFunctionNode* const fun = (*arrays[i])[j].function; CreateAlterFunctionNode* const fun = (*arrays[i])[j].function;
ddlNode = fun; ddlNode = fun;
if (functionNames[i].exist(fun->name)) if (functionNames[i].exist(fun->name.object))
{ {
status_exception::raise( status_exception::raise(
Arg::Gds(isc_no_meta_update) << Arg::Gds(isc_no_meta_update) <<
Arg::Gds(isc_dyn_duplicate_package_item) << 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; fun->create = true;
if (arrays[i] == items) if (arrays[i] == items)
@ -725,17 +734,18 @@ DdlNode* CreatePackageBodyNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
CreateAlterProcedureNode* const proc = (*arrays[i])[j].procedure; CreateAlterProcedureNode* const proc = (*arrays[i])[j].procedure;
ddlNode = proc; ddlNode = proc;
if (procedureNames[i].exist(proc->name)) if (procedureNames[i].exist(proc->name.object))
{ {
status_exception::raise( status_exception::raise(
Arg::Gds(isc_no_meta_update) << Arg::Gds(isc_no_meta_update) <<
Arg::Gds(isc_dyn_duplicate_package_item) << 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; proc->create = true;
if (arrays[i] == items) if (arrays[i] == items)
@ -754,6 +764,7 @@ DdlNode* CreatePackageBodyNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
FB_NEW_POOL(pool) DsqlCompilerScratch(pool, dsqlScratch->getAttachment(), FB_NEW_POOL(pool) DsqlCompilerScratch(pool, dsqlScratch->getAttachment(),
dsqlScratch->getTransaction(), itemStatement); dsqlScratch->getTransaction(), itemStatement);
itemScratch->ddlSchema = name.schema;
itemScratch->clientDialect = dsqlScratch->clientDialect; itemScratch->clientDialect = dsqlScratch->clientDialect;
itemScratch->flags |= DsqlCompilerScratch::FLAG_DDL; itemScratch->flags |= DsqlCompilerScratch::FLAG_DDL;
itemScratch->package = name; itemScratch->package = name;
@ -773,12 +784,11 @@ DdlNode* CreatePackageBodyNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
void CreatePackageBodyNode::checkPermission(thread_db* tdbb, jrd_tra* transaction) 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, void CreatePackageBodyNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction)
jrd_tra* transaction)
{ {
MemoryPool& pool = dsqlScratch->getPool(); MemoryPool& pool = dsqlScratch->getPool();
Attachment* attachment = transaction->getAttachment(); Attachment* attachment = transaction->getAttachment();
@ -791,7 +801,8 @@ void CreatePackageBodyNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlSc
FOR (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction) FOR (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction)
PKG IN RDB$PACKAGES 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) 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( status_exception::raise(
Arg::Gds(isc_no_meta_update) << 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, executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE, DDL_TRIGGER_CREATE_PACKAGE_BODY, name, {});
DDL_TRIGGER_CREATE_PACKAGE_BODY, name, NULL);
MODIFY PKG MODIFY PKG
PKG.RDB$VALID_BODY_FLAG.NULL = FALSE; PKG.RDB$VALID_BODY_FLAG.NULL = FALSE;
@ -824,7 +834,7 @@ void CreatePackageBodyNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlSc
{ {
status_exception::raise( status_exception::raise(
Arg::Gds(isc_no_meta_update) << 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); SortedObjectsArray<Signature> headerFuncs(pool);
@ -861,18 +871,18 @@ void CreatePackageBodyNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlSc
CreateAlterFunctionNode* func = elem.function; CreateAlterFunctionNode* func = elem.function;
if (arrays[i] == items) if (arrays[i] == items)
func->privateScope = !headerFuncs.exist(Signature(func->name)); func->privateScope = !headerFuncs.exist(Signature(func->name.object));
else if (existingFuncs.exist(Signature(func->name))) else if (existingFuncs.exist(Signature(func->name.object)))
{ {
status_exception::raise( status_exception::raise(
Arg::Gds(isc_no_meta_update) << Arg::Gds(isc_no_meta_update) <<
Arg::Gds(isc_dyn_duplicate_package_item) << Arg::Gds(isc_dyn_duplicate_package_item) <<
Arg::Str("FUNCTION") << Arg::Str(func->name)); Arg::Str("FUNCTION") << func->name.toQuotedString());
} }
func->packageOwner = owner; func->packageOwner = owner;
func->preserveDefaults = 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); func->executeDdl(tdbb, elem.dsqlScratch, transaction, true);
break; break;
} }
@ -882,18 +892,18 @@ void CreatePackageBodyNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlSc
CreateAlterProcedureNode* proc = elem.procedure; CreateAlterProcedureNode* proc = elem.procedure;
if (arrays[i] == items) if (arrays[i] == items)
proc->privateScope = !headerProcs.exist(Signature(proc->name)); proc->privateScope = !headerProcs.exist(Signature(proc->name.object));
else if (existingProcs.exist(Signature(proc->name))) else if (existingProcs.exist(Signature(proc->name.object)))
{ {
status_exception::raise( status_exception::raise(
Arg::Gds(isc_no_meta_update) << Arg::Gds(isc_no_meta_update) <<
Arg::Gds(isc_dyn_duplicate_package_item) << Arg::Gds(isc_dyn_duplicate_package_item) <<
Arg::Str("PROCEDURE") << Arg::Str(proc->name)); Arg::Str("PROCEDURE") << proc->name.toQuotedString());
} }
proc->packageOwner = owner; proc->packageOwner = owner;
proc->preserveDefaults = 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); proc->executeDdl(tdbb, elem.dsqlScratch, transaction, true);
break; break;
} }
@ -914,12 +924,12 @@ void CreatePackageBodyNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlSc
if (!found || !newFuncs[pos].defined) if (!found || !newFuncs[pos].defined)
{ {
status_exception::raise( 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) else if (newFuncs[pos] != *i)
{ {
status_exception::raise( 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) if (!found || !newProcs[pos].defined)
{ {
status_exception::raise( 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) else if (newProcs[pos] != *i)
{ {
status_exception::raise( 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, executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER, DDL_TRIGGER_CREATE_PACKAGE_BODY, name, {});
DDL_TRIGGER_CREATE_PACKAGE_BODY, name, NULL);
savePoint.release(); // everything is ok savePoint.release(); // everything is ok
} }
@ -964,9 +973,7 @@ string DropPackageBodyNode::internalPrint(NodePrinter& printer) const
void DropPackageBodyNode::checkPermission(thread_db* tdbb, jrd_tra* transaction) void DropPackageBodyNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
{ {
dsc dscName; SCL_check_package(tdbb, name, SCL_drop);
dscName.makeText(name.length(), CS_METADATA, (UCHAR*) name.c_str());
SCL_check_package(tdbb, &dscName, SCL_drop);
} }
@ -983,21 +990,21 @@ void DropPackageBodyNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScra
FOR (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction) FOR (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction)
PKG IN RDB$PACKAGES 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; found = true;
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE, executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE, DDL_TRIGGER_DROP_PACKAGE_BODY, name, {});
DDL_TRIGGER_DROP_PACKAGE_BODY, name, NULL);
MODIFY PKG MODIFY PKG
PKG.RDB$VALID_BODY_FLAG.NULL = TRUE; PKG.RDB$VALID_BODY_FLAG.NULL = TRUE;
PKG.RDB$PACKAGE_BODY_SOURCE.NULL = TRUE; PKG.RDB$PACKAGE_BODY_SOURCE.NULL = TRUE;
dsc desc; dsc schemaDesc, nameDesc;
desc.makeText(name.length(), ttype_metadata, schemaDesc.makeText(name.schema.length(), ttype_metadata, (UCHAR*) const_cast<char*>(name.schema.c_str()));
(UCHAR*) const_cast<char*>(name.c_str())); // safe const_cast nameDesc.makeText(name.object.length(), ttype_metadata, (UCHAR*) const_cast<char*>(name.object.c_str()));
DFW_post_work(transaction, dfw_drop_package_body, &desc, 0); DFW_post_work(transaction, dfw_drop_package_body, &nameDesc, &schemaDesc, 0);
END_MODIFY END_MODIFY
} }
END_FOR END_FOR
@ -1012,19 +1019,19 @@ void DropPackageBodyNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScra
status_exception::raise( status_exception::raise(
Arg::Gds(isc_no_meta_update) << 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); requestHandle.reset(tdbb, drq_m_pkg_fun, DYN_REQUESTS);
FOR (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction) FOR (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction)
FUN IN RDB$FUNCTIONS 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) if (!FUN.RDB$PRIVATE_FLAG.NULL && FUN.RDB$PRIVATE_FLAG != 0)
{ {
DropFunctionNode dropNode(pool, FUN.RDB$FUNCTION_NAME); DropFunctionNode dropNode(pool, QualifiedName(FUN.RDB$FUNCTION_NAME, name.schema, name.object));
dropNode.package = name;
dropNode.dsqlPass(dsqlScratch); dropNode.dsqlPass(dsqlScratch);
dropNode.executeDdl(tdbb, dsqlScratch, transaction, true); 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) FOR (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction)
PRC IN RDB$PROCEDURES 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) if (!PRC.RDB$PRIVATE_FLAG.NULL && PRC.RDB$PRIVATE_FLAG != 0)
{ {
DropProcedureNode dropNode(pool, PRC.RDB$PROCEDURE_NAME); DropProcedureNode dropNode(pool, QualifiedName(PRC.RDB$PROCEDURE_NAME, name.schema, name.object));
dropNode.package = name;
dropNode.dsqlPass(dsqlScratch); dropNode.dsqlPass(dsqlScratch);
dropNode.executeDdl(tdbb, dsqlScratch, transaction, true); dropNode.executeDdl(tdbb, dsqlScratch, transaction, true);
} }
@ -1068,8 +1075,7 @@ void DropPackageBodyNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScra
} }
END_FOR END_FOR
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER, executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER, DDL_TRIGGER_DROP_PACKAGE_BODY, name, {});
DDL_TRIGGER_DROP_PACKAGE_BODY, name, NULL);
savePoint.release(); // everything is ok savePoint.release(); // everything is ok
} }

View File

@ -68,7 +68,7 @@ public:
}; };
public: public:
CreateAlterPackageNode(MemoryPool& pool, const MetaName& aName) CreateAlterPackageNode(MemoryPool& pool, const QualifiedName& aName)
: DdlNode(pool), : DdlNode(pool),
name(pool, aName), name(pool, aName),
create(true), create(true),
@ -94,7 +94,7 @@ protected:
Firebird::Arg::Gds(createAlterCode(create, alter, Firebird::Arg::Gds(createAlterCode(create, alter,
isc_dsql_create_pack_failed, isc_dsql_alter_pack_failed, isc_dsql_create_pack_failed, isc_dsql_alter_pack_failed,
isc_dsql_create_alter_pack_failed)) << isc_dsql_create_alter_pack_failed)) <<
name; name.toQuotedString();
} }
private: private:
@ -104,7 +104,7 @@ private:
void executeItems(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); void executeItems(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction);
public: public:
MetaName name; QualifiedName name;
bool create; bool create;
bool alter; bool alter;
bool createIfNotExistsOnly = false; bool createIfNotExistsOnly = false;
@ -122,7 +122,7 @@ private:
class DropPackageNode : public DdlNode class DropPackageNode : public DdlNode
{ {
public: public:
DropPackageNode(MemoryPool& pool, const MetaName& aName) DropPackageNode(MemoryPool& pool, const QualifiedName& aName)
: DdlNode(pool), : DdlNode(pool),
name(pool, aName), name(pool, aName),
silent(false) silent(false)
@ -134,15 +134,29 @@ public:
virtual void checkPermission(thread_db* tdbb, jrd_tra* transaction); virtual void checkPermission(thread_db* tdbb, jrd_tra* transaction);
virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, 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: protected:
virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) 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: public:
MetaName name; QualifiedName name;
bool silent; bool silent;
bool recreate = false;
}; };
@ -153,7 +167,7 @@ typedef RecreateNode<CreateAlterPackageNode, DropPackageNode, isc_dsql_recreate_
class CreatePackageBodyNode : public DdlNode class CreatePackageBodyNode : public DdlNode
{ {
public: public:
CreatePackageBodyNode(MemoryPool& pool, const MetaName& aName) CreatePackageBodyNode(MemoryPool& pool, const QualifiedName& aName)
: DdlNode(pool), : DdlNode(pool),
name(pool, aName), name(pool, aName),
source(pool), source(pool),
@ -172,11 +186,11 @@ public:
protected: protected:
virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) 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: public:
MetaName name; QualifiedName name;
Firebird::string source; Firebird::string source;
Firebird::Array<CreateAlterPackageNode::Item>* declaredItems; Firebird::Array<CreateAlterPackageNode::Item>* declaredItems;
Firebird::Array<CreateAlterPackageNode::Item>* items; Firebird::Array<CreateAlterPackageNode::Item>* items;
@ -190,7 +204,7 @@ private:
class DropPackageBodyNode : public DdlNode class DropPackageBodyNode : public DdlNode
{ {
public: public:
DropPackageBodyNode(MemoryPool& pool, const MetaName& aName) DropPackageBodyNode(MemoryPool& pool, const QualifiedName& aName)
: DdlNode(pool), : DdlNode(pool),
name(pool, aName), name(pool, aName),
silent(false) silent(false)
@ -202,15 +216,25 @@ public:
virtual void checkPermission(thread_db* tdbb, jrd_tra* transaction); virtual void checkPermission(thread_db* tdbb, jrd_tra* transaction);
virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, 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: protected:
virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) 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: public:
MetaName name; QualifiedName name;
bool silent; // Unused. Just to please RecreateNode template. 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) if (tok_class & CHR_INTRODUCER)
{ {
// The Introducer (_) is skipped, all other idents are copied if (lex.ptr >= lex.end)
// to become the name of the character set. return -1;
char* p = string;
for (; lex.ptr < lex.end && (classes(*lex.ptr) & CHR_IDENT); lex.ptr++)
{
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); return (UCHAR) c;
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;
} }
// parse a quoted string, being sure to look for double quotes // parse a quoted string, being sure to look for double quotes
@ -711,15 +696,14 @@ int Parser::yylexAux()
if (introducerCharSetName) if (introducerCharSetName)
{ {
const auto symbol = METD_get_charset(scratch->getTransaction(), const auto symbol = METD_get_charset(scratch->getTransaction(), *introducerCharSetName);
introducerCharSetName->length(), introducerCharSetName->c_str());
if (!symbol) if (!symbol)
{ {
// character set name is not defined // character set name is not defined
ERRD_post( ERRD_post(
Arg::Gds(isc_sqlerr) << Arg::Num(-504) << 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); currentCharSet = INTL_charset_lookup(tdbb, symbol->intlsym_ttype);

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

@ -68,7 +68,7 @@ const USHORT blr_dtypes[] = {
}; };
bool DDL_ids(const Jrd::DsqlCompilerScratch*); 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); bool = false);
#endif // DSQL_DDL_PROTO_H #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_charsets_by_id(p),
dbb_cursors(p), dbb_cursors(p),
dbb_pool(p), dbb_pool(p),
dbb_schemas_dfl_charset(p),
dbb_dfl_charset(p) dbb_dfl_charset(p)
{ {
dbb_attachment = attachment; 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. // Execute a dynamic SQL statement.
void DSQL_execute(thread_db* tdbb, void DSQL_execute(thread_db* tdbb,
jrd_tra** tra_handle, jrd_tra** tra_handle,
@ -711,15 +719,15 @@ string IntlString::toUtf8(jrd_tra* transaction) const
{ {
CHARSET_ID id = CS_dynamic; 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) if (!resolved)
{ {
// character set name is not defined // character set name is not defined
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-504) << 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; 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;) for (const UCHAR* describe = items; describe < end_describe;)
{ {
USHORT length; USHORT length;
string str;
MetaName name; MetaName name;
const UCHAR* buffer = buf; const UCHAR* buffer = buf;
UCHAR item = *describe++; UCHAR item = *describe++;
@ -1235,10 +1244,21 @@ static UCHAR* var_info(const dsql_msg* message,
length = 0; length = 0;
break; break;
case isc_info_sql_relation: case isc_info_sql_relation_schema:
if (param->par_rel_name.hasData()) 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(); length = name.length();
buffer = reinterpret_cast<const UCHAR*>(name.c_str()); 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: case isc_info_sql_relation_alias:
if (param->par_rel_alias.hasData()) if (param->par_rel_alias.hasData())
{ {
name = attachment->nameToUserCharSet(tdbb, param->par_rel_alias); str = attachment->stringToUserCharSet(tdbb, param->par_rel_alias);
length = name.length(); length = str.length();
buffer = reinterpret_cast<const UCHAR*>(name.c_str()); buffer = reinterpret_cast<const UCHAR*>(str.c_str());
} }
else else
length = 0; length = 0;

View File

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

View File

@ -342,7 +342,7 @@ ValueExprNode* MAKE_constant(const char* str, dsql_constant_type numeric_flag, S
@param character_set @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(); 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); message->msg_parameters.insert(0, parameter);
parameter->par_parameter = message->msg_parameter++; parameter->par_parameter = message->msg_parameter++;
parameter->par_rel_name = NULL; parameter->par_rel_name.clear();
parameter->par_owner_name = NULL; parameter->par_owner_name = NULL;
parameter->par_rel_alias = NULL; parameter->par_rel_alias.clear();
if (node) if (node)
MAKE_parameter_names(parameter, node); MAKE_parameter_names(parameter, node);

View File

@ -82,7 +82,7 @@ namespace Jrd {
Jrd::LiteralNode* MAKE_const_slong(SLONG); Jrd::LiteralNode* MAKE_const_slong(SLONG);
Jrd::LiteralNode* MAKE_const_sint64(SINT64 value, SCHAR scale); Jrd::LiteralNode* MAKE_const_sint64(SINT64 value, SCHAR scale);
Jrd::ValueExprNode* MAKE_constant(const char*, Jrd::dsql_constant_type, SSHORT = 0); 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(Jrd::dsql_ctx*, Jrd::dsql_fld*, Jrd::ValueListNode*);
Jrd::FieldNode* MAKE_field_name(const char*); Jrd::FieldNode* MAKE_field_name(const char*);
Jrd::dsql_par* MAKE_parameter(Jrd::dsql_msg*, bool, bool, USHORT, const Jrd::ValueExprNode*); 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; bool rc = false;
AutoCacheRequest handle(tdbb, irq_system_relation, IRQ_REQUESTS); AutoCacheRequest handle(tdbb, irq_system_relation, IRQ_REQUESTS);
FOR(REQUEST_HANDLE handle TRANSACTION_HANDLE transaction) FOR(REQUEST_HANDLE handle TRANSACTION_HANDLE transaction)
R IN RDB$RELATIONS WITH R IN RDB$RELATIONS
R.RDB$RELATION_NAME EQ relName AND WITH R.RDB$SCHEMA_NAME EQ relName.schema.c_str() AND
R.RDB$SYSTEM_FLAG EQ 1 R.RDB$RELATION_NAME EQ relName.object.c_str() AND
R.RDB$SYSTEM_FLAG EQ 1
{ {
rc = true; rc = true;
} }
@ -93,15 +94,16 @@ namespace
return rc; 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; bool rc = false;
AutoCacheRequest handle(tdbb, irq_system_domain, IRQ_REQUESTS); AutoCacheRequest handle(tdbb, irq_system_domain, IRQ_REQUESTS);
FOR(REQUEST_HANDLE handle TRANSACTION_HANDLE transaction) FOR(REQUEST_HANDLE handle TRANSACTION_HANDLE transaction)
R IN RDB$FIELDS WITH R IN RDB$FIELDS
R.RDB$FIELD_NAME EQ fldName AND WITH R.RDB$SCHEMA_NAME EQ fldName.schema.c_str() AND
R.RDB$SYSTEM_FLAG EQ 1 R.RDB$FIELD_NAME EQ fldName.object.c_str() AND
R.RDB$SYSTEM_FLAG EQ 1
{ {
rc = true; 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)) 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; function->udf_flags |= UDF_dropped;
dbb->dbb_functions.remove(name); 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)) 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; procedure->prc_flags |= PRC_dropped;
dbb->dbb_procedures.remove(name); 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) FOR(REQUEST_HANDLE handle TRANSACTION_HANDLE transaction)
X IN RDB$COLLATIONS X IN RDB$COLLATIONS
CROSS Y IN RDB$CHARACTER_SETS OVER RDB$CHARACTER_SET_ID 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; X.RDB$CHARACTER_SET_ID EQ charset_id;
{ {
symbol = FB_NEW_POOL(dbb->dbb_pool) dsql_intlsym(dbb->dbb_pool); 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); validateTransaction(transaction);
dsql_dbb* dbb = transaction->getDsqlAttachment(); dsql_dbb* dbb = transaction->getDsqlAttachment();
MetaName metaName(name, length);
// Start by seeing if symbol is already defined // Start by seeing if symbol is already defined
dsql_intlsym* symbol; 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; symbol->intlsym_flags |= INTLSYM_dropped;
else else
return symbol; 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); AutoCacheRequest handle(tdbb, irq_charset, IRQ_REQUESTS);
FOR(REQUEST_HANDLE handle TRANSACTION_HANDLE transaction) FOR(REQUEST_HANDLE handle TRANSACTION_HANDLE transaction)
X IN RDB$COLLATIONS CS IN RDB$CHARACTER_SETS
CROSS Y IN RDB$CHARACTER_SETS OVER RDB$CHARACTER_SET_ID CROSS COLL IN RDB$COLLATIONS OVER RDB$CHARACTER_SET_ID
CROSS Z IN RDB$TYPES CROSS T IN RDB$TYPES
WITH Z.RDB$TYPE EQ Y.RDB$CHARACTER_SET_ID WITH CS.RDB$SCHEMA_NAME EQ name.schema.c_str() AND
AND Z.RDB$TYPE_NAME EQ name T.RDB$TYPE_NAME EQ name.object.c_str() AND
AND Z.RDB$FIELD_NAME EQ "RDB$CHARACTER_SET_NAME" COLL.RDB$SCHEMA_NAME EQ CS.RDB$DEFAULT_COLLATE_SCHEMA_NAME AND
AND Y.RDB$DEFAULT_COLLATE_NAME EQ X.RDB$COLLATION_NAME; 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 = 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_flags = 0;
symbol->intlsym_charset_id = X.RDB$CHARACTER_SET_ID; symbol->intlsym_charset_id = COLL.RDB$CHARACTER_SET_ID;
symbol->intlsym_collate_id = X.RDB$COLLATION_ID; symbol->intlsym_collate_id = COLL.RDB$COLLATION_ID;
symbol->intlsym_ttype = symbol->intlsym_ttype =
INTL_CS_COLL_TO_TTYPE(symbol->intlsym_charset_id, symbol->intlsym_collate_id); INTL_CS_COLL_TO_TTYPE(symbol->intlsym_charset_id, symbol->intlsym_collate_id);
symbol->intlsym_bytes_per_char = 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 END_FOR
if (!symbol) if (!symbol)
return NULL; 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); 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; return symbol;
} }
@ -431,8 +435,8 @@ USHORT METD_get_charset_bpc(jrd_tra* transaction, SSHORT charset_id)
dsql_intlsym* symbol = NULL; dsql_intlsym* symbol = NULL;
if (!dbb->dbb_charsets_by_id.get(charset_id, symbol)) if (!dbb->dbb_charsets_by_id.get(charset_id, symbol))
{ {
const MetaName cs_name = METD_get_charset_name(transaction, charset_id); const auto cs_name = METD_get_charset_name(transaction, charset_id);
symbol = METD_get_charset(transaction, cs_name.length(), cs_name.c_str()); symbol = METD_get_charset(transaction, cs_name);
} }
fb_assert(symbol); 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(); dsql_dbb* dbb = transaction->getDsqlAttachment();
if (charset_id == CS_dynamic) if (charset_id == CS_dynamic)
charset_id = tdbb->getCharSet(); charset_id = tdbb->getCharSet();
dsql_intlsym* sym = NULL; dsql_intlsym* sym = NULL;
if (dbb->dbb_charsets_by_id.get(charset_id, sym)) if (dbb->dbb_charsets_by_id.get(charset_id, sym))
return sym->intlsym_name; return sym->intlsym_name;
MetaName name; QualifiedName name;
AutoCacheRequest handle(tdbb, irq_cs_name, IRQ_REQUESTS); 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 Y IN RDB$CHARACTER_SETS
WITH Y.RDB$CHARACTER_SET_ID EQ charset_id 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 END_FOR
// put new charset into hash table if needed // put new charset into hash table if needed
METD_get_charset(transaction, name.length(), name.c_str()); METD_get_charset(transaction, name);
return 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(); thread_db* tdbb = JRD_get_thread_data();
validateTransaction(transaction); validateTransaction(transaction);
dsql_dbb* dbb = transaction->getDsqlAttachment(); dsql_dbb* dbb = transaction->getDsqlAttachment();
if (dbb->dbb_no_charset) 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; return dbb->dbb_dfl_charset;
// Now see if it is in the database // 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 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 dbb->dbb_dfl_charset = QualifiedName(DBB.RDB$CHARACTER_SET_NAME, DBB.RDB$CHARACTER_SET_SCHEMA_NAME);
fb_utils::exact_name(DBB.RDB$CHARACTER_SET_NAME);
dbb->dbb_dfl_charset = DBB.RDB$CHARACTER_SET_NAME;
} }
END_FOR END_FOR
if (dbb->dbb_dfl_charset.isEmpty()) if (dbb->dbb_dfl_charset.object.isEmpty())
{
fb_assert(false);
dbb->dbb_no_charset = true; dbb->dbb_no_charset = true;
}
return dbb->dbb_dfl_charset; 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); AutoCacheRequest handle(tdbb, irq_domain, IRQ_REQUESTS);
FOR(REQUEST_HANDLE handle TRANSACTION_HANDLE transaction) 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; found = true;
field->length = FLX.RDB$FIELD_LENGTH; 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, dsql_udf* METD_get_function(jrd_tra* transaction, DsqlCompilerScratch* dsqlScratch, const QualifiedName& name)
const QualifiedName& name)
{ {
/************************************** /**************************************
* *
@ -611,24 +641,13 @@ dsql_udf* METD_get_function(jrd_tra* transaction, DsqlCompilerScratch* dsqlScrat
validateTransaction(transaction); validateTransaction(transaction);
dsql_dbb* dbb = transaction->getDsqlAttachment(); 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 // Start by seeing if symbol is already defined
dsql_udf* userFunc = NULL; 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) if (MET_dsql_cache_use(tdbb, SYM_udf, name))
{
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))
userFunc->udf_flags |= UDF_dropped; userFunc->udf_flags |= UDF_dropped;
} }
@ -642,43 +661,34 @@ dsql_udf* METD_get_function(jrd_tra* transaction, DsqlCompilerScratch* dsqlScrat
USHORT return_arg = 0; 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) return_arg = X.RDB$RETURN_ARGUMENT;
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;
}
} }
END_FOR
if (!userFunc)
return nullptr;
SSHORT defaults = 0; SSHORT defaults = 0;
AutoCacheRequest handle2(tdbb, irq_func_return, IRQ_REQUESTS); AutoCacheRequest handle2(tdbb, irq_func_return, IRQ_REQUESTS);
FOR(REQUEST_HANDLE handle2 TRANSACTION_HANDLE transaction) FOR(REQUEST_HANDLE handle2 TRANSACTION_HANDLE transaction)
X IN RDB$FUNCTION_ARGUMENTS WITH X IN RDB$FUNCTION_ARGUMENTS
X.RDB$FUNCTION_NAME EQ metaName.identifier.c_str() AND WITH X.RDB$SCHEMA_NAME EQ name.schema.c_str() AND
X.RDB$PACKAGE_NAME EQUIV NULLIF(metaName.package.c_str(), '') 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 SORTED BY X.RDB$ARGUMENT_POSITION
{ {
if (!X.RDB$FIELD_SOURCE.NULL) 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) FOR(REQUEST_HANDLE handle3 TRANSACTION_HANDLE transaction)
F IN RDB$FIELDS WITH 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 F.RDB$FIELD_NAME EQ X.RDB$FIELD_SOURCE
{ {
if (X.RDB$ARGUMENT_POSITION == return_arg) 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]) !X.RDB$RELATION_NAME.NULL && X.RDB$RELATION_NAME[0])
{ {
// type of column used in declaration // 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; userFunc->udf_flags |= UDF_sys_based;
}
} }
else if (!X.RDB$FIELD_SOURCE.NULL && X.RDB$FIELD_SOURCE[0]) else if (!X.RDB$FIELD_SOURCE.NULL && X.RDB$FIELD_SOURCE[0])
{ {
// domain used in declaration // 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; userFunc->udf_flags |= UDF_sys_based;
}
} }
} }
else else
@ -896,19 +913,13 @@ dsql_udf* METD_get_function(jrd_tra* transaction, DsqlCompilerScratch* dsqlScrat
dbb->dbb_functions.put(userFunc->udf_name, userFunc); dbb->dbb_functions.put(userFunc->udf_name, userFunc);
if (userFunc->udf_private && metaName.package != dsqlScratch->package) MET_dsql_cache_use(tdbb, SYM_udf, userFunc->udf_name);
{
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);
return userFunc; 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) 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); AutoCacheRequest handle(tdbb, irq_primary_key, IRQ_REQUESTS);
FOR(REQUEST_HANDLE handle TRANSACTION_HANDLE transaction) FOR(REQUEST_HANDLE handle TRANSACTION_HANDLE transaction)
X IN RDB$INDICES CROSS X IN RDB$INDICES
Y IN RDB$INDEX_SEGMENTS CROSS Y IN RDB$INDEX_SEGMENTS OVER RDB$SCHEMA_NAME, RDB$INDEX_NAME
OVER RDB$INDEX_NAME CROSS CROSS Z IN RDB$RELATION_CONSTRAINTS OVER RDB$SCHEMA_NAME, RDB$INDEX_NAME
Z IN RDB$RELATION_CONSTRAINTS WITH Z.RDB$SCHEMA_NAME EQ relationName.schema.c_str() AND
OVER RDB$INDEX_NAME Z.RDB$RELATION_NAME EQ relationName.object.c_str() AND
WITH Z.RDB$RELATION_NAME EQ relationName.c_str() Z.RDB$CONSTRAINT_TYPE EQ "PRIMARY KEY"
AND Z.RDB$CONSTRAINT_TYPE EQ "PRIMARY KEY"
SORTED BY Y.RDB$FIELD_POSITION SORTED BY Y.RDB$FIELD_POSITION
{ {
FieldNode* fieldNode = FB_NEW_POOL(pool) FieldNode(pool); 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, dsql_prc* METD_get_procedure(jrd_tra* transaction, DsqlCompilerScratch* dsqlScratch, const QualifiedName& name)
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. // I hope for a solution, involving savepoint logic.
QualifiedName metaName(name); QualifiedName qualifiedName(name);
bool maybeUnqualified = dsqlScratch->package.hasData() && metaName.package.isEmpty();
if (maybeUnqualified)
metaName.package = dsqlScratch->package;
// Start by seeing if symbol is already defined // Start by seeing if symbol is already defined
dsql_prc* procedure = NULL; 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) if (MET_dsql_cache_use(tdbb, SYM_procedure, qualifiedName))
{
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))
procedure->prc_flags |= PRC_dropped; 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 // 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); procedure = FB_NEW_POOL(dbb->dbb_pool) dsql_prc(dbb->dbb_pool);
procedure->prc_id = X.RDB$PROCEDURE_ID;
FOR(REQUEST_HANDLE handle1 TRANSACTION_HANDLE transaction) procedure->prc_name = qualifiedName;
X IN RDB$PROCEDURES procedure->prc_owner = X.RDB$OWNER_NAME;
WITH X.RDB$PROCEDURE_NAME EQ metaName.identifier.c_str() AND procedure->prc_private = !X.RDB$PRIVATE_FLAG.NULL && X.RDB$PRIVATE_FLAG != 0;
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;
}
} }
END_FOR
if (!procedure)
return nullptr;
// Lookup parameter stuff // Lookup parameter stuff
@ -1076,10 +1063,12 @@ dsql_prc* METD_get_procedure(jrd_tra* transaction, DsqlCompilerScratch* dsqlScra
FOR (REQUEST_HANDLE handle2 TRANSACTION_HANDLE transaction) FOR (REQUEST_HANDLE handle2 TRANSACTION_HANDLE transaction)
PR IN RDB$PROCEDURE_PARAMETERS PR IN RDB$PROCEDURE_PARAMETERS
CROSS FLD IN RDB$FIELDS CROSS FLD IN RDB$FIELDS
WITH FLD.RDB$FIELD_NAME EQ PR.RDB$FIELD_SOURCE AND WITH PR.RDB$SCHEMA_NAME EQ qualifiedName.schema.c_str() AND
PR.RDB$PROCEDURE_NAME EQ metaName.identifier.c_str() AND PR.RDB$PROCEDURE_NAME EQ qualifiedName.object.c_str() AND
PR.RDB$PARAMETER_TYPE = type 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 SORTED BY DESCENDING PR.RDB$PARAMETER_NUMBER
{ {
const SSHORT pr_collation_id_null = PR.RDB$COLLATION_ID.NULL; 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 // get parameter information
parameter->fld_name = PR.RDB$PARAMETER_NAME; 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->fld_id = PR.RDB$PARAMETER_NUMBER;
parameter->length = FLD.RDB$FIELD_LENGTH; 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) if (!PR.RDB$FIELD_NAME.NULL)
{ {
fb_utils::exact_name(PR.RDB$FIELD_NAME); 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) if (!PR.RDB$RELATION_NAME.NULL)
{ parameter->typeOfTable = QualifiedName(PR.RDB$RELATION_NAME, PR.RDB$RELATION_SCHEMA_NAME);
fb_utils::exact_name(PR.RDB$RELATION_NAME);
parameter->typeOfTable = PR.RDB$RELATION_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; 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; 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; 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); dbb->dbb_procedures.put(procedure->prc_name, procedure);
if (procedure->prc_private && metaName.package != dsqlScratch->package) MET_dsql_cache_use(tdbb, SYM_procedure, procedure->prc_name);
{
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);
return procedure; return procedure;
} }
dsql_rel* METD_get_relation(jrd_tra* transaction, DsqlCompilerScratch* dsqlScratch, 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) FOR(REQUEST_HANDLE handle1 TRANSACTION_HANDLE transaction)
REL IN RDB$RELATIONS REL IN RDB$RELATIONS
CROSS RFR IN RDB$RELATION_FIELDS OVER RDB$RELATION_NAME CROSS RFR IN RDB$RELATION_FIELDS OVER RDB$SCHEMA_NAME, RDB$RELATION_NAME
WITH REL.RDB$RELATION_NAME EQ name.c_str() WITH REL.RDB$SCHEMA_NAME EQ name.schema.c_str() AND
AND (REL.RDB$RELATION_ID MISSING OR RFR.RDB$FIELD_ID MISSING) REL.RDB$RELATION_NAME EQ name.object.c_str() AND
(REL.RDB$RELATION_ID MISSING OR RFR.RDB$FIELD_ID MISSING)
{ {
permanent = false; permanent = false;
} }
@ -1259,10 +1239,10 @@ dsql_rel* METD_get_relation(jrd_tra* transaction, DsqlCompilerScratch* dsqlScrat
AutoCacheRequest handle2(tdbb, irq_relation, IRQ_REQUESTS); AutoCacheRequest handle2(tdbb, irq_relation, IRQ_REQUESTS);
FOR(REQUEST_HANDLE handle2 TRANSACTION_HANDLE transaction) 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 // Allocate from default or permanent pool as appropriate
if (!X.RDB$RELATION_ID.NULL) 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); AutoCacheRequest handle3(tdbb, irq_fields, IRQ_REQUESTS);
FOR(REQUEST_HANDLE handle3 TRANSACTION_HANDLE transaction) FOR(REQUEST_HANDLE handle3 TRANSACTION_HANDLE transaction)
FLX IN RDB$FIELDS CROSS FLX IN RDB$FIELDS
RFR IN RDB$RELATION_FIELDS CROSS RFR IN RDB$RELATION_FIELDS
WITH FLX.RDB$FIELD_NAME EQ RFR.RDB$FIELD_SOURCE WITH RFR.RDB$SCHEMA_NAME EQ name.schema.c_str() AND
AND RFR.RDB$RELATION_NAME EQ name.c_str() 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 SORTED BY RFR.RDB$FIELD_POSITION
{ {
// allocate the field block // Allocate the field block
fb_utils::exact_name(RFR.RDB$FIELD_NAME);
fb_utils::exact_name(RFR.RDB$FIELD_SOURCE);
// Allocate from default or permanent pool as appropriate // Allocate from default or permanent pool as appropriate
dsql_fld* field = NULL; dsql_fld* field = NULL;
@ -1331,7 +1309,7 @@ dsql_rel* METD_get_relation(jrd_tra* transaction, DsqlCompilerScratch* dsqlScrat
// get field information // get field information
field->fld_name = RFR.RDB$FIELD_NAME; 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->length = FLX.RDB$FIELD_LENGTH;
field->scale = FLX.RDB$FIELD_SCALE; field->scale = FLX.RDB$FIELD_SCALE;
field->subType = FLX.RDB$FIELD_SUB_TYPE; 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); AutoCacheRequest handle(tdbb, irq_type, IRQ_REQUESTS);
FOR(REQUEST_HANDLE handle TRANSACTION_HANDLE transaction) FOR(REQUEST_HANDLE handle TRANSACTION_HANDLE transaction)
X IN RDB$TYPES WITH X IN RDB$TYPES
X.RDB$FIELD_NAME EQ field AND X.RDB$TYPE_NAME EQ name.c_str(); WITH X.RDB$FIELD_NAME EQ field AND
X.RDB$TYPE_NAME EQ name.c_str()
{ {
found = true; found = true;
*value = X.RDB$TYPE; *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, 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); validateTransaction(transaction);
dsql_rel* relation = NULL; auto nextViewName = viewName;
dsql_rel* relation = nullptr;
bool first = true; bool first = true;
bool cont = true; bool cont = true;
MetaNamePairMap previousAux; MetaNamePairMap previousAux;
@ -1463,7 +1442,8 @@ dsql_rel* METD_get_view_base(jrd_tra* transaction, DsqlCompilerScratch* dsqlScra
FOR(REQUEST_HANDLE handle1 TRANSACTION_HANDLE transaction) FOR(REQUEST_HANDLE handle1 TRANSACTION_HANDLE transaction)
X IN RDB$VIEW_RELATIONS 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 // return NULL if there is more than one context
if (X.RDB$VIEW_CONTEXT != 1 || X.RDB$CONTEXT_TYPE == VCT_PROCEDURE) 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; break;
} }
fb_utils::exact_name(X.RDB$CONTEXT_NAME); nextViewName = QualifiedName(X.RDB$RELATION_NAME, X.RDB$RELATION_SCHEMA_NAME);
fb_utils::exact_name(X.RDB$RELATION_NAME); relation = METD_get_relation(transaction, dsqlScratch, nextViewName);
relation = METD_get_relation(transaction, dsqlScratch, X.RDB$RELATION_NAME);
Array<MetaName> ambiguities; Array<MetaName> ambiguities;
MetaNamePairMap currentAux; MetaNamePairMap currentAux;
@ -1491,7 +1469,8 @@ dsql_rel* METD_get_view_base(jrd_tra* transaction, DsqlCompilerScratch* dsqlScra
FOR(REQUEST_HANDLE handle2 TRANSACTION_HANDLE transaction) FOR(REQUEST_HANDLE handle2 TRANSACTION_HANDLE transaction)
RFL IN RDB$RELATION_FIELDS 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) if (RFL.RDB$BASE_FIELD.NULL || RFL.RDB$FIELD_NAME.NULL)
continue; continue;
@ -1534,9 +1513,7 @@ dsql_rel* METD_get_view_base(jrd_tra* transaction, DsqlCompilerScratch* dsqlScra
previousAux.takeOwnership(currentAux); previousAux.takeOwnership(currentAux);
if (relation->rel_flags & REL_view) if (!(relation->rel_flags & REL_view))
view_name = X.RDB$RELATION_NAME;
else
{ {
cont = false; cont = false;
break; 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, 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) 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); AutoCacheRequest handle(tdbb, irq_view, IRQ_REQUESTS);
FOR(REQUEST_HANDLE handle TRANSACTION_HANDLE transaction) 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); QualifiedName relationName(X.RDB$RELATION_NAME, X.RDB$RELATION_SCHEMA_NAME);
fb_utils::exact_name(X.RDB$RELATION_NAME);
if (relation_or_alias == X.RDB$RELATION_NAME || if (PASS1_compare_alias(relationName, relation_or_alias) ||
relation_or_alias == X.RDB$CONTEXT_NAME) (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; 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); X.RDB$PACKAGE_NAME.NULL ? nullptr : X.RDB$PACKAGE_NAME);
if ( (procedure = METD_get_procedure(transaction, dsqlScratch, procName)) ) if ( (procedure = METD_get_procedure(transaction, dsqlScratch, procName)) )
return true; return true;
} }
if (METD_get_view_relation(transaction, dsqlScratch, X.RDB$RELATION_NAME, if (METD_get_view_relation(transaction, dsqlScratch, relationName, relation_or_alias, relation, procedure))
relation_or_alias, relation, procedure))
{
return true; return true;
}
} }
END_FOR END_FOR

View File

@ -45,29 +45,30 @@ namespace Jrd {
class FieldNode; class FieldNode;
}; };
void METD_drop_charset(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::MetaName&); void METD_drop_collation(Jrd::jrd_tra*, const Jrd::QualifiedName&);
void METD_drop_function(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_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); USHORT METD_get_charset_bpc(Jrd::jrd_tra*, SSHORT);
Jrd::MetaName METD_get_charset_name(Jrd::jrd_tra*, SSHORT); Jrd::QualifiedName METD_get_charset_name(Jrd::jrd_tra*, SSHORT);
Jrd::dsql_intlsym* METD_get_collation(Jrd::jrd_tra*, const Jrd::MetaName&, USHORT charset_id); Jrd::dsql_intlsym* METD_get_collation(Jrd::jrd_tra*, const Jrd::QualifiedName&, USHORT charset_id);
Jrd::MetaName METD_get_default_charset(Jrd::jrd_tra*); Jrd::QualifiedName METD_get_database_charset(Jrd::jrd_tra*);
bool METD_get_domain(Jrd::jrd_tra*, class Jrd::TypeClause*, const Jrd::MetaName& name); 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*, Jrd::dsql_udf* METD_get_function(Jrd::jrd_tra*, Jrd::DsqlCompilerScratch*,
const Jrd::QualifiedName&); const Jrd::QualifiedName&);
void METD_get_primary_key(Jrd::jrd_tra*, const Jrd::MetaName&, void METD_get_primary_key(Jrd::jrd_tra*, const Jrd::QualifiedName&,
Firebird::Array<NestConst<Jrd::FieldNode> >&); Firebird::Array<NestConst<Jrd::FieldNode>>&);
Jrd::dsql_prc* METD_get_procedure(Jrd::jrd_tra*, Jrd::DsqlCompilerScratch*, Jrd::dsql_prc* METD_get_procedure(Jrd::jrd_tra*, Jrd::DsqlCompilerScratch*,
const Jrd::QualifiedName&); 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*); 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); Jrd::MetaNamePairMap& fields);
bool METD_get_view_relation(Jrd::jrd_tra*, Jrd::DsqlCompilerScratch*, const Jrd::MetaName& view_name, bool METD_get_view_relation(Jrd::jrd_tra*, Jrd::DsqlCompilerScratch*, const Jrd::QualifiedName& view_name,
const Jrd::MetaName& relation_or_alias, Jrd::dsql_rel*& relation, Jrd::dsql_prc*& procedure); const Jrd::QualifiedName& relation_or_alias, Jrd::dsql_rel*& relation, Jrd::dsql_prc*& procedure);
#endif // DSQL_METD_PROTO_H #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 * PROGRAM: Dynamic SQL runtime support
* MODULE: pass1.cpp * MODULE: pass1.cpp
@ -139,6 +162,7 @@
*/ */
#include "firebird.h" #include "firebird.h"
#include <numeric>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include "ibase.h" #include "ibase.h"
@ -165,6 +189,7 @@
#include "../common/dsc_proto.h" #include "../common/dsc_proto.h"
#include "../jrd/intl_proto.h" #include "../jrd/intl_proto.h"
#include "../jrd/jrd_proto.h" #include "../jrd/jrd_proto.h"
#include "../jrd/met_proto.h"
#include "../yvalve/why_proto.h" #include "../yvalve/why_proto.h"
#include "../jrd/SysFunction.h" #include "../jrd/SysFunction.h"
#include "../common/classes/array.h" #include "../common/classes/array.h"
@ -177,7 +202,6 @@ using namespace Jrd;
using namespace Firebird; using namespace Firebird;
static string pass1_alias_concat(const string&, const string&);
static ValueListNode* pass1_group_by_list(DsqlCompilerScratch*, ValueListNode*, ValueListNode*); static ValueListNode* pass1_group_by_list(DsqlCompilerScratch*, ValueListNode*, ValueListNode*);
static ValueExprNode* pass1_make_derived_field(thread_db*, DsqlCompilerScratch*, ValueExprNode*); static ValueExprNode* pass1_make_derived_field(thread_db*, DsqlCompilerScratch*, ValueExprNode*);
static RseNode* pass1_rse(DsqlCompilerScratch*, RecordSourceNode*, ValueListNode*, RowsClause*, bool, bool, USHORT); 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(); 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 // figure out whether this is a relation or a procedure
// and give an error if it is neither // and give an error if it is neither
MetaName relation_name; QualifiedName name;
ProcedureSourceNode* procNode = NULL; ProcedureSourceNode* procNode = NULL;
RelationSourceNode* relNode = NULL; RelationSourceNode* relNode = NULL;
SelectExprNode* selNode = NULL; SelectExprNode* selNode = NULL;
if ((procNode = nodeAs<ProcedureSourceNode>(relationNode))) if ((procNode = nodeAs<ProcedureSourceNode>(relationNode)))
relation_name = procNode->dsqlName.identifier; name = procNode->dsqlName;
else if ((relNode = nodeAs<RelationSourceNode>(relationNode))) else if ((relNode = nodeAs<RelationSourceNode>(relationNode)))
relation_name = relNode->dsqlName; name = relNode->dsqlName;
//// TODO: LocalTableSourceNode //// TODO: LocalTableSourceNode
else if ((selNode = nodeAs<SelectExprNode>(relationNode))) else if ((selNode = nodeAs<SelectExprNode>(relationNode)))
relation_name = selNode->alias.c_str(); name.object = selNode->alias;
SelectExprNode* cte = NULL; SelectExprNode* cte = NULL;
dsql_rel* relation = NULL;
dsql_prc* procedure = NULL;
if (selNode) if (selNode)
{ {
// No processing needed here for derived tables. // 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; relationNode = cte;
}
else else
{ {
if (procNode && procNode->dsqlName.package.isEmpty()) auto qualifiedName = name;
if (name.package.isEmpty())
{ {
const auto subProcedure = dsqlScratch->getSubProcedure(procNode->dsqlName.identifier); if (name.schema.isEmpty())
procedure = subProcedure ? subProcedure->dsqlProcedure : NULL; {
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) if (!procedure)
relation = METD_get_relation(dsqlScratch->getTransaction(), dsqlScratch, relation_name); procedure = METD_get_procedure(dsqlScratch->getTransaction(), dsqlScratch, qualifiedName);
if (!relation && !procedure && procNode) if (!procedure && !(name.package.hasData() || (procNode && procNode->inputSources)))
procedure = METD_get_procedure(dsqlScratch->getTransaction(), dsqlScratch, procNode->dsqlName);
if (!relation && !procedure)
{ {
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-204) << qualifiedName = name;
Arg::Gds(isc_dsql_relation_err) << dsqlScratch->qualifyExistingName(qualifiedName, obj_relation);
Arg::Gds(isc_random) << Arg::Str(relation_name) << relation = METD_get_relation(dsqlScratch->getTransaction(), dsqlScratch, qualifiedName);
Arg::Gds(isc_dsql_line_col_error) << Arg::Num(relationNode->line) <<
Arg::Num(relationNode->column));
} }
}
if (procedure && !procedure->prc_out_count) if (!procedure && !relation)
{ {
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-84) << const auto errorCode = name.package.hasData() || (procNode && procNode->inputSources) ?
Arg::Gds(isc_dsql_procedure_use_err) << Arg::Str(procedure->prc_name.toString()) << isc_dsql_procedure_err : isc_dsql_relation_err;
Arg::Gds(isc_dsql_line_col_error) << Arg::Num(relationNode->line) <<
Arg::Num(relationNode->column)); 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. // Set up context block.
@ -469,20 +526,16 @@ dsql_ctx* PASS1_make_context(DsqlCompilerScratch* dsqlScratch, RecordSourceNode*
} }
if (str.hasData()) if (str.hasData())
context->ctx_internal_alias = str; context->ctx_internal_alias = QualifiedName(str);
if (dsqlScratch->aliasRelationPrefix.hasData() && !selNode) if (dsqlScratch->aliasRelationPrefix.hasData() && !selNode)
{ context->ctx_alias = dsqlScratch->aliasRelationPrefix;
if (str.hasData())
str = pass1_alias_concat(dsqlScratch->aliasRelationPrefix, str);
else
str = pass1_alias_concat(dsqlScratch->aliasRelationPrefix, relation_name.c_str());
}
if (str.hasData()) if (str.hasData())
{ context->ctx_alias.push(QualifiedName(str));
context->ctx_alias = str;
if (context->ctx_alias.hasData())
{
// check to make sure the context is not already used at this same // check to make sure the context is not already used at this same
// query level (if there are no subqueries, this checks that the // query level (if there are no subqueries, this checks that the
// alias is not used twice in the dsqlScratch). // 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) if (conflict->ctx_scope_level != context->ctx_scope_level)
continue; continue;
const TEXT* conflict_name; ObjectsArray<QualifiedName> conflictNames;
ISC_STATUS error_code; ISC_STATUS error_code;
if (conflict->ctx_alias.hasData()) if (conflict->ctx_alias.hasData())
{ {
conflict_name = conflict->ctx_alias.c_str(); conflictNames = conflict->ctx_alias;
error_code = isc_alias_conflict_err; error_code = isc_alias_conflict_err;
// alias %s conflicts with an alias in the same dsqlScratch. // alias %s conflicts with an alias in the same dsqlScratch.
} }
else if (conflict->ctx_procedure) 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; error_code = isc_procedure_conflict_error;
// alias %s conflicts with a procedure in the same dsqlScratch. // alias %s conflicts with a procedure in the same dsqlScratch.
} }
else if (conflict->ctx_relation) 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; error_code = isc_relation_conflict_err;
// alias %s conflicts with a relation in the same dsqlScratch. // alias %s conflicts with a relation in the same dsqlScratch.
} }
else else
continue; 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) << 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; USHORT count = 0;
if (procNode->inputSources) if (procNode && procNode->inputSources)
{ {
context->ctx_proc_inputs = Node::doDsqlPass(dsqlScratch, procNode->inputSources, false); context->ctx_proc_inputs = Node::doDsqlPass(dsqlScratch, procNode->inputSources, false);
count = context->ctx_proc_inputs->items.getCount(); 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 || if (count > procedure->prc_in_count ||
count < procedure->prc_in_count - procedure->prc_def_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) if (count)
@ -595,7 +659,7 @@ dsql_ctx* PASS1_make_context(DsqlCompilerScratch* dsqlScratch, RecordSourceNode*
} }
if (mismatchStatus.hasData()) 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) if (ambiguous_contexts.getCount() < 2)
return; return;
TEXT buffer[1024]; string buffers[2];
USHORT loop = 0; string* bufferPtr = &buffers[0];
buffer[0] = 0;
TEXT* b = buffer;
TEXT* p = NULL;
for (DsqlContextStack::const_iterator stack(ambiguous_contexts); stack.hasData(); ++stack) for (DsqlContextStack::const_iterator stack(ambiguous_contexts); stack.hasData(); ++stack)
{ {
string& buffer = *bufferPtr;
const dsql_ctx* context = stack.object(); const dsql_ctx* context = stack.object();
const dsql_rel* relation = context->ctx_relation; const dsql_rel* relation = context->ctx_relation;
const dsql_prc* procedure = context->ctx_procedure; 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 this is the second loop add "and " before relation.
if (++loop > 2) if (buffer.hasData())
strcat(buffer, "and "); buffer += " and ";
// Process relation when present. // Process relation when present.
if (relation) if (relation)
{ {
if (!(relation->rel_flags & REL_view)) if (!(relation->rel_flags & REL_view))
strcat(buffer, "table "); buffer += "table ";
else else
strcat(buffer, "view "); buffer += "view ";
strcat(buffer, relation->rel_name.c_str());
buffer += relation->rel_name.toQuotedString();
} }
else if (procedure) else if (procedure)
{ {
// Process procedure when present. // Process procedure when present.
strcat(b, "procedure "); buffer += "procedure ";
strcat(b, procedure->prc_name.toString().c_str()); buffer += procedure->prc_name.toQuotedString();
} }
else else
{ {
// When there's no relation and no procedure it's a derived table. const auto contextAliases = context->getConcatenatedAlias();
strcat(b, "derived table ");
if (context->ctx_alias.hasData())
strcat(b, context->ctx_alias.c_str());
}
strcat(buffer, " ");
if (!p)
p = b + strlen(b);
}
if (p) // When there's no relation and no procedure it's a derived table.
*--p = 0; buffer += "derived table ";
if (context->ctx_alias.hasData())
buffer += contextAliases;
}
if (bufferPtr == &buffers[0])
++bufferPtr;
}
if (dsqlScratch->clientDialect >= SQL_DIALECT_V6) if (dsqlScratch->clientDialect >= SQL_DIALECT_V6)
{ {
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-204) << 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); Arg::Gds(isc_random) << name);
} }
ERRD_post_warning(Arg::Warning(isc_sqlwarn) << Arg::Num(204) << ERRD_post_warning(Arg::Warning(isc_sqlwarn) << Arg::Num(204) <<
Arg::Warning(isc_dsql_ambiguous_field_name) << Arg::Str(buffer) << Arg::Warning(isc_dsql_ambiguous_field_name) << buffers[0] << buffers[1] <<
Arg::Str(++p) <<
Arg::Warning(isc_random) << name); 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. // Compose two booleans.
BoolExprNode* PASS1_compose(BoolExprNode* expr1, BoolExprNode* expr2, UCHAR blrOp) 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, void PASS1_field_unknown(const TEXT* qualifier_name, const TEXT* field_name,
const ExprNode* flawed_node) const ExprNode* flawed_node)
{ {
TEXT field_buffer[MAX_SQL_IDENTIFIER_SIZE * 2]; string buffer;
if (qualifier_name) if (qualifier_name)
{ {
sprintf(field_buffer, "%.*s.%.*s", (int) MAX_SQL_IDENTIFIER_LEN, qualifier_name, buffer.printf("%s.%s", qualifier_name, (field_name ? field_name : "*"));
(int) MAX_SQL_IDENTIFIER_LEN, field_name ? field_name : "*"); field_name = buffer.c_str();
field_name = field_buffer;
} }
if (flawed_node) if (flawed_node)
@ -941,13 +1023,13 @@ DeclareCursorNode* PASS1_cursor_name(DsqlCompilerScratch* dsqlScratch, const Met
{ {
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-504) << ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-504) <<
Arg::Gds(isc_dsql_cursor_err) << 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) else if (cursor && !existence_flag)
{ {
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-502) << ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-502) <<
Arg::Gds(isc_dsql_decl_err) << Arg::Gds(isc_dsql_decl_err) <<
Arg::Gds(isc_dsql_cursor_exists) << name); Arg::Gds(isc_dsql_cursor_exists) << name.toQuotedString());
} }
return cursor; return cursor;
@ -983,14 +1065,14 @@ RseNode* PASS1_derived_table(DsqlCompilerScratch* dsqlScratch, SelectExprNode* i
thread_db* tdbb = JRD_get_thread_data(); thread_db* tdbb = JRD_get_thread_data();
MemoryPool& pool = *tdbb->getDefaultPool(); 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. // Create the context now, because we need to know it for the tables inside.
dsql_ctx* const context = PASS1_make_context(dsqlScratch, input); dsql_ctx* const context = PASS1_make_context(dsqlScratch, input);
// Save some values to restore after rse process. // Save some values to restore after rse process.
DsqlContextStack* const req_base = dsqlScratch->context; 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 // Change context, because the derived table cannot reference other streams
// at the same scope_level (unless this is a lateral derived table). // 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(); baseContext = temp.object();
dsqlScratch->context = &temp; dsqlScratch->context = &temp;
dsqlScratch->aliasRelationPrefix = pass1_alias_concat(aliasRelationPrefix, alias);
if (alias.hasData())
dsqlScratch->aliasRelationPrefix.add(QualifiedName(alias));
RecordSourceNode* query = input->querySpec; RecordSourceNode* query = input->querySpec;
UnionSourceNode* unionQuery = nodeAs<UnionSourceNode>(query); 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 // CVC: prepare a truncated alias for the derived table here
// because we need it several times. // because we need it several times.
TEXT aliasbuffer[100] = ""; string aliasname;
const TEXT* aliasname = aliasbuffer;
if (alias.hasData()) if (alias.hasData())
{ aliasname = alias;
int length = alias.length();
if (length > 99)
{
length = 99;
memcpy(aliasbuffer, alias.c_str(), length);
aliasbuffer[length] = 0;
}
else
aliasname = alias.c_str();
}
else else
aliasname = "<unnamed>"; aliasname = "<unnamed>";
@ -1236,7 +1310,7 @@ RseNode* PASS1_derived_table(DsqlCompilerScratch* dsqlScratch, SelectExprNode* i
const string* const saveCteAlias = const string* const saveCteAlias =
dsqlScratch->currCteAlias ? *dsqlScratch->currCteAlias : NULL; dsqlScratch->currCteAlias ? *dsqlScratch->currCteAlias : NULL;
dsqlScratch->resetCTEAlias(alias); dsqlScratch->resetCTEAlias(alias.c_str());
rse = PASS1_rse(dsqlScratch, input, select); rse = PASS1_rse(dsqlScratch, input, select);
@ -1260,7 +1334,10 @@ RseNode* PASS1_derived_table(DsqlCompilerScratch* dsqlScratch, SelectExprNode* i
context->ctx_rse = rse; context->ctx_rse = rse;
if (cte_alias) if (cte_alias)
context->ctx_alias = cte_alias; {
context->ctx_alias.clear();
context->ctx_alias.push(QualifiedName(cte_alias));
}
dsqlScratch->context = req_base; dsqlScratch->context = req_base;
@ -1481,7 +1558,7 @@ static ValueListNode* pass1_group_by_list(DsqlCompilerScratch* dsqlScratch, Valu
if ((field = nodeAs<FieldNode>(sub))) if ((field = nodeAs<FieldNode>(sub)))
{ {
// check for alias or field node // 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. // AB: Check first against the select list for matching column.
// When no matches at all are found we go on with our // 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. // Wrapper for pass1_rse_impl. Substitute recursive CTE alias (if needed) and call pass1_rse_impl.
static RseNode* pass1_rse(DsqlCompilerScratch* dsqlScratch, RecordSourceNode* input, static RseNode* pass1_rse(DsqlCompilerScratch* dsqlScratch, RecordSourceNode* input,
ValueListNode* order, RowsClause* rows, bool updateLock, bool skipLocked, USHORT flags) ValueListNode* order, RowsClause* rows, bool updateLock, bool skipLocked, USHORT flags)
{ {
string save_alias; ObjectsArray<QualifiedName> save_alias;
RseNode* rseNode = nodeAs<RseNode>(input); RseNode* rseNode = nodeAs<RseNode>(input);
const bool isRecursive = rseNode && (rseNode->dsqlFlags & RecordSourceNode::DFLAG_RECURSIVE); const bool isRecursive = rseNode && (rseNode->dsqlFlags & RecordSourceNode::DFLAG_RECURSIVE);
AutoSetRestore<USHORT> autoScopeLevel(&dsqlScratch->scopeLevel, dsqlScratch->scopeLevel); AutoSetRestore<USHORT> autoScopeLevel(&dsqlScratch->scopeLevel, dsqlScratch->scopeLevel);
@ -1769,7 +1826,8 @@ static RseNode* pass1_rse(DsqlCompilerScratch* dsqlScratch, RecordSourceNode* in
fb_assert(dsqlScratch->recursiveCtx); fb_assert(dsqlScratch->recursiveCtx);
save_alias = dsqlScratch->recursiveCtx->ctx_alias; 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 // 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. // 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; ValueExprNode* aliasNode = NULL;
// check for alias or field node // 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. // AB: Check first against the select list for matching column.
// When no matches at all are found we go on with our // 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 != end;
++ptr, ++uptr) ++ptr, ++uptr)
{ {
OrderNode* order1 = nodeAs<OrderNode>(*ptr); const auto order1 = nodeAs<OrderNode>(*ptr);
const ValueExprNode* position = order1->value; auto position = order1->value;
const CollateNode* collateNode = nodeAs<CollateNode>(position); const auto collateNode = nodeAs<CollateNode>(position);
if (collateNode) if (collateNode)
position = collateNode->arg; position = collateNode->arg;

View File

@ -39,6 +39,9 @@ namespace Jrd
} }
void PASS1_ambiguity_check(Jrd::DsqlCompilerScratch*, const Jrd::MetaName&, const Jrd::DsqlContextStack&); 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::BoolExprNode* PASS1_compose(Jrd::BoolExprNode*, Jrd::BoolExprNode*, UCHAR);
Jrd::DeclareCursorNode* PASS1_cursor_name(Jrd::DsqlCompilerScratch*, const Jrd::MetaName&, USHORT, bool); Jrd::DeclareCursorNode* PASS1_cursor_name(Jrd::DsqlCompilerScratch*, const Jrd::MetaName&, USHORT, bool);
Jrd::RseNode* PASS1_derived_table(Jrd::DsqlCompilerScratch*, Jrd::SelectExprNode*, const char*, 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) 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) if (!symbol)
{ {
PAR_error("NATIONAL character set missing"); PAR_error("NATIONAL character set missing");

View File

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

View File

@ -408,6 +408,9 @@ interface MessageMetadata : ReferenceCounted
version: // 3.0 => 4.0 version: // 3.0 => 4.0
uint getAlignment(Status status); uint getAlignment(Status status);
uint getAlignedLength(Status status); uint getAlignedLength(Status status);
version: // 5.0 => 6.0 Alpha1
const string getSchema(Status status, uint index);
} }
interface MetadataBuilder : ReferenceCounted interface MetadataBuilder : ReferenceCounted
@ -430,6 +433,9 @@ version: // 3.0 => 4.0
void setRelation(Status status, uint index, const string relation); void setRelation(Status status, uint index, const string relation);
void setOwner(Status status, uint index, const string owner); void setOwner(Status status, uint index, const string owner);
void setAlias(Status status, uint index, const string alias); 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 interface ResultSet : ReferenceCounted
@ -1132,6 +1138,9 @@ interface RoutineMetadata : Versioned
MessageMetadata getTriggerMetadata(Status status) const; MessageMetadata getTriggerMetadata(Status status) const;
const string getTriggerTable(Status status) const; const string getTriggerTable(Status status) const;
uint getTriggerType(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); uint* fractions, uint timeZoneBufferLength, string timeZoneBuffer);
void decodeTimeStampTzEx(Status status, const ISC_TIMESTAMP_TZ_EX* timeStampTz, uint* year, uint* month, uint* day, 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); 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 interface OffsetsCallback : Versioned
@ -1742,16 +1757,24 @@ interface ReplicatedTransaction : Disposable
void rollbackSavepoint(Status status); void rollbackSavepoint(Status status);
// ReplicatedRecords parameters point to local objects, do not ever store the pointer. // ReplicatedRecords parameters point to local objects, do not ever store the pointer.
void insertRecord(Status status, const string name, void deprecatedInsertRecord(Status status, const string name, ReplicatedRecord record);
ReplicatedRecord record); void deprecatedUpdateRecord(Status status, const string name,
void updateRecord(Status status, const string name, ReplicatedRecord orgRecord, ReplicatedRecord newRecord);
ReplicatedRecord orgRecord, void deprecatedDeleteRecord(Status status, const string name, ReplicatedRecord record);
ReplicatedRecord newRecord);
void deleteRecord(Status status, const string name,
ReplicatedRecord record);
void executeSql(Status status, const string sql); void deprecatedExecuteSql(Status status, const string sql);
void executeSqlIntl(Status status, uint charset, 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 interface ReplicatedSession : PluginBase
@ -1761,7 +1784,10 @@ interface ReplicatedSession : PluginBase
ReplicatedTransaction startTransaction(Status status, Transaction transaction, int64 number); ReplicatedTransaction startTransaction(Status status, Transaction transaction, int64 number);
void cleanupTransaction(Status status, 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 // Profiler interfaces
@ -1789,7 +1815,7 @@ interface ProfilerSession : Disposable
void finish(Status status, ISC_TIMESTAMP_TZ timestamp); 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); 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); 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 beforeRecordSourceGetRecord(int64 statementId, int64 requestId, uint cursorId, uint recSourceId);
void afterRecordSourceGetRecord(int64 statementId, int64 requestId, uint cursorId, uint recSourceId, void afterRecordSourceGetRecord(int64 statementId, int64 requestId, uint cursorId, uint recSourceId,
ProfilerStats stats); 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 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 class IMessageMetadata : public IReferenceCounted
{ {
@ -1389,6 +1389,7 @@ namespace Firebird
unsigned (CLOOP_CARG *getMessageLength)(IMessageMetadata* self, IStatus* status) CLOOP_NOEXCEPT; unsigned (CLOOP_CARG *getMessageLength)(IMessageMetadata* self, IStatus* status) CLOOP_NOEXCEPT;
unsigned (CLOOP_CARG *getAlignment)(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; unsigned (CLOOP_CARG *getAlignedLength)(IMessageMetadata* self, IStatus* status) CLOOP_NOEXCEPT;
const char* (CLOOP_CARG *getSchema)(IMessageMetadata* self, IStatus* status, unsigned index) CLOOP_NOEXCEPT;
}; };
protected: protected:
@ -1551,9 +1552,23 @@ namespace Firebird
StatusType::checkException(status); StatusType::checkException(status);
return ret; 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 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 *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 *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 *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: protected:
@ -1712,6 +1728,19 @@ namespace Firebird
static_cast<VTable*>(this->cloopVTable)->setAlias(this, status, index, alias); static_cast<VTable*>(this->cloopVTable)->setAlias(this, status, index, alias);
StatusType::checkException(status); 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 #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 class IRoutineMetadata : public IVersioned
{ {
@ -4392,6 +4421,7 @@ namespace Firebird
IMessageMetadata* (CLOOP_CARG *getTriggerMetadata)(const IRoutineMetadata* self, IStatus* status) CLOOP_NOEXCEPT; IMessageMetadata* (CLOOP_CARG *getTriggerMetadata)(const IRoutineMetadata* self, IStatus* status) CLOOP_NOEXCEPT;
const char* (CLOOP_CARG *getTriggerTable)(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; unsigned (CLOOP_CARG *getTriggerType)(const IRoutineMetadata* self, IStatus* status) CLOOP_NOEXCEPT;
const char* (CLOOP_CARG *getSchema)(const IRoutineMetadata* self, IStatus* status) CLOOP_NOEXCEPT;
}; };
protected: protected:
@ -4478,6 +4508,20 @@ namespace Firebird
StatusType::checkException(status); StatusType::checkException(status);
return ret; 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 #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 class IUtil : public IVersioned
{ {
@ -4682,6 +4726,7 @@ namespace Firebird
IInt128* (CLOOP_CARG *getInt128)(IUtil* self, IStatus* status) CLOOP_NOEXCEPT; 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 *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; 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: 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); static_cast<VTable*>(this->cloopVTable)->decodeTimeStampTzEx(this, status, timeStampTz, year, month, day, hours, minutes, seconds, fractions, timeZoneBufferLength, timeZoneBuffer);
StatusType::checkException(status); 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 #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 class IReplicatedTransaction : public IDisposable
{ {
@ -6903,11 +6962,15 @@ namespace Firebird
void (CLOOP_CARG *startSavepoint)(IReplicatedTransaction* self, IStatus* status) CLOOP_NOEXCEPT; void (CLOOP_CARG *startSavepoint)(IReplicatedTransaction* self, IStatus* status) CLOOP_NOEXCEPT;
void (CLOOP_CARG *releaseSavepoint)(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 *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 *deprecatedInsertRecord)(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 *deprecatedUpdateRecord)(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 *deprecatedDeleteRecord)(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 *deprecatedExecuteSql)(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 *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: protected:
@ -6965,43 +7028,95 @@ namespace Firebird
StatusType::checkException(status); 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); 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); 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); 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); 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); 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); 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); StatusType::clearException(status);
static_cast<VTable*>(this->cloopVTable)->executeSql(this, status, sql); static_cast<VTable*>(this->cloopVTable)->deprecatedExecuteSql(this, status, sql);
StatusType::checkException(status); 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); 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); StatusType::checkException(status);
} }
}; };
#define FIREBIRD_IREPLICATED_SESSION_VERSION 4u #define FIREBIRD_IREPLICATED_SESSION_VERSION 5u
class IReplicatedSession : public IPluginBase class IReplicatedSession : public IPluginBase
{ {
@ -7011,7 +7126,8 @@ namespace Firebird
FB_BOOLEAN (CLOOP_CARG *init)(IReplicatedSession* self, IStatus* status, IAttachment* attachment) CLOOP_NOEXCEPT; 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; 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 *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: protected:
@ -7050,10 +7166,23 @@ namespace Firebird
StatusType::checkException(status); 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); 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); 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 class IProfilerSession : public IDisposable
{ {
@ -7117,7 +7246,7 @@ namespace Firebird
unsigned (CLOOP_CARG *getFlags)(IProfilerSession* self) CLOOP_NOEXCEPT; unsigned (CLOOP_CARG *getFlags)(IProfilerSession* self) CLOOP_NOEXCEPT;
void (CLOOP_CARG *cancel)(IProfilerSession* self, IStatus* status) 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 *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 *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 *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; 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 *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 *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 *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: protected:
@ -7172,10 +7302,10 @@ namespace Firebird
StatusType::checkException(status); 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); 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); StatusType::checkException(status);
} }
@ -7232,6 +7362,18 @@ namespace Firebird
{ {
static_cast<VTable*>(this->cloopVTable)->afterRecordSourceGetRecord(this, statementId, requestId, cursorId, recSourceId, stats); 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 #define FIREBIRD_IPROFILER_STATS_VERSION 2u
@ -9609,6 +9751,7 @@ namespace Firebird
this->getMessageLength = &Name::cloopgetMessageLengthDispatcher; this->getMessageLength = &Name::cloopgetMessageLengthDispatcher;
this->getAlignment = &Name::cloopgetAlignmentDispatcher; this->getAlignment = &Name::cloopgetAlignmentDispatcher;
this->getAlignedLength = &Name::cloopgetAlignedLengthDispatcher; this->getAlignedLength = &Name::cloopgetAlignedLengthDispatcher;
this->getSchema = &Name::cloopgetSchemaDispatcher;
} }
} vTable; } 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 static void CLOOP_CARG cloopaddRefDispatcher(IReferenceCounted* self) CLOOP_NOEXCEPT
{ {
try try
@ -9926,6 +10084,7 @@ namespace Firebird
virtual unsigned getMessageLength(StatusType* status) = 0; virtual unsigned getMessageLength(StatusType* status) = 0;
virtual unsigned getAlignment(StatusType* status) = 0; virtual unsigned getAlignment(StatusType* status) = 0;
virtual unsigned getAlignedLength(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> template <typename Name, typename StatusType, typename Base>
@ -9957,6 +10116,7 @@ namespace Firebird
this->setRelation = &Name::cloopsetRelationDispatcher; this->setRelation = &Name::cloopsetRelationDispatcher;
this->setOwner = &Name::cloopsetOwnerDispatcher; this->setOwner = &Name::cloopsetOwnerDispatcher;
this->setAlias = &Name::cloopsetAliasDispatcher; this->setAlias = &Name::cloopsetAliasDispatcher;
this->setSchema = &Name::cloopsetSchemaDispatcher;
} }
} vTable; } 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 static void CLOOP_CARG cloopaddRefDispatcher(IReferenceCounted* self) CLOOP_NOEXCEPT
{ {
try try
@ -10214,6 +10388,7 @@ namespace Firebird
virtual void setRelation(StatusType* status, unsigned index, const char* relation) = 0; virtual void setRelation(StatusType* status, unsigned index, const char* relation) = 0;
virtual void setOwner(StatusType* status, unsigned index, const char* owner) = 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 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> template <typename Name, typename StatusType, typename Base>
@ -15404,6 +15579,7 @@ namespace Firebird
this->getTriggerMetadata = &Name::cloopgetTriggerMetadataDispatcher; this->getTriggerMetadata = &Name::cloopgetTriggerMetadataDispatcher;
this->getTriggerTable = &Name::cloopgetTriggerTableDispatcher; this->getTriggerTable = &Name::cloopgetTriggerTableDispatcher;
this->getTriggerType = &Name::cloopgetTriggerTypeDispatcher; this->getTriggerType = &Name::cloopgetTriggerTypeDispatcher;
this->getSchema = &Name::cloopgetSchemaDispatcher;
} }
} vTable; } vTable;
@ -15544,6 +15720,21 @@ namespace Firebird
return static_cast<unsigned>(0); 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> > > 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 IMessageMetadata* getTriggerMetadata(StatusType* status) const = 0;
virtual const char* getTriggerTable(StatusType* status) const = 0; virtual const char* getTriggerTable(StatusType* status) const = 0;
virtual unsigned getTriggerType(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> template <typename Name, typename StatusType, typename Base>
@ -15987,6 +16179,7 @@ namespace Firebird
this->getInt128 = &Name::cloopgetInt128Dispatcher; this->getInt128 = &Name::cloopgetInt128Dispatcher;
this->decodeTimeTzEx = &Name::cloopdecodeTimeTzExDispatcher; this->decodeTimeTzEx = &Name::cloopdecodeTimeTzExDispatcher;
this->decodeTimeStampTzEx = &Name::cloopdecodeTimeStampTzExDispatcher; this->decodeTimeStampTzEx = &Name::cloopdecodeTimeStampTzExDispatcher;
this->executeCreateDatabase2 = &Name::cloopexecuteCreateDatabase2Dispatcher;
} }
} vTable; } vTable;
@ -16298,6 +16491,21 @@ namespace Firebird
StatusType::catchException(&status2); 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> > > 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 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 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 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> template <typename Name, typename StatusType, typename Base>
@ -20297,11 +20506,15 @@ namespace Firebird
this->startSavepoint = &Name::cloopstartSavepointDispatcher; this->startSavepoint = &Name::cloopstartSavepointDispatcher;
this->releaseSavepoint = &Name::cloopreleaseSavepointDispatcher; this->releaseSavepoint = &Name::cloopreleaseSavepointDispatcher;
this->rollbackSavepoint = &Name::clooprollbackSavepointDispatcher; this->rollbackSavepoint = &Name::clooprollbackSavepointDispatcher;
this->insertRecord = &Name::cloopinsertRecordDispatcher; this->deprecatedInsertRecord = &Name::cloopdeprecatedInsertRecordDispatcher;
this->updateRecord = &Name::cloopupdateRecordDispatcher; this->deprecatedUpdateRecord = &Name::cloopdeprecatedUpdateRecordDispatcher;
this->deleteRecord = &Name::cloopdeleteRecordDispatcher; this->deprecatedDeleteRecord = &Name::cloopdeprecatedDeleteRecordDispatcher;
this->executeSql = &Name::cloopexecuteSqlDispatcher; this->deprecatedExecuteSql = &Name::cloopdeprecatedExecuteSqlDispatcher;
this->executeSqlIntl = &Name::cloopexecuteSqlIntlDispatcher; this->deprecatedExecuteSqlIntl = &Name::cloopdeprecatedExecuteSqlIntlDispatcher;
this->insertRecord2 = &Name::cloopinsertRecord2Dispatcher;
this->updateRecord2 = &Name::cloopupdateRecord2Dispatcher;
this->deleteRecord2 = &Name::cloopdeleteRecord2Dispatcher;
this->executeSqlIntl2 = &Name::cloopexecuteSqlIntl2Dispatcher;
} }
} vTable; } 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); StatusType status2(status);
try try
{ {
static_cast<Name*>(self)->Name::insertRecord(&status2, name, record); static_cast<Name*>(self)->Name::deprecatedInsertRecord(&status2, name, record);
} }
catch (...) 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); StatusType status2(status);
try try
{ {
static_cast<Name*>(self)->Name::updateRecord(&status2, name, orgRecord, newRecord); static_cast<Name*>(self)->Name::deprecatedUpdateRecord(&status2, name, orgRecord, newRecord);
} }
catch (...) 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); StatusType status2(status);
try try
{ {
static_cast<Name*>(self)->Name::deleteRecord(&status2, name, record); static_cast<Name*>(self)->Name::deprecatedDeleteRecord(&status2, name, record);
} }
catch (...) 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); StatusType status2(status);
try try
{ {
static_cast<Name*>(self)->Name::executeSql(&status2, sql); static_cast<Name*>(self)->Name::deprecatedExecuteSql(&status2, sql);
} }
catch (...) 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); StatusType status2(status);
try 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 (...) catch (...)
{ {
@ -20494,11 +20763,15 @@ namespace Firebird
virtual void startSavepoint(StatusType* status) = 0; virtual void startSavepoint(StatusType* status) = 0;
virtual void releaseSavepoint(StatusType* status) = 0; virtual void releaseSavepoint(StatusType* status) = 0;
virtual void rollbackSavepoint(StatusType* status) = 0; virtual void rollbackSavepoint(StatusType* status) = 0;
virtual void insertRecord(StatusType* status, const char* name, IReplicatedRecord* record) = 0; virtual void deprecatedInsertRecord(StatusType* status, const char* name, IReplicatedRecord* record) = 0;
virtual void updateRecord(StatusType* status, const char* name, IReplicatedRecord* orgRecord, IReplicatedRecord* newRecord) = 0; virtual void deprecatedUpdateRecord(StatusType* status, const char* name, IReplicatedRecord* orgRecord, IReplicatedRecord* newRecord) = 0;
virtual void deleteRecord(StatusType* status, const char* name, IReplicatedRecord* record) = 0; virtual void deprecatedDeleteRecord(StatusType* status, const char* name, IReplicatedRecord* record) = 0;
virtual void executeSql(StatusType* status, const char* sql) = 0; virtual void deprecatedExecuteSql(StatusType* status, const char* sql) = 0;
virtual void executeSqlIntl(StatusType* status, unsigned charset, 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> template <typename Name, typename StatusType, typename Base>
@ -20521,7 +20794,8 @@ namespace Firebird
this->init = &Name::cloopinitDispatcher; this->init = &Name::cloopinitDispatcher;
this->startTransaction = &Name::cloopstartTransactionDispatcher; this->startTransaction = &Name::cloopstartTransactionDispatcher;
this->cleanupTransaction = &Name::cloopcleanupTransactionDispatcher; this->cleanupTransaction = &Name::cloopcleanupTransactionDispatcher;
this->setSequence = &Name::cloopsetSequenceDispatcher; this->deprecatedSetSequence = &Name::cloopdeprecatedSetSequenceDispatcher;
this->setSequence2 = &Name::cloopsetSequence2Dispatcher;
} }
} vTable; } 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); StatusType status2(status);
try 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 (...) catch (...)
{ {
@ -20653,7 +20941,8 @@ namespace Firebird
virtual FB_BOOLEAN init(StatusType* status, IAttachment* attachment) = 0; virtual FB_BOOLEAN init(StatusType* status, IAttachment* attachment) = 0;
virtual IReplicatedTransaction* startTransaction(StatusType* status, ITransaction* transaction, ISC_INT64 number) = 0; virtual IReplicatedTransaction* startTransaction(StatusType* status, ITransaction* transaction, ISC_INT64 number) = 0;
virtual void cleanupTransaction(StatusType* status, 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> template <typename Name, typename StatusType, typename Base>
@ -20812,7 +21101,7 @@ namespace Firebird
this->getFlags = &Name::cloopgetFlagsDispatcher; this->getFlags = &Name::cloopgetFlagsDispatcher;
this->cancel = &Name::cloopcancelDispatcher; this->cancel = &Name::cloopcancelDispatcher;
this->finish = &Name::cloopfinishDispatcher; this->finish = &Name::cloopfinishDispatcher;
this->defineStatement = &Name::cloopdefineStatementDispatcher; this->deprecatedDefineStatement = &Name::cloopdeprecatedDefineStatementDispatcher;
this->defineCursor = &Name::cloopdefineCursorDispatcher; this->defineCursor = &Name::cloopdefineCursorDispatcher;
this->defineRecordSource = &Name::cloopdefineRecordSourceDispatcher; this->defineRecordSource = &Name::cloopdefineRecordSourceDispatcher;
this->onRequestStart = &Name::clooponRequestStartDispatcher; this->onRequestStart = &Name::clooponRequestStartDispatcher;
@ -20823,6 +21112,7 @@ namespace Firebird
this->afterRecordSourceOpen = &Name::cloopafterRecordSourceOpenDispatcher; this->afterRecordSourceOpen = &Name::cloopafterRecordSourceOpenDispatcher;
this->beforeRecordSourceGetRecord = &Name::cloopbeforeRecordSourceGetRecordDispatcher; this->beforeRecordSourceGetRecord = &Name::cloopbeforeRecordSourceGetRecordDispatcher;
this->afterRecordSourceGetRecord = &Name::cloopafterRecordSourceGetRecordDispatcher; this->afterRecordSourceGetRecord = &Name::cloopafterRecordSourceGetRecordDispatcher;
this->defineStatement2 = &Name::cloopdefineStatement2Dispatcher;
} }
} vTable; } 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); StatusType status2(status);
try 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 (...) 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 static void CLOOP_CARG cloopdisposeDispatcher(IDisposable* self) CLOOP_NOEXCEPT
{ {
try try
@ -21051,7 +21355,7 @@ namespace Firebird
virtual unsigned getFlags() = 0; virtual unsigned getFlags() = 0;
virtual void cancel(StatusType* status) = 0; virtual void cancel(StatusType* status) = 0;
virtual void finish(StatusType* status, ISC_TIMESTAMP_TZ timestamp) = 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 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 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; 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 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 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 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> template <typename Name, typename StatusType, typename Base>

View File

@ -74,8 +74,10 @@
#define blr_timestamp_tz (unsigned char)29 #define blr_timestamp_tz (unsigned char)29
#define blr_ex_time_tz (unsigned char)30 #define blr_ex_time_tz (unsigned char)30
#define blr_ex_timestamp_tz (unsigned char)31 #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_type_of (unsigned char)0
#define blr_domain_full (unsigned char)1 #define blr_domain_full (unsigned char)1
@ -96,6 +98,8 @@
#define blr_exception_msg (unsigned char)6 #define blr_exception_msg (unsigned char)6
#define blr_exception_params (unsigned char)7 #define blr_exception_params (unsigned char)7
#define blr_sql_state (unsigned char)8 #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_version4 (unsigned char)4
#define blr_version5 (unsigned char)5 #define blr_version5 (unsigned char)5
@ -257,6 +261,7 @@
#define blr_relation2 (unsigned char)146 #define blr_relation2 (unsigned char)146
#define blr_rid2 (unsigned char)147 #define blr_rid2 (unsigned char)147
#define blr_relation3 (unsigned char)148
// unused codes: 148..149 // unused codes: 148..149
@ -470,10 +475,11 @@
// FB 6.0 specific BLR // FB 6.0 specific BLR
#define blr_invoke_function (unsigned char) 224 #define blr_invoke_function (unsigned char) 224
#define blr_invoke_function_type (unsigned char) 1 #define blr_invoke_function_id (unsigned char) 1
#define blr_invoke_function_type_standalone (unsigned char) 1 #define blr_invoke_function_id_schema (unsigned char) 1
#define blr_invoke_function_type_packaged (unsigned char) 2 #define blr_invoke_function_id_package (unsigned char) 2
#define blr_invoke_function_type_sub (unsigned char) 3 #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_arg_names (unsigned char) 2
#define blr_invoke_function_args (unsigned char) 3 #define blr_invoke_function_args (unsigned char) 3
@ -481,10 +487,11 @@
#define blr_select_procedure (unsigned char) 226 #define blr_select_procedure (unsigned char) 226
// subcodes of blr_invoke_procedure and blr_select_procedure // subcodes of blr_invoke_procedure and blr_select_procedure
#define blr_invsel_procedure_type (unsigned char) 1 #define blr_invsel_procedure_id (unsigned char) 1
#define blr_invsel_procedure_type_standalone (unsigned char) 1 #define blr_invsel_procedure_id_schema (unsigned char) 1
#define blr_invsel_procedure_type_packaged (unsigned char) 2 #define blr_invsel_procedure_id_package (unsigned char) 2
#define blr_invsel_procedure_type_sub (unsigned char) 3 #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_arg_names (unsigned char) 2
#define blr_invsel_procedure_in_args (unsigned char) 3 #define blr_invsel_procedure_in_args (unsigned char) 3
#define blr_invsel_procedure_out_arg_names (unsigned char) 4 #define blr_invsel_procedure_out_arg_names (unsigned char) 4
@ -498,4 +505,12 @@
#define blr_cast_format (unsigned char) 228 #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 #endif // FIREBIRD_IMPL_BLR_H

View File

@ -133,6 +133,9 @@
#define isc_dpb_parallel_workers 100 #define isc_dpb_parallel_workers 100
#define isc_dpb_worker_attach 101 #define isc_dpb_worker_attach 101
#define isc_dpb_owner 102 #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_crypt 18
#define isc_spb_bkp_include_data 19 #define isc_spb_bkp_include_data 19
#define isc_spb_bkp_parallel_workers 21 #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_checksums 0x01
#define isc_spb_bkp_ignore_limbo 0x02 #define isc_spb_bkp_ignore_limbo 0x02
#define isc_spb_bkp_metadata_only 0x04 #define isc_spb_bkp_metadata_only 0x04
@ -552,6 +557,8 @@
#define isc_spb_res_access_mode 12 #define isc_spb_res_access_mode 12
#define isc_spb_res_fix_fss_data 13 #define isc_spb_res_fix_fss_data 13
#define isc_spb_res_fix_fss_metadata 14 #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_keyholder isc_spb_bkp_keyholder
#define isc_spb_res_keyname isc_spb_bkp_keyname #define isc_spb_res_keyname isc_spb_bkp_keyname
#define isc_spb_res_crypt isc_spb_bkp_crypt #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_incl 3 // regexp of indices to validate
#define isc_spb_val_idx_excl 4 // regexp of indices to NOT 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_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 * * Parameters for isc_spb_res_access_mode *
@ -686,6 +695,7 @@
#define isc_sdl_do2 34 #define isc_sdl_do2 34
#define isc_sdl_do1 35 #define isc_sdl_do1 35
#define isc_sdl_element 36 #define isc_sdl_element 36
#define isc_sdl_schema 37
/********************************************/ /********************************************/
/* International text interpretation values */ /* 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_stmt_blob_align 30
#define isc_info_sql_exec_path_blr_bytes 31 #define isc_info_sql_exec_path_blr_bytes 31
#define isc_info_sql_exec_path_blr_text 32 #define isc_info_sql_exec_path_blr_text 32
#define isc_info_sql_relation_schema 33
/*********************************/ /*********************************/
/* SQL information return values */ /* 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, 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, 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, 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, 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, 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") 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, 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, 312, dyn_dup_collation, "Collation @1 already exists")
FB_IMPL_MSG_SYMBOL(DYN, 313, dyn_dup_package, "Package @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_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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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") 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, 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, 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, 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, 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, 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") 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, 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, 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, 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, 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, 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") 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, 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, 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, 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, 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, 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") 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, 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, 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, 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, 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, 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, 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_getMessageLengthPtr = function(this: IMessageMetadata; status: IStatus): Cardinal; cdecl;
IMessageMetadata_getAlignmentPtr = 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_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_setTypePtr = procedure(this: IMetadataBuilder; status: IStatus; index: Cardinal; type_: Cardinal); cdecl;
IMetadataBuilder_setSubTypePtr = procedure(this: IMetadataBuilder; status: IStatus; index: Cardinal; subType: Integer); 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; 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_setRelationPtr = procedure(this: IMetadataBuilder; status: IStatus; index: Cardinal; relation: PAnsiChar); cdecl;
IMetadataBuilder_setOwnerPtr = procedure(this: IMetadataBuilder; status: IStatus; index: Cardinal; owner: 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_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_fetchNextPtr = function(this: IResultSet; status: IStatus; message: Pointer): Integer; cdecl;
IResultSet_fetchPriorPtr = 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; 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_getTriggerMetadataPtr = function(this: IRoutineMetadata; status: IStatus): IMessageMetadata; cdecl;
IRoutineMetadata_getTriggerTablePtr = function(this: IRoutineMetadata; status: IStatus): PAnsiChar; cdecl; IRoutineMetadata_getTriggerTablePtr = function(this: IRoutineMetadata; status: IStatus): PAnsiChar; cdecl;
IRoutineMetadata_getTriggerTypePtr = function(this: IRoutineMetadata; status: IStatus): Cardinal; 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_openPtr = procedure(this: IExternalEngine; status: IStatus; context: IExternalContext; charSet: PAnsiChar; charSetSize: Cardinal); cdecl;
IExternalEngine_openAttachmentPtr = procedure(this: IExternalEngine; status: IStatus; context: IExternalContext); cdecl; IExternalEngine_openAttachmentPtr = procedure(this: IExternalEngine; status: IStatus; context: IExternalContext); cdecl;
IExternalEngine_closeAttachmentPtr = 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_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_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_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; IOffsetsCallback_setOffsetPtr = procedure(this: IOffsetsCallback; status: IStatus; index: Cardinal; offset: Cardinal; nullOffset: Cardinal); cdecl;
IXpbBuilder_clearPtr = procedure(this: IXpbBuilder; status: IStatus); cdecl; IXpbBuilder_clearPtr = procedure(this: IXpbBuilder; status: IStatus); cdecl;
IXpbBuilder_removeCurrentPtr = 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_startSavepointPtr = procedure(this: IReplicatedTransaction; status: IStatus); cdecl;
IReplicatedTransaction_releaseSavepointPtr = procedure(this: IReplicatedTransaction; status: IStatus); cdecl; IReplicatedTransaction_releaseSavepointPtr = procedure(this: IReplicatedTransaction; status: IStatus); cdecl;
IReplicatedTransaction_rollbackSavepointPtr = 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_deprecatedInsertRecordPtr = 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_deprecatedUpdateRecordPtr = 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_deprecatedDeleteRecordPtr = procedure(this: IReplicatedTransaction; status: IStatus; name: PAnsiChar; record_: IReplicatedRecord); cdecl;
IReplicatedTransaction_executeSqlPtr = procedure(this: IReplicatedTransaction; status: IStatus; sql: PAnsiChar); cdecl; IReplicatedTransaction_deprecatedExecuteSqlPtr = procedure(this: IReplicatedTransaction; status: IStatus; sql: PAnsiChar); cdecl;
IReplicatedTransaction_executeSqlIntlPtr = procedure(this: IReplicatedTransaction; status: IStatus; charset: Cardinal; 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_initPtr = function(this: IReplicatedSession; status: IStatus; attachment: IAttachment): Boolean; cdecl;
IReplicatedSession_startTransactionPtr = function(this: IReplicatedSession; status: IStatus; transaction: ITransaction; number: Int64): IReplicatedTransaction; 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_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_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_startSessionPtr = function(this: IProfilerPlugin; status: IStatus; description: PAnsiChar; options: PAnsiChar; timestamp: ISC_TIMESTAMP_TZ): IProfilerSession; cdecl;
IProfilerPlugin_flushPtr = procedure(this: IProfilerPlugin; status: IStatus); cdecl; IProfilerPlugin_flushPtr = procedure(this: IProfilerPlugin; status: IStatus); cdecl;
@ -739,7 +748,7 @@ type
IProfilerSession_getFlagsPtr = function(this: IProfilerSession): Cardinal; cdecl; IProfilerSession_getFlagsPtr = function(this: IProfilerSession): Cardinal; cdecl;
IProfilerSession_cancelPtr = procedure(this: IProfilerSession; status: IStatus); cdecl; IProfilerSession_cancelPtr = procedure(this: IProfilerSession; status: IStatus); cdecl;
IProfilerSession_finishPtr = procedure(this: IProfilerSession; status: IStatus; timestamp: ISC_TIMESTAMP_TZ); 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_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_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; 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_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_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_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; IProfilerStats_getElapsedTicksPtr = function(this: IProfilerStats): QWord; cdecl;
VersionedVTable = class VersionedVTable = class
@ -1347,10 +1357,11 @@ type
getMessageLength: IMessageMetadata_getMessageLengthPtr; getMessageLength: IMessageMetadata_getMessageLengthPtr;
getAlignment: IMessageMetadata_getAlignmentPtr; getAlignment: IMessageMetadata_getAlignmentPtr;
getAlignedLength: IMessageMetadata_getAlignedLengthPtr; getAlignedLength: IMessageMetadata_getAlignedLengthPtr;
getSchema: IMessageMetadata_getSchemaPtr;
end; end;
IMessageMetadata = class(IReferenceCounted) IMessageMetadata = class(IReferenceCounted)
const VERSION = 4; const VERSION = 5;
function getCount(status: IStatus): Cardinal; function getCount(status: IStatus): Cardinal;
function getField(status: IStatus; index: Cardinal): PAnsiChar; function getField(status: IStatus; index: Cardinal): PAnsiChar;
@ -1369,6 +1380,7 @@ type
function getMessageLength(status: IStatus): Cardinal; function getMessageLength(status: IStatus): Cardinal;
function getAlignment(status: IStatus): Cardinal; function getAlignment(status: IStatus): Cardinal;
function getAlignedLength(status: IStatus): Cardinal; function getAlignedLength(status: IStatus): Cardinal;
function getSchema(status: IStatus; index: Cardinal): PAnsiChar;
end; end;
IMessageMetadataImpl = class(IMessageMetadata) IMessageMetadataImpl = class(IMessageMetadata)
@ -1393,6 +1405,7 @@ type
function getMessageLength(status: IStatus): Cardinal; virtual; abstract; function getMessageLength(status: IStatus): Cardinal; virtual; abstract;
function getAlignment(status: IStatus): Cardinal; virtual; abstract; function getAlignment(status: IStatus): Cardinal; virtual; abstract;
function getAlignedLength(status: IStatus): Cardinal; virtual; abstract; function getAlignedLength(status: IStatus): Cardinal; virtual; abstract;
function getSchema(status: IStatus; index: Cardinal): PAnsiChar; virtual; abstract;
end; end;
MetadataBuilderVTable = class(ReferenceCountedVTable) MetadataBuilderVTable = class(ReferenceCountedVTable)
@ -1410,10 +1423,11 @@ type
setRelation: IMetadataBuilder_setRelationPtr; setRelation: IMetadataBuilder_setRelationPtr;
setOwner: IMetadataBuilder_setOwnerPtr; setOwner: IMetadataBuilder_setOwnerPtr;
setAlias: IMetadataBuilder_setAliasPtr; setAlias: IMetadataBuilder_setAliasPtr;
setSchema: IMetadataBuilder_setSchemaPtr;
end; end;
IMetadataBuilder = class(IReferenceCounted) IMetadataBuilder = class(IReferenceCounted)
const VERSION = 4; const VERSION = 5;
procedure setType(status: IStatus; index: Cardinal; type_: Cardinal); procedure setType(status: IStatus; index: Cardinal; type_: Cardinal);
procedure setSubType(status: IStatus; index: Cardinal; subType: Integer); procedure setSubType(status: IStatus; index: Cardinal; subType: Integer);
@ -1429,6 +1443,7 @@ type
procedure setRelation(status: IStatus; index: Cardinal; relation: PAnsiChar); procedure setRelation(status: IStatus; index: Cardinal; relation: PAnsiChar);
procedure setOwner(status: IStatus; index: Cardinal; owner: PAnsiChar); procedure setOwner(status: IStatus; index: Cardinal; owner: PAnsiChar);
procedure setAlias(status: IStatus; index: Cardinal; alias: PAnsiChar); procedure setAlias(status: IStatus; index: Cardinal; alias: PAnsiChar);
procedure setSchema(status: IStatus; index: Cardinal; schema: PAnsiChar);
end; end;
IMetadataBuilderImpl = class(IMetadataBuilder) IMetadataBuilderImpl = class(IMetadataBuilder)
@ -1450,6 +1465,7 @@ type
procedure setRelation(status: IStatus; index: Cardinal; relation: PAnsiChar); virtual; abstract; procedure setRelation(status: IStatus; index: Cardinal; relation: PAnsiChar); virtual; abstract;
procedure setOwner(status: IStatus; index: Cardinal; owner: PAnsiChar); virtual; abstract; procedure setOwner(status: IStatus; index: Cardinal; owner: PAnsiChar); virtual; abstract;
procedure setAlias(status: IStatus; index: Cardinal; alias: PAnsiChar); virtual; abstract; procedure setAlias(status: IStatus; index: Cardinal; alias: PAnsiChar); virtual; abstract;
procedure setSchema(status: IStatus; index: Cardinal; schema: PAnsiChar); virtual; abstract;
end; end;
ResultSetVTable = class(ReferenceCountedVTable) ResultSetVTable = class(ReferenceCountedVTable)
@ -2618,10 +2634,11 @@ type
getTriggerMetadata: IRoutineMetadata_getTriggerMetadataPtr; getTriggerMetadata: IRoutineMetadata_getTriggerMetadataPtr;
getTriggerTable: IRoutineMetadata_getTriggerTablePtr; getTriggerTable: IRoutineMetadata_getTriggerTablePtr;
getTriggerType: IRoutineMetadata_getTriggerTypePtr; getTriggerType: IRoutineMetadata_getTriggerTypePtr;
getSchema: IRoutineMetadata_getSchemaPtr;
end; end;
IRoutineMetadata = class(IVersioned) IRoutineMetadata = class(IVersioned)
const VERSION = 2; const VERSION = 3;
function getPackage(status: IStatus): PAnsiChar; function getPackage(status: IStatus): PAnsiChar;
function getName(status: IStatus): PAnsiChar; function getName(status: IStatus): PAnsiChar;
@ -2632,6 +2649,7 @@ type
function getTriggerMetadata(status: IStatus): IMessageMetadata; function getTriggerMetadata(status: IStatus): IMessageMetadata;
function getTriggerTable(status: IStatus): PAnsiChar; function getTriggerTable(status: IStatus): PAnsiChar;
function getTriggerType(status: IStatus): Cardinal; function getTriggerType(status: IStatus): Cardinal;
function getSchema(status: IStatus): PAnsiChar;
end; end;
IRoutineMetadataImpl = class(IRoutineMetadata) IRoutineMetadataImpl = class(IRoutineMetadata)
@ -2646,6 +2664,7 @@ type
function getTriggerMetadata(status: IStatus): IMessageMetadata; virtual; abstract; function getTriggerMetadata(status: IStatus): IMessageMetadata; virtual; abstract;
function getTriggerTable(status: IStatus): PAnsiChar; virtual; abstract; function getTriggerTable(status: IStatus): PAnsiChar; virtual; abstract;
function getTriggerType(status: IStatus): Cardinal; virtual; abstract; function getTriggerType(status: IStatus): Cardinal; virtual; abstract;
function getSchema(status: IStatus): PAnsiChar; virtual; abstract;
end; end;
ExternalEngineVTable = class(PluginBaseVTable) ExternalEngineVTable = class(PluginBaseVTable)
@ -2759,10 +2778,11 @@ type
getInt128: IUtil_getInt128Ptr; getInt128: IUtil_getInt128Ptr;
decodeTimeTzEx: IUtil_decodeTimeTzExPtr; decodeTimeTzEx: IUtil_decodeTimeTzExPtr;
decodeTimeStampTzEx: IUtil_decodeTimeStampTzExPtr; decodeTimeStampTzEx: IUtil_decodeTimeStampTzExPtr;
executeCreateDatabase2: IUtil_executeCreateDatabase2Ptr;
end; end;
IUtil = class(IVersioned) IUtil = class(IVersioned)
const VERSION = 4; const VERSION = 5;
procedure getFbVersion(status: IStatus; att: IAttachment; callback: IVersionCallback); procedure getFbVersion(status: IStatus; att: IAttachment; callback: IVersionCallback);
procedure loadBlob(status: IStatus; blobId: ISC_QUADPtr; att: IAttachment; tra: ITransaction; file_: PAnsiChar; txt: Boolean); 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; 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 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); 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; end;
IUtilImpl = class(IUtil) IUtilImpl = class(IUtil)
@ -2813,6 +2834,7 @@ type
function getInt128(status: IStatus): IInt128; virtual; abstract; 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 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; 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; end;
OffsetsCallbackVTable = class(VersionedVTable) OffsetsCallbackVTable = class(VersionedVTable)
@ -3777,15 +3799,19 @@ type
startSavepoint: IReplicatedTransaction_startSavepointPtr; startSavepoint: IReplicatedTransaction_startSavepointPtr;
releaseSavepoint: IReplicatedTransaction_releaseSavepointPtr; releaseSavepoint: IReplicatedTransaction_releaseSavepointPtr;
rollbackSavepoint: IReplicatedTransaction_rollbackSavepointPtr; rollbackSavepoint: IReplicatedTransaction_rollbackSavepointPtr;
insertRecord: IReplicatedTransaction_insertRecordPtr; deprecatedInsertRecord: IReplicatedTransaction_deprecatedInsertRecordPtr;
updateRecord: IReplicatedTransaction_updateRecordPtr; deprecatedUpdateRecord: IReplicatedTransaction_deprecatedUpdateRecordPtr;
deleteRecord: IReplicatedTransaction_deleteRecordPtr; deprecatedDeleteRecord: IReplicatedTransaction_deprecatedDeleteRecordPtr;
executeSql: IReplicatedTransaction_executeSqlPtr; deprecatedExecuteSql: IReplicatedTransaction_deprecatedExecuteSqlPtr;
executeSqlIntl: IReplicatedTransaction_executeSqlIntlPtr; deprecatedExecuteSqlIntl: IReplicatedTransaction_deprecatedExecuteSqlIntlPtr;
insertRecord2: IReplicatedTransaction_insertRecord2Ptr;
updateRecord2: IReplicatedTransaction_updateRecord2Ptr;
deleteRecord2: IReplicatedTransaction_deleteRecord2Ptr;
executeSqlIntl2: IReplicatedTransaction_executeSqlIntl2Ptr;
end; end;
IReplicatedTransaction = class(IDisposable) IReplicatedTransaction = class(IDisposable)
const VERSION = 3; const VERSION = 4;
procedure prepare(status: IStatus); procedure prepare(status: IStatus);
procedure commit(status: IStatus); procedure commit(status: IStatus);
@ -3793,11 +3819,15 @@ type
procedure startSavepoint(status: IStatus); procedure startSavepoint(status: IStatus);
procedure releaseSavepoint(status: IStatus); procedure releaseSavepoint(status: IStatus);
procedure rollbackSavepoint(status: IStatus); procedure rollbackSavepoint(status: IStatus);
procedure insertRecord(status: IStatus; name: PAnsiChar; record_: IReplicatedRecord); procedure deprecatedInsertRecord(status: IStatus; name: PAnsiChar; record_: IReplicatedRecord);
procedure updateRecord(status: IStatus; name: PAnsiChar; orgRecord: IReplicatedRecord; newRecord: IReplicatedRecord); procedure deprecatedUpdateRecord(status: IStatus; name: PAnsiChar; orgRecord: IReplicatedRecord; newRecord: IReplicatedRecord);
procedure deleteRecord(status: IStatus; name: PAnsiChar; record_: IReplicatedRecord); procedure deprecatedDeleteRecord(status: IStatus; name: PAnsiChar; record_: IReplicatedRecord);
procedure executeSql(status: IStatus; sql: PAnsiChar); procedure deprecatedExecuteSql(status: IStatus; sql: PAnsiChar);
procedure executeSqlIntl(status: IStatus; charset: Cardinal; 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; end;
IReplicatedTransactionImpl = class(IReplicatedTransaction) IReplicatedTransactionImpl = class(IReplicatedTransaction)
@ -3810,27 +3840,33 @@ type
procedure startSavepoint(status: IStatus); virtual; abstract; procedure startSavepoint(status: IStatus); virtual; abstract;
procedure releaseSavepoint(status: IStatus); virtual; abstract; procedure releaseSavepoint(status: IStatus); virtual; abstract;
procedure rollbackSavepoint(status: IStatus); virtual; abstract; procedure rollbackSavepoint(status: IStatus); virtual; abstract;
procedure insertRecord(status: IStatus; name: PAnsiChar; record_: IReplicatedRecord); virtual; abstract; procedure deprecatedInsertRecord(status: IStatus; name: PAnsiChar; record_: IReplicatedRecord); virtual; abstract;
procedure updateRecord(status: IStatus; name: PAnsiChar; orgRecord: IReplicatedRecord; newRecord: IReplicatedRecord); virtual; abstract; procedure deprecatedUpdateRecord(status: IStatus; name: PAnsiChar; orgRecord: IReplicatedRecord; newRecord: IReplicatedRecord); virtual; abstract;
procedure deleteRecord(status: IStatus; name: PAnsiChar; record_: IReplicatedRecord); virtual; abstract; procedure deprecatedDeleteRecord(status: IStatus; name: PAnsiChar; record_: IReplicatedRecord); virtual; abstract;
procedure executeSql(status: IStatus; sql: PAnsiChar); virtual; abstract; procedure deprecatedExecuteSql(status: IStatus; sql: PAnsiChar); virtual; abstract;
procedure executeSqlIntl(status: IStatus; charset: Cardinal; 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; end;
ReplicatedSessionVTable = class(PluginBaseVTable) ReplicatedSessionVTable = class(PluginBaseVTable)
init: IReplicatedSession_initPtr; init: IReplicatedSession_initPtr;
startTransaction: IReplicatedSession_startTransactionPtr; startTransaction: IReplicatedSession_startTransactionPtr;
cleanupTransaction: IReplicatedSession_cleanupTransactionPtr; cleanupTransaction: IReplicatedSession_cleanupTransactionPtr;
setSequence: IReplicatedSession_setSequencePtr; deprecatedSetSequence: IReplicatedSession_deprecatedSetSequencePtr;
setSequence2: IReplicatedSession_setSequence2Ptr;
end; end;
IReplicatedSession = class(IPluginBase) IReplicatedSession = class(IPluginBase)
const VERSION = 4; const VERSION = 5;
function init(status: IStatus; attachment: IAttachment): Boolean; function init(status: IStatus; attachment: IAttachment): Boolean;
function startTransaction(status: IStatus; transaction: ITransaction; number: Int64): IReplicatedTransaction; function startTransaction(status: IStatus; transaction: ITransaction; number: Int64): IReplicatedTransaction;
procedure cleanupTransaction(status: IStatus; number: Int64); 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; end;
IReplicatedSessionImpl = class(IReplicatedSession) IReplicatedSessionImpl = class(IReplicatedSession)
@ -3843,7 +3879,8 @@ type
function init(status: IStatus; attachment: IAttachment): Boolean; virtual; abstract; function init(status: IStatus; attachment: IAttachment): Boolean; virtual; abstract;
function startTransaction(status: IStatus; transaction: ITransaction; number: Int64): IReplicatedTransaction; virtual; abstract; function startTransaction(status: IStatus; transaction: ITransaction; number: Int64): IReplicatedTransaction; virtual; abstract;
procedure cleanupTransaction(status: IStatus; number: Int64); 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; end;
ProfilerPluginVTable = class(PluginBaseVTable) ProfilerPluginVTable = class(PluginBaseVTable)
@ -3877,7 +3914,7 @@ type
getFlags: IProfilerSession_getFlagsPtr; getFlags: IProfilerSession_getFlagsPtr;
cancel: IProfilerSession_cancelPtr; cancel: IProfilerSession_cancelPtr;
finish: IProfilerSession_finishPtr; finish: IProfilerSession_finishPtr;
defineStatement: IProfilerSession_defineStatementPtr; deprecatedDefineStatement: IProfilerSession_deprecatedDefineStatementPtr;
defineCursor: IProfilerSession_defineCursorPtr; defineCursor: IProfilerSession_defineCursorPtr;
defineRecordSource: IProfilerSession_defineRecordSourcePtr; defineRecordSource: IProfilerSession_defineRecordSourcePtr;
onRequestStart: IProfilerSession_onRequestStartPtr; onRequestStart: IProfilerSession_onRequestStartPtr;
@ -3888,10 +3925,11 @@ type
afterRecordSourceOpen: IProfilerSession_afterRecordSourceOpenPtr; afterRecordSourceOpen: IProfilerSession_afterRecordSourceOpenPtr;
beforeRecordSourceGetRecord: IProfilerSession_beforeRecordSourceGetRecordPtr; beforeRecordSourceGetRecord: IProfilerSession_beforeRecordSourceGetRecordPtr;
afterRecordSourceGetRecord: IProfilerSession_afterRecordSourceGetRecordPtr; afterRecordSourceGetRecord: IProfilerSession_afterRecordSourceGetRecordPtr;
defineStatement2: IProfilerSession_defineStatement2Ptr;
end; end;
IProfilerSession = class(IDisposable) IProfilerSession = class(IDisposable)
const VERSION = 3; const VERSION = 4;
const FLAG_BEFORE_EVENTS = Cardinal($1); const FLAG_BEFORE_EVENTS = Cardinal($1);
const FLAG_AFTER_EVENTS = Cardinal($2); const FLAG_AFTER_EVENTS = Cardinal($2);
@ -3899,7 +3937,7 @@ type
function getFlags(): Cardinal; function getFlags(): Cardinal;
procedure cancel(status: IStatus); procedure cancel(status: IStatus);
procedure finish(status: IStatus; timestamp: ISC_TIMESTAMP_TZ); 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 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 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); 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 afterRecordSourceOpen(statementId: Int64; requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal; stats: IProfilerStats);
procedure beforeRecordSourceGetRecord(statementId: Int64; requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal); procedure beforeRecordSourceGetRecord(statementId: Int64; requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal);
procedure afterRecordSourceGetRecord(statementId: Int64; requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal; stats: IProfilerStats); 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; end;
IProfilerSessionImpl = class(IProfilerSession) IProfilerSessionImpl = class(IProfilerSession)
@ -3920,7 +3959,7 @@ type
function getFlags(): Cardinal; virtual; abstract; function getFlags(): Cardinal; virtual; abstract;
procedure cancel(status: IStatus); virtual; abstract; procedure cancel(status: IStatus); virtual; abstract;
procedure finish(status: IStatus; timestamp: ISC_TIMESTAMP_TZ); 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 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 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; 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 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 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 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; end;
ProfilerStatsVTable = class(VersionedVTable) ProfilerStatsVTable = class(VersionedVTable)
@ -4057,6 +4097,9 @@ const
isc_dpb_parallel_workers = byte(100); isc_dpb_parallel_workers = byte(100);
isc_dpb_worker_attach = byte(101); isc_dpb_worker_attach = byte(101);
isc_dpb_owner = byte(102); 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_address = byte(1);
isc_dpb_addr_protocol = byte(1); isc_dpb_addr_protocol = byte(1);
isc_dpb_addr_endpoint = byte(2); isc_dpb_addr_endpoint = byte(2);
@ -4215,6 +4258,8 @@ const
isc_spb_bkp_crypt = byte(18); isc_spb_bkp_crypt = byte(18);
isc_spb_bkp_include_data = byte(19); isc_spb_bkp_include_data = byte(19);
isc_spb_bkp_parallel_workers = byte(21); 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_checksums = $01;
isc_spb_bkp_ignore_limbo = $02; isc_spb_bkp_ignore_limbo = $02;
isc_spb_bkp_metadata_only = $04; isc_spb_bkp_metadata_only = $04;
@ -4311,6 +4356,8 @@ const
isc_spb_val_idx_incl = byte(3); isc_spb_val_idx_incl = byte(3);
isc_spb_val_idx_excl = byte(4); isc_spb_val_idx_excl = byte(4);
isc_spb_val_lock_timeout = byte(5); 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_att = byte(5);
isc_spb_num_db = byte(6); isc_spb_num_db = byte(6);
isc_spb_sts_table = byte(64); isc_spb_sts_table = byte(64);
@ -4358,6 +4405,7 @@ const
isc_sdl_do2 = byte(34); isc_sdl_do2 = byte(34);
isc_sdl_do1 = byte(35); isc_sdl_do1 = byte(35);
isc_sdl_element = byte(36); isc_sdl_element = byte(36);
isc_sdl_schema = byte(37);
isc_blob_untyped = byte(0); isc_blob_untyped = byte(0);
isc_blob_text = byte(1); isc_blob_text = byte(1);
isc_blob_blr = byte(2); isc_blob_blr = byte(2);
@ -4727,6 +4775,7 @@ const
isc_info_sql_stmt_blob_align = byte(30); isc_info_sql_stmt_blob_align = byte(30);
isc_info_sql_exec_path_blr_bytes = byte(31); isc_info_sql_exec_path_blr_bytes = byte(31);
isc_info_sql_exec_path_blr_text = byte(32); 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_select = byte(1);
isc_info_sql_stmt_insert = byte(2); isc_info_sql_stmt_insert = byte(2);
isc_info_sql_stmt_update = byte(3); isc_info_sql_stmt_update = byte(3);
@ -5741,6 +5790,8 @@ const
isc_only_one_pattern_can_be_used = 335545305; isc_only_one_pattern_can_be_used = 335545305;
isc_can_not_use_same_pattern_twice = 335545306; isc_can_not_use_same_pattern_twice = 335545306;
isc_sysf_invalid_gen_uuid_version = 335545307; isc_sysf_invalid_gen_uuid_version = 335545307;
isc_invalid_name = 335545308;
isc_invalid_unqualified_name_list = 335545309;
isc_gfix_db_name = 335740929; isc_gfix_db_name = 335740929;
isc_gfix_invalid_sw = 335740930; isc_gfix_invalid_sw = 335740930;
isc_gfix_incmp_sw = 335740932; isc_gfix_incmp_sw = 335740932;
@ -5897,6 +5948,13 @@ const
isc_dyn_exc_not_exist = 336068915; isc_dyn_exc_not_exist = 336068915;
isc_dyn_gen_not_exist = 336068916; isc_dyn_gen_not_exist = 336068916;
isc_dyn_fld_not_exist = 336068917; 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_unknown_switch = 336330753;
isc_gbak_page_size_missing = 336330754; isc_gbak_page_size_missing = 336330754;
isc_gbak_page_size_toobig = 336330755; isc_gbak_page_size_toobig = 336330755;
@ -6125,6 +6183,11 @@ const
isc_dsql_string_char_length = 336397332; isc_dsql_string_char_length = 336397332;
isc_dsql_max_nesting = 336397333; isc_dsql_max_nesting = 336397333;
isc_dsql_recreate_user_failed = 336397334; 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_cant_open_db = 336723983;
isc_gsec_switches_error = 336723984; isc_gsec_switches_error = 336723984;
isc_gsec_no_op_spec = 336723985; isc_gsec_no_op_spec = 336723985;
@ -6907,6 +6970,18 @@ begin
FbException.checkException(status); FbException.checkException(status);
end; 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); procedure IMetadataBuilder.setType(status: IStatus; index: Cardinal; type_: Cardinal);
begin begin
MetadataBuilderVTable(vTable).setType(Self, status, index, type_); MetadataBuilderVTable(vTable).setType(Self, status, index, type_);
@ -7011,6 +7086,17 @@ begin
FbException.checkException(status); FbException.checkException(status);
end; 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; function IResultSet.fetchNext(status: IStatus; message: Pointer): Integer;
begin begin
Result := ResultSetVTable(vTable).fetchNext(Self, status, message); Result := ResultSetVTable(vTable).fetchNext(Self, status, message);
@ -8371,6 +8457,18 @@ begin
FbException.checkException(status); FbException.checkException(status);
end; 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); procedure IExternalEngine.open(status: IStatus; context: IExternalContext; charSet: PAnsiChar; charSetSize: Cardinal);
begin begin
ExternalEngineVTable(vTable).open(Self, status, context, charSet, charSetSize); ExternalEngineVTable(vTable).open(Self, status, context, charSet, charSetSize);
@ -8604,6 +8702,18 @@ begin
FbException.checkException(status); FbException.checkException(status);
end; 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); procedure IOffsetsCallback.setOffset(status: IStatus; index: Cardinal; offset: Cardinal; nullOffset: Cardinal);
begin begin
OffsetsCallbackVTable(vTable).setOffset(Self, status, index, offset, nullOffset); OffsetsCallbackVTable(vTable).setOffset(Self, status, index, offset, nullOffset);
@ -9556,33 +9666,77 @@ begin
FbException.checkException(status); FbException.checkException(status);
end; end;
procedure IReplicatedTransaction.insertRecord(status: IStatus; name: PAnsiChar; record_: IReplicatedRecord); procedure IReplicatedTransaction.deprecatedInsertRecord(status: IStatus; name: PAnsiChar; record_: IReplicatedRecord);
begin begin
ReplicatedTransactionVTable(vTable).insertRecord(Self, status, name, record_); ReplicatedTransactionVTable(vTable).deprecatedInsertRecord(Self, status, name, record_);
FbException.checkException(status); FbException.checkException(status);
end; end;
procedure IReplicatedTransaction.updateRecord(status: IStatus; name: PAnsiChar; orgRecord: IReplicatedRecord; newRecord: IReplicatedRecord); procedure IReplicatedTransaction.deprecatedUpdateRecord(status: IStatus; name: PAnsiChar; orgRecord: IReplicatedRecord; newRecord: IReplicatedRecord);
begin begin
ReplicatedTransactionVTable(vTable).updateRecord(Self, status, name, orgRecord, newRecord); ReplicatedTransactionVTable(vTable).deprecatedUpdateRecord(Self, status, name, orgRecord, newRecord);
FbException.checkException(status); FbException.checkException(status);
end; end;
procedure IReplicatedTransaction.deleteRecord(status: IStatus; name: PAnsiChar; record_: IReplicatedRecord); procedure IReplicatedTransaction.deprecatedDeleteRecord(status: IStatus; name: PAnsiChar; record_: IReplicatedRecord);
begin begin
ReplicatedTransactionVTable(vTable).deleteRecord(Self, status, name, record_); ReplicatedTransactionVTable(vTable).deprecatedDeleteRecord(Self, status, name, record_);
FbException.checkException(status); FbException.checkException(status);
end; end;
procedure IReplicatedTransaction.executeSql(status: IStatus; sql: PAnsiChar); procedure IReplicatedTransaction.deprecatedExecuteSql(status: IStatus; sql: PAnsiChar);
begin begin
ReplicatedTransactionVTable(vTable).executeSql(Self, status, sql); ReplicatedTransactionVTable(vTable).deprecatedExecuteSql(Self, status, sql);
FbException.checkException(status); FbException.checkException(status);
end; end;
procedure IReplicatedTransaction.executeSqlIntl(status: IStatus; charset: Cardinal; sql: PAnsiChar); procedure IReplicatedTransaction.deprecatedExecuteSqlIntl(status: IStatus; charset: Cardinal; sql: PAnsiChar);
begin 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); FbException.checkException(status);
end; end;
@ -9604,9 +9758,20 @@ begin
FbException.checkException(status); FbException.checkException(status);
end; end;
procedure IReplicatedSession.setSequence(status: IStatus; name: PAnsiChar; value: Int64); procedure IReplicatedSession.deprecatedSetSequence(status: IStatus; name: PAnsiChar; value: Int64);
begin 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); FbException.checkException(status);
end; end;
@ -9650,9 +9815,9 @@ begin
FbException.checkException(status); FbException.checkException(status);
end; 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 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); FbException.checkException(status);
end; end;
@ -9708,6 +9873,17 @@ begin
ProfilerSessionVTable(vTable).afterRecordSourceGetRecord(Self, statementId, requestId, cursorId, recSourceId, stats); ProfilerSessionVTable(vTable).afterRecordSourceGetRecord(Self, statementId, requestId, cursorId, recSourceId, stats);
end; 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; function IProfilerStats.getElapsedTicks(): QWord;
begin begin
Result := ProfilerStatsVTable(vTable).getElapsedTicks(Self); Result := ProfilerStatsVTable(vTable).getElapsedTicks(Self);
@ -11098,6 +11274,16 @@ begin
end end
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 var
IMessageMetadataImpl_vTable: MessageMetadataVTable; IMessageMetadataImpl_vTable: MessageMetadataVTable;
@ -11253,6 +11439,15 @@ begin
end end
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 var
IMetadataBuilderImpl_vTable: MetadataBuilderVTable; IMetadataBuilderImpl_vTable: MetadataBuilderVTable;
@ -14051,6 +14246,16 @@ begin
end end
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 var
IRoutineMetadataImpl_vTable: RoutineMetadataVTable; IRoutineMetadataImpl_vTable: RoutineMetadataVTable;
@ -14449,6 +14654,16 @@ begin
end end
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 var
IUtilImpl_vTable: UtilVTable; IUtilImpl_vTable: UtilVTable;
@ -16646,46 +16861,82 @@ begin
end end
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 begin
try try
IReplicatedTransactionImpl(this).insertRecord(status, name, record_); IReplicatedTransactionImpl(this).deprecatedInsertRecord(status, name, record_);
except except
on e: Exception do FbException.catchException(status, e); on e: Exception do FbException.catchException(status, e);
end end
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 begin
try try
IReplicatedTransactionImpl(this).updateRecord(status, name, orgRecord, newRecord); IReplicatedTransactionImpl(this).deprecatedUpdateRecord(status, name, orgRecord, newRecord);
except except
on e: Exception do FbException.catchException(status, e); on e: Exception do FbException.catchException(status, e);
end end
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 begin
try try
IReplicatedTransactionImpl(this).deleteRecord(status, name, record_); IReplicatedTransactionImpl(this).deprecatedDeleteRecord(status, name, record_);
except except
on e: Exception do FbException.catchException(status, e); on e: Exception do FbException.catchException(status, e);
end end
end; end;
procedure IReplicatedTransactionImpl_executeSqlDispatcher(this: IReplicatedTransaction; status: IStatus; sql: PAnsiChar); cdecl; procedure IReplicatedTransactionImpl_deprecatedExecuteSqlDispatcher(this: IReplicatedTransaction; status: IStatus; sql: PAnsiChar); cdecl;
begin begin
try try
IReplicatedTransactionImpl(this).executeSql(status, sql); IReplicatedTransactionImpl(this).deprecatedExecuteSql(status, sql);
except except
on e: Exception do FbException.catchException(status, e); on e: Exception do FbException.catchException(status, e);
end end
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 begin
try 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 except
on e: Exception do FbException.catchException(status, e); on e: Exception do FbException.catchException(status, e);
end end
@ -16766,10 +17017,19 @@ begin
end end
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 begin
try 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 except
on e: Exception do FbException.catchException(status, e); on e: Exception do FbException.catchException(status, e);
end end
@ -16904,10 +17164,10 @@ begin
end end
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 begin
try try
IProfilerSessionImpl(this).defineStatement(status, statementId, parentStatementId, type_, packageName, routineName, sqlText); IProfilerSessionImpl(this).deprecatedDefineStatement(status, statementId, parentStatementId, type_, packageName, routineName, sqlText);
except except
on e: Exception do FbException.catchException(status, e); on e: Exception do FbException.catchException(status, e);
end end
@ -17003,6 +17263,15 @@ begin
end end
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 var
IProfilerSessionImpl_vTable: ProfilerSessionVTable; IProfilerSessionImpl_vTable: ProfilerSessionVTable;
@ -17261,7 +17530,7 @@ initialization
ITransactionImpl_vTable.disconnect := @ITransactionImpl_disconnectDispatcher; ITransactionImpl_vTable.disconnect := @ITransactionImpl_disconnectDispatcher;
IMessageMetadataImpl_vTable := MessageMetadataVTable.create; IMessageMetadataImpl_vTable := MessageMetadataVTable.create;
IMessageMetadataImpl_vTable.version := 4; IMessageMetadataImpl_vTable.version := 5;
IMessageMetadataImpl_vTable.addRef := @IMessageMetadataImpl_addRefDispatcher; IMessageMetadataImpl_vTable.addRef := @IMessageMetadataImpl_addRefDispatcher;
IMessageMetadataImpl_vTable.release := @IMessageMetadataImpl_releaseDispatcher; IMessageMetadataImpl_vTable.release := @IMessageMetadataImpl_releaseDispatcher;
IMessageMetadataImpl_vTable.getCount := @IMessageMetadataImpl_getCountDispatcher; IMessageMetadataImpl_vTable.getCount := @IMessageMetadataImpl_getCountDispatcher;
@ -17281,9 +17550,10 @@ initialization
IMessageMetadataImpl_vTable.getMessageLength := @IMessageMetadataImpl_getMessageLengthDispatcher; IMessageMetadataImpl_vTable.getMessageLength := @IMessageMetadataImpl_getMessageLengthDispatcher;
IMessageMetadataImpl_vTable.getAlignment := @IMessageMetadataImpl_getAlignmentDispatcher; IMessageMetadataImpl_vTable.getAlignment := @IMessageMetadataImpl_getAlignmentDispatcher;
IMessageMetadataImpl_vTable.getAlignedLength := @IMessageMetadataImpl_getAlignedLengthDispatcher; IMessageMetadataImpl_vTable.getAlignedLength := @IMessageMetadataImpl_getAlignedLengthDispatcher;
IMessageMetadataImpl_vTable.getSchema := @IMessageMetadataImpl_getSchemaDispatcher;
IMetadataBuilderImpl_vTable := MetadataBuilderVTable.create; IMetadataBuilderImpl_vTable := MetadataBuilderVTable.create;
IMetadataBuilderImpl_vTable.version := 4; IMetadataBuilderImpl_vTable.version := 5;
IMetadataBuilderImpl_vTable.addRef := @IMetadataBuilderImpl_addRefDispatcher; IMetadataBuilderImpl_vTable.addRef := @IMetadataBuilderImpl_addRefDispatcher;
IMetadataBuilderImpl_vTable.release := @IMetadataBuilderImpl_releaseDispatcher; IMetadataBuilderImpl_vTable.release := @IMetadataBuilderImpl_releaseDispatcher;
IMetadataBuilderImpl_vTable.setType := @IMetadataBuilderImpl_setTypeDispatcher; IMetadataBuilderImpl_vTable.setType := @IMetadataBuilderImpl_setTypeDispatcher;
@ -17300,6 +17570,7 @@ initialization
IMetadataBuilderImpl_vTable.setRelation := @IMetadataBuilderImpl_setRelationDispatcher; IMetadataBuilderImpl_vTable.setRelation := @IMetadataBuilderImpl_setRelationDispatcher;
IMetadataBuilderImpl_vTable.setOwner := @IMetadataBuilderImpl_setOwnerDispatcher; IMetadataBuilderImpl_vTable.setOwner := @IMetadataBuilderImpl_setOwnerDispatcher;
IMetadataBuilderImpl_vTable.setAlias := @IMetadataBuilderImpl_setAliasDispatcher; IMetadataBuilderImpl_vTable.setAlias := @IMetadataBuilderImpl_setAliasDispatcher;
IMetadataBuilderImpl_vTable.setSchema := @IMetadataBuilderImpl_setSchemaDispatcher;
IResultSetImpl_vTable := ResultSetVTable.create; IResultSetImpl_vTable := ResultSetVTable.create;
IResultSetImpl_vTable.version := 5; IResultSetImpl_vTable.version := 5;
@ -17662,7 +17933,7 @@ initialization
IExternalTriggerImpl_vTable.execute := @IExternalTriggerImpl_executeDispatcher; IExternalTriggerImpl_vTable.execute := @IExternalTriggerImpl_executeDispatcher;
IRoutineMetadataImpl_vTable := RoutineMetadataVTable.create; IRoutineMetadataImpl_vTable := RoutineMetadataVTable.create;
IRoutineMetadataImpl_vTable.version := 2; IRoutineMetadataImpl_vTable.version := 3;
IRoutineMetadataImpl_vTable.getPackage := @IRoutineMetadataImpl_getPackageDispatcher; IRoutineMetadataImpl_vTable.getPackage := @IRoutineMetadataImpl_getPackageDispatcher;
IRoutineMetadataImpl_vTable.getName := @IRoutineMetadataImpl_getNameDispatcher; IRoutineMetadataImpl_vTable.getName := @IRoutineMetadataImpl_getNameDispatcher;
IRoutineMetadataImpl_vTable.getEntryPoint := @IRoutineMetadataImpl_getEntryPointDispatcher; IRoutineMetadataImpl_vTable.getEntryPoint := @IRoutineMetadataImpl_getEntryPointDispatcher;
@ -17672,6 +17943,7 @@ initialization
IRoutineMetadataImpl_vTable.getTriggerMetadata := @IRoutineMetadataImpl_getTriggerMetadataDispatcher; IRoutineMetadataImpl_vTable.getTriggerMetadata := @IRoutineMetadataImpl_getTriggerMetadataDispatcher;
IRoutineMetadataImpl_vTable.getTriggerTable := @IRoutineMetadataImpl_getTriggerTableDispatcher; IRoutineMetadataImpl_vTable.getTriggerTable := @IRoutineMetadataImpl_getTriggerTableDispatcher;
IRoutineMetadataImpl_vTable.getTriggerType := @IRoutineMetadataImpl_getTriggerTypeDispatcher; IRoutineMetadataImpl_vTable.getTriggerType := @IRoutineMetadataImpl_getTriggerTypeDispatcher;
IRoutineMetadataImpl_vTable.getSchema := @IRoutineMetadataImpl_getSchemaDispatcher;
IExternalEngineImpl_vTable := ExternalEngineVTable.create; IExternalEngineImpl_vTable := ExternalEngineVTable.create;
IExternalEngineImpl_vTable.version := 4; IExternalEngineImpl_vTable.version := 4;
@ -17702,7 +17974,7 @@ initialization
IVersionCallbackImpl_vTable.callback := @IVersionCallbackImpl_callbackDispatcher; IVersionCallbackImpl_vTable.callback := @IVersionCallbackImpl_callbackDispatcher;
IUtilImpl_vTable := UtilVTable.create; IUtilImpl_vTable := UtilVTable.create;
IUtilImpl_vTable.version := 4; IUtilImpl_vTable.version := 5;
IUtilImpl_vTable.getFbVersion := @IUtilImpl_getFbVersionDispatcher; IUtilImpl_vTable.getFbVersion := @IUtilImpl_getFbVersionDispatcher;
IUtilImpl_vTable.loadBlob := @IUtilImpl_loadBlobDispatcher; IUtilImpl_vTable.loadBlob := @IUtilImpl_loadBlobDispatcher;
IUtilImpl_vTable.dumpBlob := @IUtilImpl_dumpBlobDispatcher; IUtilImpl_vTable.dumpBlob := @IUtilImpl_dumpBlobDispatcher;
@ -17725,6 +17997,7 @@ initialization
IUtilImpl_vTable.getInt128 := @IUtilImpl_getInt128Dispatcher; IUtilImpl_vTable.getInt128 := @IUtilImpl_getInt128Dispatcher;
IUtilImpl_vTable.decodeTimeTzEx := @IUtilImpl_decodeTimeTzExDispatcher; IUtilImpl_vTable.decodeTimeTzEx := @IUtilImpl_decodeTimeTzExDispatcher;
IUtilImpl_vTable.decodeTimeStampTzEx := @IUtilImpl_decodeTimeStampTzExDispatcher; IUtilImpl_vTable.decodeTimeStampTzEx := @IUtilImpl_decodeTimeStampTzExDispatcher;
IUtilImpl_vTable.executeCreateDatabase2 := @IUtilImpl_executeCreateDatabase2Dispatcher;
IOffsetsCallbackImpl_vTable := OffsetsCallbackVTable.create; IOffsetsCallbackImpl_vTable := OffsetsCallbackVTable.create;
IOffsetsCallbackImpl_vTable.version := 2; IOffsetsCallbackImpl_vTable.version := 2;
@ -18009,7 +18282,7 @@ initialization
IReplicatedRecordImpl_vTable.getRawData := @IReplicatedRecordImpl_getRawDataDispatcher; IReplicatedRecordImpl_vTable.getRawData := @IReplicatedRecordImpl_getRawDataDispatcher;
IReplicatedTransactionImpl_vTable := ReplicatedTransactionVTable.create; IReplicatedTransactionImpl_vTable := ReplicatedTransactionVTable.create;
IReplicatedTransactionImpl_vTable.version := 3; IReplicatedTransactionImpl_vTable.version := 4;
IReplicatedTransactionImpl_vTable.dispose := @IReplicatedTransactionImpl_disposeDispatcher; IReplicatedTransactionImpl_vTable.dispose := @IReplicatedTransactionImpl_disposeDispatcher;
IReplicatedTransactionImpl_vTable.prepare := @IReplicatedTransactionImpl_prepareDispatcher; IReplicatedTransactionImpl_vTable.prepare := @IReplicatedTransactionImpl_prepareDispatcher;
IReplicatedTransactionImpl_vTable.commit := @IReplicatedTransactionImpl_commitDispatcher; IReplicatedTransactionImpl_vTable.commit := @IReplicatedTransactionImpl_commitDispatcher;
@ -18017,14 +18290,18 @@ initialization
IReplicatedTransactionImpl_vTable.startSavepoint := @IReplicatedTransactionImpl_startSavepointDispatcher; IReplicatedTransactionImpl_vTable.startSavepoint := @IReplicatedTransactionImpl_startSavepointDispatcher;
IReplicatedTransactionImpl_vTable.releaseSavepoint := @IReplicatedTransactionImpl_releaseSavepointDispatcher; IReplicatedTransactionImpl_vTable.releaseSavepoint := @IReplicatedTransactionImpl_releaseSavepointDispatcher;
IReplicatedTransactionImpl_vTable.rollbackSavepoint := @IReplicatedTransactionImpl_rollbackSavepointDispatcher; IReplicatedTransactionImpl_vTable.rollbackSavepoint := @IReplicatedTransactionImpl_rollbackSavepointDispatcher;
IReplicatedTransactionImpl_vTable.insertRecord := @IReplicatedTransactionImpl_insertRecordDispatcher; IReplicatedTransactionImpl_vTable.deprecatedInsertRecord := @IReplicatedTransactionImpl_deprecatedInsertRecordDispatcher;
IReplicatedTransactionImpl_vTable.updateRecord := @IReplicatedTransactionImpl_updateRecordDispatcher; IReplicatedTransactionImpl_vTable.deprecatedUpdateRecord := @IReplicatedTransactionImpl_deprecatedUpdateRecordDispatcher;
IReplicatedTransactionImpl_vTable.deleteRecord := @IReplicatedTransactionImpl_deleteRecordDispatcher; IReplicatedTransactionImpl_vTable.deprecatedDeleteRecord := @IReplicatedTransactionImpl_deprecatedDeleteRecordDispatcher;
IReplicatedTransactionImpl_vTable.executeSql := @IReplicatedTransactionImpl_executeSqlDispatcher; IReplicatedTransactionImpl_vTable.deprecatedExecuteSql := @IReplicatedTransactionImpl_deprecatedExecuteSqlDispatcher;
IReplicatedTransactionImpl_vTable.executeSqlIntl := @IReplicatedTransactionImpl_executeSqlIntlDispatcher; 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 := ReplicatedSessionVTable.create;
IReplicatedSessionImpl_vTable.version := 4; IReplicatedSessionImpl_vTable.version := 5;
IReplicatedSessionImpl_vTable.addRef := @IReplicatedSessionImpl_addRefDispatcher; IReplicatedSessionImpl_vTable.addRef := @IReplicatedSessionImpl_addRefDispatcher;
IReplicatedSessionImpl_vTable.release := @IReplicatedSessionImpl_releaseDispatcher; IReplicatedSessionImpl_vTable.release := @IReplicatedSessionImpl_releaseDispatcher;
IReplicatedSessionImpl_vTable.setOwner := @IReplicatedSessionImpl_setOwnerDispatcher; IReplicatedSessionImpl_vTable.setOwner := @IReplicatedSessionImpl_setOwnerDispatcher;
@ -18032,7 +18309,8 @@ initialization
IReplicatedSessionImpl_vTable.init := @IReplicatedSessionImpl_initDispatcher; IReplicatedSessionImpl_vTable.init := @IReplicatedSessionImpl_initDispatcher;
IReplicatedSessionImpl_vTable.startTransaction := @IReplicatedSessionImpl_startTransactionDispatcher; IReplicatedSessionImpl_vTable.startTransaction := @IReplicatedSessionImpl_startTransactionDispatcher;
IReplicatedSessionImpl_vTable.cleanupTransaction := @IReplicatedSessionImpl_cleanupTransactionDispatcher; 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 := ProfilerPluginVTable.create;
IProfilerPluginImpl_vTable.version := 4; IProfilerPluginImpl_vTable.version := 4;
@ -18045,13 +18323,13 @@ initialization
IProfilerPluginImpl_vTable.flush := @IProfilerPluginImpl_flushDispatcher; IProfilerPluginImpl_vTable.flush := @IProfilerPluginImpl_flushDispatcher;
IProfilerSessionImpl_vTable := ProfilerSessionVTable.create; IProfilerSessionImpl_vTable := ProfilerSessionVTable.create;
IProfilerSessionImpl_vTable.version := 3; IProfilerSessionImpl_vTable.version := 4;
IProfilerSessionImpl_vTable.dispose := @IProfilerSessionImpl_disposeDispatcher; IProfilerSessionImpl_vTable.dispose := @IProfilerSessionImpl_disposeDispatcher;
IProfilerSessionImpl_vTable.getId := @IProfilerSessionImpl_getIdDispatcher; IProfilerSessionImpl_vTable.getId := @IProfilerSessionImpl_getIdDispatcher;
IProfilerSessionImpl_vTable.getFlags := @IProfilerSessionImpl_getFlagsDispatcher; IProfilerSessionImpl_vTable.getFlags := @IProfilerSessionImpl_getFlagsDispatcher;
IProfilerSessionImpl_vTable.cancel := @IProfilerSessionImpl_cancelDispatcher; IProfilerSessionImpl_vTable.cancel := @IProfilerSessionImpl_cancelDispatcher;
IProfilerSessionImpl_vTable.finish := @IProfilerSessionImpl_finishDispatcher; IProfilerSessionImpl_vTable.finish := @IProfilerSessionImpl_finishDispatcher;
IProfilerSessionImpl_vTable.defineStatement := @IProfilerSessionImpl_defineStatementDispatcher; IProfilerSessionImpl_vTable.deprecatedDefineStatement := @IProfilerSessionImpl_deprecatedDefineStatementDispatcher;
IProfilerSessionImpl_vTable.defineCursor := @IProfilerSessionImpl_defineCursorDispatcher; IProfilerSessionImpl_vTable.defineCursor := @IProfilerSessionImpl_defineCursorDispatcher;
IProfilerSessionImpl_vTable.defineRecordSource := @IProfilerSessionImpl_defineRecordSourceDispatcher; IProfilerSessionImpl_vTable.defineRecordSource := @IProfilerSessionImpl_defineRecordSourceDispatcher;
IProfilerSessionImpl_vTable.onRequestStart := @IProfilerSessionImpl_onRequestStartDispatcher; IProfilerSessionImpl_vTable.onRequestStart := @IProfilerSessionImpl_onRequestStartDispatcher;
@ -18062,6 +18340,7 @@ initialization
IProfilerSessionImpl_vTable.afterRecordSourceOpen := @IProfilerSessionImpl_afterRecordSourceOpenDispatcher; IProfilerSessionImpl_vTable.afterRecordSourceOpen := @IProfilerSessionImpl_afterRecordSourceOpenDispatcher;
IProfilerSessionImpl_vTable.beforeRecordSourceGetRecord := @IProfilerSessionImpl_beforeRecordSourceGetRecordDispatcher; IProfilerSessionImpl_vTable.beforeRecordSourceGetRecord := @IProfilerSessionImpl_beforeRecordSourceGetRecordDispatcher;
IProfilerSessionImpl_vTable.afterRecordSourceGetRecord := @IProfilerSessionImpl_afterRecordSourceGetRecordDispatcher; IProfilerSessionImpl_vTable.afterRecordSourceGetRecord := @IProfilerSessionImpl_afterRecordSourceGetRecordDispatcher;
IProfilerSessionImpl_vTable.defineStatement2 := @IProfilerSessionImpl_defineStatement2Dispatcher;
IProfilerStatsImpl_vTable := ProfilerStatsVTable.create; IProfilerStatsImpl_vTable := ProfilerStatsVTable.create;
IProfilerStatsImpl_vTable.version := 2; IProfilerStatsImpl_vTable.version := 2;

View File

@ -55,7 +55,7 @@ FrontendParser::AnyNode FrontendParser::internalParse()
if (command == TOKEN_ADD) if (command == TOKEN_ADD)
{ {
if (auto tableName = parseName()) if (auto tableName = parseQualifiedName())
{ {
AddNode node; AddNode node;
node.tableName = std::move(tableName.value()); node.tableName = std::move(tableName.value());
@ -120,15 +120,15 @@ FrontendParser::AnyNode FrontendParser::internalParse()
} while(true); } while(true);
} }
else if (command == TOKEN_COPY) else if (command == TOKEN_COPY)
{ {
CopyNode node; CopyNode node;
if (auto source = parseName()) if (auto source = parseQualifiedName())
node.source = std::move(source.value()); node.source = std::move(source.value());
else else
return InvalidNode(); return InvalidNode();
if (auto destination = parseName()) if (auto destination = parseQualifiedName())
node.destination = std::move(destination.value()); node.destination = std::move(destination.value());
else else
return InvalidNode(); return InvalidNode();
@ -344,7 +344,7 @@ FrontendParser::AnySetNode FrontendParser::parseSet()
else if (text == TOKEN_NAMES) else if (text == TOKEN_NAMES)
{ {
SetNamesNode node; SetNamesNode node;
node.name = parseName(); node.name = parseQualifiedName();
if (parseEof()) if (parseEof())
return node; return node;
@ -496,11 +496,11 @@ FrontendParser::AnyShowNode FrontendParser::parseShow()
{ {
const auto& text = showCommandToken.processedText; 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(); 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(); 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(); return parsed.value();
else if (text.length() >= 7 && TOKEN_COMMENTS.find(text) == 0) else if (text.length() >= 7 && TOKEN_COMMENTS.find(text) == 0)
{ {
@ -512,74 +512,42 @@ FrontendParser::AnyShowNode FrontendParser::parseShow()
if (parseEof()) if (parseEof())
return ShowDatabaseNode(); 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(); 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(); 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(); 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(); return parsed.value();
else if (const auto parsed = parseShowOptName<ShowFiltersNode>(text, TOKEN_FILTERS, 6)) else if (const auto parsed = parseShowOptName<ShowFiltersNode>(text, TOKEN_FILTERS, 6))
return parsed.value(); return parsed.value();
else if (text.length() >= 4 && TOKEN_FUNCTIONS.find(text) == 0) else if (text.length() >= 4 && TOKEN_FUNCTIONS.find(text) == 0)
{ {
ShowFunctionsNode node; ShowFunctionsNode node;
node.name = parseName(); node.name = parseQualifiedName(); // FIXME: package
if (node.name) if (parseEof())
{
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
return node; 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(); 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(); 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(); 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(); return parsed.value();
else if (const auto parsed = parseShowOptName<ShowMappingsNode>(text, TOKEN_MAPPINGS, 3)) else if (const auto parsed = parseShowOptName<ShowMappingsNode>(text, TOKEN_MAPPINGS, 3))
return parsed.value(); 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(); return parsed.value();
else if (text.length() >= 4 && TOKEN_PROCEDURES.find(text) == 0) else if (text.length() >= 4 && TOKEN_PROCEDURES.find(text) == 0)
{ {
ShowProceduresNode node; ShowProceduresNode node;
node.name = parseName(); node.name = parseQualifiedName(); // FIXME: package
if (node.name) if (parseEof())
{
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
return node; return node;
} }
else if (const auto parsed = parseShowOptName<ShowPublicationsNode>(text, TOKEN_PUBLICATIONS, 3)) 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 == "*")) if (!(token.type == Token::TYPE_OTHER && token.rawText == "*"))
{ {
lexer.setPos(lexerPos); lexer.setPos(lexerPos);
node.name = parseName(); node.name = parseQualifiedName();
if (!node.name) if (!node.name)
return InvalidNode(); return InvalidNode();
@ -611,7 +579,7 @@ FrontendParser::AnyShowNode FrontendParser::parseShow()
if (parseEof()) if (parseEof())
return node; 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(); return parsed.value();
else if (text == TOKEN_SQL) else if (text == TOKEN_SQL)
{ {
@ -656,9 +624,9 @@ FrontendParser::AnyShowNode FrontendParser::parseShow()
return node; 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(); 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(); return parsed.value();
else if (text == TOKEN_USERS) else if (text == TOKEN_USERS)
{ {
@ -670,7 +638,7 @@ FrontendParser::AnyShowNode FrontendParser::parseShow()
if (parseEof()) if (parseEof())
return ShowVersionNode(); 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(); return parsed.value();
else if (text.length() >= 9 && TOKEN_WIRE_STATISTICS.find(text) == 0 || else if (text.length() >= 9 && TOKEN_WIRE_STATISTICS.find(text) == 0 ||
text == TOKEN_WIRE_STATS) text == TOKEN_WIRE_STATS)
@ -706,6 +674,26 @@ std::optional<FrontendParser::AnyShowNode> FrontendParser::parseShowOptName(std:
return std::nullopt; 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() std::optional<std::string> FrontendParser::parseUtilEof()
{ {
const auto startIt = lexer.getPos(); const auto startIt = lexer.getPos();

View File

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

View File

@ -24,8 +24,15 @@
#ifndef ISQL_EXTRA_PROTO_H #ifndef ISQL_EXTRA_PROTO_H
#define ISQL_EXTRA_PROTO_H #define ISQL_EXTRA_PROTO_H
int EXTRACT_ddl(LegacyTables, const SCHAR*); #include <functional>
int EXTRACT_list_table(const SCHAR*, const SCHAR*, bool, SSHORT); #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*); processing_state EXTRACT_list_grants (const SCHAR*);
#endif // ISQL_EXTRA_PROTO_H #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 1; // null terminator
static const char* const DEFTERM = ";"; static const char* const DEFTERM = ";";
static const char* const DEFCHARSET = "NONE";
const unsigned NULL_DISP_LEN = 6; const unsigned NULL_DISP_LEN = 6;
@ -234,6 +233,7 @@ public:
size_t Termlen; size_t Termlen;
SCHAR User[128]; SCHAR User[128];
SCHAR Role[256]; SCHAR Role[256];
SCHAR SearchPath[512];
USHORT SQL_dialect; USHORT SQL_dialect;
USHORT db_SQL_dialect; USHORT db_SQL_dialect;
// from isql.epp // from isql.epp

View File

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

View File

@ -52,17 +52,18 @@ enum isql_switches
IN_SW_ISQL_QUIET = 19, IN_SW_ISQL_QUIET = 19,
IN_SW_ISQL_ROLE = 20, IN_SW_ISQL_ROLE = 20,
IN_SW_ISQL_ROLE2 = 21, IN_SW_ISQL_ROLE2 = 21,
IN_SW_ISQL_SQLDIALECT = 22, IN_SW_ISQL_SEARCH_PATH = 22,
IN_SW_ISQL_TERM = 23, IN_SW_ISQL_SQLDIALECT = 23,
IN_SW_ISQL_TERM = 24,
#ifdef TRUSTED_AUTH #ifdef TRUSTED_AUTH
IN_SW_ISQL_TRUSTED = 24, IN_SW_ISQL_TRUSTED = 25,
#endif #endif
IN_SW_ISQL_USER = 25, IN_SW_ISQL_USER = 26,
IN_SW_ISQL_VERSION = 26, IN_SW_ISQL_VERSION = 27,
#ifdef DEV_BUILD #ifdef DEV_BUILD
IN_SW_ISQL_EXTRACTTBL = 27, IN_SW_ISQL_EXTRACTTBL = 28,
#endif #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_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_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_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, "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_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}, {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) void IUTILS_printf(FILE* fp, const char* buffer)
{ {
/************************************** /**************************************

View File

@ -25,6 +25,7 @@
#define ISQL_IUTILS_PROTO_H #define ISQL_IUTILS_PROTO_H
#include "../common/classes/MetaString.h" #include "../common/classes/MetaString.h"
#include "../common/classes/QualifiedMetaString.h"
#include "../common/classes/SafeArg.h" #include "../common/classes/SafeArg.h"
#include <stdio.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, void IUTILS_msg_get(USHORT number, USHORT size, TEXT* msg,
const MsgFormat::SafeArg& args = MsgFormat::SafeArg()); const MsgFormat::SafeArg& args = MsgFormat::SafeArg());
Firebird::string IUTILS_name_to_string(const Firebird::MetaString& name); 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_printf(FILE*, const char*);
void IUTILS_printf2(FILE*, const char*, ...); void IUTILS_printf2(FILE*, const char*, ...);
void IUTILS_put_errmsg(USHORT number, const MsgFormat::SafeArg& args); 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 #define ISQL_SHOW_PROTO_H
#include "../common/classes/fb_string.h" #include "../common/classes/fb_string.h"
#include "../common/classes/QualifiedMetaString.h"
#include <firebird/Interface.h> #include <firebird/Interface.h>
#include "../isql/FrontendParser.h" #include "../isql/FrontendParser.h"
#include "../jrd/obj.h" #include "../jrd/obj.h"
#include <optional>
void SHOW_comments(bool force); void SHOW_comments(bool force);
void SHOW_dbb_parameters (Firebird::IAttachment*, const UCHAR*, unsigned, bool, const char*); void SHOW_dbb_parameters (Firebird::IAttachment*, const UCHAR*, unsigned, bool, const char*);
processing_state SHOW_grants (const SCHAR*, const SCHAR*, ObjectType); processing_state SHOW_grants(const std::optional<Firebird::QualifiedMetaString>&, const SCHAR*, ObjectType);
processing_state SHOW_grants2 (const SCHAR*, const SCHAR*, ObjectType, const TEXT*, bool); processing_state SHOW_grants2(const Firebird::QualifiedMetaString&, const SCHAR*, ObjectType, const TEXT*, bool);
void SHOW_grant_roles (const SCHAR*, bool*); void SHOW_grant_roles(const SCHAR*, bool*, const TEXT*, bool);
void SHOW_grant_roles2 (const SCHAR*, bool*, const TEXT*, bool);
void SHOW_print_metadata_text_blob(FILE*, ISC_QUAD*, bool escape_squote = false, void SHOW_print_metadata_text_blob(FILE*, ISC_QUAD*, bool escape_squote = false,
bool avoid_end_in_single_line_comment = false); bool avoid_end_in_single_line_comment = false);
processing_state SHOW_metadata(const FrontendParser::AnyShowNode& node); processing_state SHOW_metadata(const FrontendParser::AnyShowNode& node);
void SHOW_read_owner(); void SHOW_read_owner();
const Firebird::string SHOW_trigger_action(SINT64); const Firebird::string SHOW_trigger_action(SINT64);
processing_state SHOW_maps(bool extract, const SCHAR* map_name); processing_state SHOW_maps(bool extract, const std::optional<Firebird::MetaString>& name);
bool SHOW_system_privileges(const char* role, const char* prfx, bool lf); bool SHOW_system_privileges(const Firebird::MetaString& name, const char* prfx, bool lf);
#endif // ISQL_SHOW_PROTO_H #endif // ISQL_SHOW_PROTO_H

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