mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-02-02 09:20:39 +01:00
Place expression index support routines where it should be.
Add protection from changes while expression index is built. Remove PCMET module.
This commit is contained in:
parent
6f0544d54a
commit
c95aaf9300
@ -4978,16 +4978,6 @@
|
||||
path = par_proto.h;
|
||||
refType = 4;
|
||||
};
|
||||
F616C67E0200B0D001EF0ADE = {
|
||||
isa = PBXFileReference;
|
||||
path = pcmet.epp;
|
||||
refType = 4;
|
||||
};
|
||||
F616C67F0200B0D001EF0ADE = {
|
||||
isa = PBXFileReference;
|
||||
path = pcmet_proto.h;
|
||||
refType = 4;
|
||||
};
|
||||
F616C6800200B0D001EF0ADE = {
|
||||
isa = PBXFileReference;
|
||||
path = pcsleep.cpp;
|
||||
@ -10612,11 +10602,6 @@
|
||||
path = met.cpp;
|
||||
refType = 4;
|
||||
};
|
||||
F6B281360200CC3601EF0ADE = {
|
||||
isa = PBXFileReference;
|
||||
path = pcmet.cpp;
|
||||
refType = 4;
|
||||
};
|
||||
F6B281400200CC3601EF0ADE = {
|
||||
isa = PBXFileReference;
|
||||
path = scl.cpp;
|
||||
|
@ -46,7 +46,7 @@ FB_FW= $(PROJ_ROOT)/build/Firebird.framework
|
||||
|
||||
JRD_EPP_FILES= blob_filter.cpp dyn.epp dyn_util.epp ini.epp stats.epp \
|
||||
dyn_def.epp met.epp dfw.epp dyn_del.epp \
|
||||
fun.epp pcmet.epp dpm.epp dyn_mod.epp grant.epp scl.epp
|
||||
fun.epp dpm.epp dyn_mod.epp grant.epp scl.epp
|
||||
JRD_GEN_FILES= $(JRD_EPP_FILES:%.epp=$(GEN_ROOT)/jrd/%.cpp)
|
||||
|
||||
DSQL_EPP_FILES= array.epp blob.epp metd.epp
|
||||
|
@ -67,7 +67,6 @@ SEGMENTS
|
||||
OPT_TEXT DISCARDABLE
|
||||
PAG_TEXT DISCARDABLE
|
||||
PAR_TEXT DISCARDABLE
|
||||
PCMET_TEXT DISCARDABLE
|
||||
PCSLEEP_TEXT DISCARDABLE
|
||||
PWD_TEXT DISCARDABLE
|
||||
QATEST_TEXT DISCARDABLE
|
||||
|
@ -30,7 +30,6 @@
|
||||
<ClCompile Include="..\..\..\gen\jrd\grant.cpp" />
|
||||
<ClCompile Include="..\..\..\gen\jrd\ini.cpp" />
|
||||
<ClCompile Include="..\..\..\gen\jrd\met.cpp" />
|
||||
<ClCompile Include="..\..\..\gen\jrd\pcmet.cpp" />
|
||||
<ClCompile Include="..\..\..\gen\jrd\scl.cpp" />
|
||||
<ClCompile Include="..\..\..\gen\utilities\gstat\dba.cpp" />
|
||||
<ClCompile Include="..\..\..\src\dsql\AggNodes.cpp" />
|
||||
@ -285,7 +284,6 @@
|
||||
<ClInclude Include="..\..\..\src\jrd\pag.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\pag_proto.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\par_proto.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\pcmet_proto.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\PreparedStatement.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\que.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\RandomGenerator.h" />
|
||||
@ -354,7 +352,6 @@
|
||||
<None Include="..\..\..\src\jrd\grant.epp" />
|
||||
<None Include="..\..\..\src\jrd\ini.epp" />
|
||||
<None Include="..\..\..\src\jrd\met.epp" />
|
||||
<None Include="..\..\..\src\jrd\pcmet.epp" />
|
||||
<None Include="..\..\..\src\jrd\scl.epp" />
|
||||
<None Include="..\..\..\src\utilities\gstat\dba.epp" />
|
||||
<None Include="..\defs\plugin.def" />
|
||||
|
@ -420,9 +420,6 @@
|
||||
<ClCompile Include="..\..\..\gen\jrd\met.cpp">
|
||||
<Filter>JRD files\GPRE cpp</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\gen\jrd\pcmet.cpp">
|
||||
<Filter>JRD files\GPRE cpp</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\gen\dsql\DdlNodes.cpp">
|
||||
<Filter>DSQL\preprocesed</Filter>
|
||||
</ClCompile>
|
||||
@ -845,9 +842,6 @@
|
||||
<ClInclude Include="..\..\..\src\jrd\par_proto.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\src\jrd\pcmet_proto.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\src\jrd\PreparedStatement.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
@ -1027,9 +1021,6 @@
|
||||
<None Include="..\..\..\src\jrd\met.epp">
|
||||
<Filter>JRD files\GPRE files</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\src\jrd\pcmet.epp">
|
||||
<Filter>JRD files\GPRE files</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\src\jrd\scl.epp">
|
||||
<Filter>JRD files\GPRE files</Filter>
|
||||
</None>
|
||||
|
@ -30,7 +30,6 @@
|
||||
<ClCompile Include="..\..\..\gen\jrd\grant.cpp" />
|
||||
<ClCompile Include="..\..\..\gen\jrd\ini.cpp" />
|
||||
<ClCompile Include="..\..\..\gen\jrd\met.cpp" />
|
||||
<ClCompile Include="..\..\..\gen\jrd\pcmet.cpp" />
|
||||
<ClCompile Include="..\..\..\gen\jrd\scl.cpp" />
|
||||
<ClCompile Include="..\..\..\gen\utilities\gstat\dba.cpp" />
|
||||
<ClCompile Include="..\..\..\src\dsql\AggNodes.cpp" />
|
||||
@ -285,7 +284,6 @@
|
||||
<ClInclude Include="..\..\..\src\jrd\pag.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\pag_proto.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\par_proto.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\pcmet_proto.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\PreparedStatement.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\que.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\RandomGenerator.h" />
|
||||
@ -354,7 +352,6 @@
|
||||
<None Include="..\..\..\src\jrd\grant.epp" />
|
||||
<None Include="..\..\..\src\jrd\ini.epp" />
|
||||
<None Include="..\..\..\src\jrd\met.epp" />
|
||||
<None Include="..\..\..\src\jrd\pcmet.epp" />
|
||||
<None Include="..\..\..\src\jrd\scl.epp" />
|
||||
<None Include="..\..\..\src\utilities\gstat\dba.epp" />
|
||||
<None Include="..\defs\plugin.def" />
|
||||
|
@ -420,9 +420,6 @@
|
||||
<ClCompile Include="..\..\..\gen\jrd\met.cpp">
|
||||
<Filter>JRD files\GPRE cpp</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\gen\jrd\pcmet.cpp">
|
||||
<Filter>JRD files\GPRE cpp</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\gen\dsql\DdlNodes.cpp">
|
||||
<Filter>DSQL\preprocesed</Filter>
|
||||
</ClCompile>
|
||||
@ -845,9 +842,6 @@
|
||||
<ClInclude Include="..\..\..\src\jrd\par_proto.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\src\jrd\pcmet_proto.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\src\jrd\PreparedStatement.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
@ -1027,9 +1021,6 @@
|
||||
<None Include="..\..\..\src\jrd\met.epp">
|
||||
<Filter>JRD files\GPRE files</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\src\jrd\pcmet.epp">
|
||||
<Filter>JRD files\GPRE files</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\src\jrd\scl.epp">
|
||||
<Filter>JRD files\GPRE files</Filter>
|
||||
</None>
|
||||
|
@ -30,7 +30,6 @@
|
||||
<ClCompile Include="..\..\..\gen\jrd\grant.cpp" />
|
||||
<ClCompile Include="..\..\..\gen\jrd\ini.cpp" />
|
||||
<ClCompile Include="..\..\..\gen\jrd\met.cpp" />
|
||||
<ClCompile Include="..\..\..\gen\jrd\pcmet.cpp" />
|
||||
<ClCompile Include="..\..\..\gen\jrd\scl.cpp" />
|
||||
<ClCompile Include="..\..\..\gen\utilities\gstat\dba.cpp" />
|
||||
<ClCompile Include="..\..\..\src\dsql\AggNodes.cpp" />
|
||||
@ -285,7 +284,6 @@
|
||||
<ClInclude Include="..\..\..\src\jrd\pag.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\pag_proto.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\par_proto.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\pcmet_proto.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\PreparedStatement.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\que.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\RandomGenerator.h" />
|
||||
@ -354,7 +352,6 @@
|
||||
<None Include="..\..\..\src\jrd\grant.epp" />
|
||||
<None Include="..\..\..\src\jrd\ini.epp" />
|
||||
<None Include="..\..\..\src\jrd\met.epp" />
|
||||
<None Include="..\..\..\src\jrd\pcmet.epp" />
|
||||
<None Include="..\..\..\src\jrd\scl.epp" />
|
||||
<None Include="..\..\..\src\utilities\gstat\dba.epp" />
|
||||
<None Include="..\defs\plugin.def" />
|
||||
|
@ -420,9 +420,6 @@
|
||||
<ClCompile Include="..\..\..\gen\jrd\met.cpp">
|
||||
<Filter>JRD files\GPRE cpp</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\gen\jrd\pcmet.cpp">
|
||||
<Filter>JRD files\GPRE cpp</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\gen\dsql\DdlNodes.cpp">
|
||||
<Filter>DSQL\preprocesed</Filter>
|
||||
</ClCompile>
|
||||
@ -845,9 +842,6 @@
|
||||
<ClInclude Include="..\..\..\src\jrd\par_proto.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\src\jrd\pcmet_proto.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\src\jrd\PreparedStatement.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
@ -1027,9 +1021,6 @@
|
||||
<None Include="..\..\..\src\jrd\met.epp">
|
||||
<Filter>JRD files\GPRE files</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\src\jrd\pcmet.epp">
|
||||
<Filter>JRD files\GPRE files</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\src\jrd\scl.epp">
|
||||
<Filter>JRD files\GPRE files</Filter>
|
||||
</None>
|
||||
|
@ -758,10 +758,6 @@
|
||||
RelativePath="..\..\..\gen\jrd\met.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\gen\jrd\pcmet.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\gen\jrd\scl.cpp"
|
||||
>
|
||||
@ -802,10 +798,6 @@
|
||||
RelativePath="..\..\..\src\jrd\met.epp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\src\jrd\pcmet.epp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\src\jrd\scl.epp"
|
||||
>
|
||||
@ -1363,10 +1355,6 @@
|
||||
RelativePath="..\..\..\src\dsql\pass1_proto.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\src\jrd\pcmet_proto.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\src\jrd\os\pio.h"
|
||||
>
|
||||
|
@ -766,10 +766,6 @@
|
||||
RelativePath="..\..\..\gen\jrd\met.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\gen\jrd\pcmet.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\gen\jrd\scl.cpp"
|
||||
>
|
||||
@ -810,10 +806,6 @@
|
||||
RelativePath="..\..\..\src\jrd\met.epp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\src\jrd\pcmet.epp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\src\jrd\scl.epp"
|
||||
>
|
||||
@ -1371,10 +1363,6 @@
|
||||
RelativePath="..\..\..\src\dsql\pass1_proto.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\src\jrd\pcmet_proto.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\src\jrd\os\pio.h"
|
||||
>
|
||||
|
@ -67,7 +67,7 @@ goto :EOF
|
||||
@for %%i in (array, blob) do @call :PREPROCESS yvalve %%i
|
||||
@for %%i in (metd, DdlNodes, PackageNodes) do @call :PREPROCESS dsql %%i -gds_cxx
|
||||
@for %%i in (gpre_meta) do @call :PREPROCESS gpre/std %%i
|
||||
@for %%i in (dfw, dpm, dyn_util, fun, grant, ini, met, pcmet, scl, Function) do @call :PREPROCESS jrd %%i -gds_cxx
|
||||
@for %%i in (dfw, dpm, dyn_util, fun, grant, ini, met, scl, Function) do @call :PREPROCESS jrd %%i -gds_cxx
|
||||
@for %%i in (stats) do @call :PREPROCESS utilities %%i
|
||||
@goto :EOF
|
||||
|
||||
@ -81,7 +81,7 @@ goto :EOF
|
||||
@for %%i in (metd) do @call :PREPROCESS dsql %%i -gds_cxx
|
||||
@for %%i in (DdlNodes, PackageNodes) do @call :PREPROCESS dsql %%i -gds_cxx
|
||||
@for %%i in (gpre_meta) do @call :PREPROCESS gpre/std %%i
|
||||
@for %%i in (dfw, dpm, dyn_util, fun, grant, ini, met, pcmet, scl, Function) do @call :PREPROCESS jrd %%i -gds_cxx
|
||||
@for %%i in (dfw, dpm, dyn_util, fun, grant, ini, met, scl, Function) do @call :PREPROCESS jrd %%i -gds_cxx
|
||||
@for %%i in (codes) do @call :PREPROCESS misc %%i
|
||||
@for %%i in (build_file) do @call :PREPROCESS msgs %%i
|
||||
@for %%i in (help, meta, proc, show) do @call :PREPROCESS qli %%i
|
||||
|
@ -58,7 +58,6 @@
|
||||
#include "../jrd/met_proto.h"
|
||||
#include "../jrd/mov_proto.h"
|
||||
#include "../jrd/pag_proto.h"
|
||||
#include "../jrd/pcmet_proto.h"
|
||||
#include "../jrd/tra_proto.h"
|
||||
|
||||
using namespace Jrd;
|
||||
@ -512,7 +511,7 @@ bool BTR_description(thread_db* tdbb, jrd_rel* relation, index_root_page* root,
|
||||
|
||||
if (idx->idx_flags & idx_expressn)
|
||||
{
|
||||
PCMET_lookup_index(tdbb, relation, idx);
|
||||
MET_lookup_index_expression(tdbb, relation, idx);
|
||||
fb_assert(idx->idx_expression != NULL);
|
||||
}
|
||||
|
||||
|
147
src/jrd/dfw.epp
147
src/jrd/dfw.epp
@ -106,7 +106,6 @@
|
||||
#include "../jrd/met_proto.h"
|
||||
#include "../jrd/mov_proto.h"
|
||||
#include "../jrd/pag_proto.h"
|
||||
#include "../jrd/pcmet_proto.h"
|
||||
#include "../jrd/os/pio_proto.h"
|
||||
#include "../jrd/rlck_proto.h"
|
||||
#include "../jrd/scl_proto.h"
|
||||
@ -2492,7 +2491,151 @@ static bool create_expression_index(thread_db* tdbb, SSHORT phase, DeferredWork*
|
||||
return true;
|
||||
|
||||
case 3:
|
||||
PCMET_expression_index(tdbb, work->dfw_name, work->dfw_id, transaction);
|
||||
{
|
||||
jrd_rel* relation = NULL;
|
||||
index_desc idx;
|
||||
MemoryPool* new_pool = NULL;
|
||||
|
||||
SET_TDBB(tdbb);
|
||||
Database* dbb = tdbb->getDatabase();
|
||||
Jrd::Attachment* attachment = tdbb->getAttachment();
|
||||
|
||||
MOVE_CLEAR(&idx, sizeof(index_desc));
|
||||
|
||||
AutoCacheRequest request(tdbb, irq_c_exp_index, IRQ_REQUESTS);
|
||||
|
||||
FOR(REQUEST_HANDLE request)
|
||||
IDX IN RDB$INDICES CROSS
|
||||
REL IN RDB$RELATIONS OVER RDB$RELATION_NAME WITH
|
||||
IDX.RDB$EXPRESSION_BLR NOT MISSING AND
|
||||
IDX.RDB$INDEX_NAME EQ work->dfw_name.c_str()
|
||||
{
|
||||
if (!relation)
|
||||
{
|
||||
relation = MET_relation(tdbb, REL.RDB$RELATION_ID);
|
||||
if (relation->rel_name.length() == 0) {
|
||||
relation->rel_name = REL.RDB$RELATION_NAME;
|
||||
}
|
||||
|
||||
if (IDX.RDB$INDEX_ID && IDX.RDB$STATISTICS < 0.0)
|
||||
{
|
||||
SelectivityList selectivity(*tdbb->getDefaultPool());
|
||||
const USHORT localId = IDX.RDB$INDEX_ID - 1;
|
||||
IDX_statistics(tdbb, relation, localId, selectivity);
|
||||
DFW_update_index(work->dfw_name.c_str(), localId, selectivity, transaction);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IDX.RDB$INDEX_ID)
|
||||
{
|
||||
IDX_delete_index(tdbb, relation, IDX.RDB$INDEX_ID - 1);
|
||||
MET_delete_dependencies(tdbb, work->dfw_name, obj_expression_index, transaction);
|
||||
MODIFY IDX
|
||||
IDX.RDB$INDEX_ID.NULL = TRUE;
|
||||
END_MODIFY
|
||||
}
|
||||
|
||||
if (IDX.RDB$INDEX_INACTIVE)
|
||||
return false;
|
||||
|
||||
if (IDX.RDB$SEGMENT_COUNT)
|
||||
{
|
||||
// Msg359: segments not allowed in expression index %s
|
||||
ERR_post(Arg::Gds(isc_no_meta_update) <<
|
||||
Arg::Gds(isc_no_segments_err) << Arg::Str(work->dfw_name));
|
||||
}
|
||||
if (IDX.RDB$UNIQUE_FLAG)
|
||||
idx.idx_flags |= idx_unique;
|
||||
if (IDX.RDB$INDEX_TYPE == 1)
|
||||
idx.idx_flags |= idx_descending;
|
||||
|
||||
CompilerScratch* csb = 0;
|
||||
// allocate a new pool to contain the expression tree for the expression index
|
||||
new_pool = attachment->createPool();
|
||||
{ // scope
|
||||
Jrd::ContextPoolHolder context(tdbb, new_pool);
|
||||
MET_scan_relation(tdbb, relation);
|
||||
|
||||
if (!IDX.RDB$EXPRESSION_BLR.NULL)
|
||||
{
|
||||
idx.idx_expression = static_cast<ValueExprNode*>(MET_get_dependencies(
|
||||
tdbb, relation, NULL, 0, NULL, &IDX.RDB$EXPRESSION_BLR,
|
||||
&idx.idx_expression_statement, &csb, work->dfw_name, obj_expression_index, 0,
|
||||
transaction));
|
||||
}
|
||||
} // end scope
|
||||
|
||||
// fake a description of the index
|
||||
|
||||
idx.idx_count = 1;
|
||||
idx.idx_flags |= idx_expressn;
|
||||
idx.idx_expression->getDesc(tdbb, csb, &idx.idx_expression_desc);
|
||||
idx.idx_rpt[0].idx_itype =
|
||||
DFW_assign_index_type(tdbb, work->dfw_name,
|
||||
idx.idx_expression_desc.dsc_dtype,
|
||||
idx.idx_expression_desc.dsc_sub_type);
|
||||
idx.idx_rpt[0].idx_selectivity = 0;
|
||||
|
||||
delete csb;
|
||||
}
|
||||
}
|
||||
END_FOR
|
||||
|
||||
if (!relation)
|
||||
{
|
||||
if (new_pool)
|
||||
attachment->deletePool(new_pool);
|
||||
|
||||
// Msg308: can't create index %s
|
||||
ERR_post(Arg::Gds(isc_no_meta_update) <<
|
||||
Arg::Gds(isc_idx_create_err) << Arg::Str(work->dfw_name));
|
||||
}
|
||||
|
||||
// Actually create the index
|
||||
|
||||
// Protect relation from modification to create consistent index
|
||||
bool releaseRelationLock = false;
|
||||
Lock* relationLock = protect_relation(tdbb, transaction, relation, releaseRelationLock);
|
||||
|
||||
SelectivityList selectivity(*tdbb->getDefaultPool());
|
||||
|
||||
jrd_tra* const current_transaction = tdbb->getTransaction();
|
||||
jrd_req* const current_request = tdbb->getRequest();
|
||||
|
||||
try
|
||||
{
|
||||
fb_assert(work->dfw_id <= dbb->dbb_max_idx);
|
||||
idx.idx_id = work->dfw_id;
|
||||
IDX_create_index(tdbb, relation, &idx, work->dfw_name.c_str(), &work->dfw_id,
|
||||
transaction, selectivity);
|
||||
|
||||
fb_assert(work->dfw_id == idx.idx_id);
|
||||
|
||||
if (relationLock && releaseRelationLock) {
|
||||
release_protect_lock(tdbb, transaction, relationLock);
|
||||
}
|
||||
}
|
||||
catch (const Exception&)
|
||||
{
|
||||
tdbb->setTransaction(current_transaction);
|
||||
tdbb->setRequest(current_request);
|
||||
|
||||
if (relationLock && releaseRelationLock) {
|
||||
release_protect_lock(tdbb, transaction, relationLock);
|
||||
}
|
||||
throw;
|
||||
}
|
||||
|
||||
tdbb->setTransaction(current_transaction);
|
||||
tdbb->setRequest(current_request);
|
||||
|
||||
DFW_update_index(work->dfw_name.c_str(), idx.idx_id, selectivity, transaction);
|
||||
|
||||
// Get rid of the pool containing the expression tree
|
||||
|
||||
attachment->deletePool(new_pool);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -82,7 +82,6 @@
|
||||
#include "../jrd/met_proto.h"
|
||||
#include "../jrd/mov_proto.h"
|
||||
#include "../jrd/par_proto.h"
|
||||
#include "../jrd/pcmet_proto.h"
|
||||
#include "../jrd/os/pio_proto.h"
|
||||
#include "../jrd/scl_proto.h"
|
||||
#include "../jrd/sdw_proto.h"
|
||||
@ -2495,6 +2494,100 @@ SLONG MET_lookup_index_name(thread_db* tdbb,
|
||||
}
|
||||
|
||||
|
||||
void MET_lookup_index_expression(thread_db* tdbb, jrd_rel* relation, index_desc* idx)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
* M E T _ l o o k u p _ i n d e x _ e x p r e s s i o n
|
||||
*
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Lookup information about an index, in
|
||||
* the metadata cache if possible.
|
||||
*
|
||||
**************************************/
|
||||
SET_TDBB(tdbb);
|
||||
Attachment* attachment = tdbb->getAttachment();
|
||||
|
||||
// Check the index blocks for the relation to see if we have a cached block
|
||||
|
||||
IndexBlock* index_block;
|
||||
for (index_block = relation->rel_index_blocks; index_block; index_block = index_block->idb_next)
|
||||
{
|
||||
if (index_block->idb_id == idx->idx_id)
|
||||
break;
|
||||
}
|
||||
|
||||
if (index_block && index_block->idb_expression)
|
||||
{
|
||||
idx->idx_expression = index_block->idb_expression;
|
||||
idx->idx_expression_statement = index_block->idb_expression_statement;
|
||||
memcpy(&idx->idx_expression_desc, &index_block->idb_expression_desc, sizeof(struct dsc));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(relation->rel_flags & REL_scanned) || (relation->rel_flags & REL_being_scanned))
|
||||
{
|
||||
MET_scan_relation(tdbb, relation);
|
||||
}
|
||||
|
||||
CompilerScratch* csb = NULL;
|
||||
AutoCacheRequest request(tdbb, irq_l_exp_index, IRQ_REQUESTS);
|
||||
|
||||
FOR(REQUEST_HANDLE request)
|
||||
IDX IN RDB$INDICES WITH
|
||||
IDX.RDB$RELATION_NAME EQ relation->rel_name.c_str() AND
|
||||
IDX.RDB$INDEX_ID EQ idx->idx_id + 1
|
||||
{
|
||||
if (idx->idx_expression_statement)
|
||||
{
|
||||
idx->idx_expression_statement->release(tdbb);
|
||||
idx->idx_expression_statement = NULL;
|
||||
}
|
||||
|
||||
// parse the blr, making sure to create the resulting expression
|
||||
// tree and request in its own pool so that it may be cached
|
||||
// with the index block in the "permanent" metadata cache
|
||||
|
||||
{ // scope
|
||||
Jrd::ContextPoolHolder context(tdbb, attachment->createPool());
|
||||
idx->idx_expression = static_cast<ValueExprNode*>(MET_parse_blob(
|
||||
tdbb, relation, &IDX.RDB$EXPRESSION_BLR, &csb,
|
||||
&idx->idx_expression_statement, false, false));
|
||||
} // end scope
|
||||
}
|
||||
END_FOR
|
||||
|
||||
if (csb)
|
||||
idx->idx_expression->getDesc(tdbb, csb, &idx->idx_expression_desc);
|
||||
|
||||
delete csb;
|
||||
|
||||
// if there is no existing index block for this index, create
|
||||
// one and link it in with the index blocks for this relation
|
||||
|
||||
if (!index_block)
|
||||
index_block = IDX_create_index_block(tdbb, relation, idx->idx_id);
|
||||
|
||||
// if we can't get the lock, no big deal: just give up on caching the index info
|
||||
|
||||
if (!LCK_lock(tdbb, index_block->idb_lock, LCK_SR, LCK_NO_WAIT))
|
||||
{
|
||||
// clear lock error from status vector
|
||||
fb_utils::init_status(tdbb->tdbb_status_vector);
|
||||
return;
|
||||
}
|
||||
|
||||
// whether the index block already existed or was just created,
|
||||
// fill in the cached information about the index
|
||||
|
||||
index_block->idb_expression = idx->idx_expression;
|
||||
index_block->idb_expression_statement = idx->idx_expression_statement;
|
||||
memcpy(&index_block->idb_expression_desc, &idx->idx_expression_desc, sizeof(struct dsc));
|
||||
}
|
||||
|
||||
|
||||
bool MET_lookup_partner(thread_db* tdbb, jrd_rel* relation, index_desc* idx, const TEXT* index_name)
|
||||
{
|
||||
/**************************************
|
||||
|
@ -105,6 +105,7 @@ SLONG MET_lookup_generator(Jrd::thread_db*, const Firebird::MetaName&, bool* sy
|
||||
bool MET_lookup_generator_id(Jrd::thread_db*, SLONG, Firebird::MetaName&, bool* sysGen = 0);
|
||||
void MET_update_generator_increment(Jrd::thread_db* tdbb, SLONG gen_id, SLONG step);
|
||||
void MET_lookup_index(Jrd::thread_db*, Firebird::MetaName&, const Firebird::MetaName&, USHORT);
|
||||
void MET_lookup_index_expression(Jrd::thread_db*, Jrd::jrd_rel*, Jrd::index_desc*);
|
||||
SLONG MET_lookup_index_name(Jrd::thread_db*, const Firebird::MetaName&, SLONG*, Jrd::IndexStatus* status);
|
||||
bool MET_lookup_partner(Jrd::thread_db*, Jrd::jrd_rel*, struct Jrd::index_desc*, const TEXT*);
|
||||
Jrd::jrd_prc* MET_lookup_procedure(Jrd::thread_db*, const Firebird::QualifiedName&, bool);
|
||||
|
@ -1,295 +0,0 @@
|
||||
/*
|
||||
* PROGRAM: JRD Access Method
|
||||
* MODULE: pcmet.epp
|
||||
* DESCRIPTION: Meta data for expression indices
|
||||
*
|
||||
* The contents of this file are subject to the Interbase Public
|
||||
* License Version 1.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy
|
||||
* of the License at http://www.Inprise.com/IPL.html
|
||||
*
|
||||
* Software distributed under the License is distributed on an
|
||||
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code was created by Inprise Corporation
|
||||
* and its predecessors. Portions created by Inprise Corporation are
|
||||
* Copyright (C) Inprise Corporation.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
*/
|
||||
|
||||
#include "firebird.h"
|
||||
#include <string.h>
|
||||
#include "../jrd/jrd.h"
|
||||
#include "../jrd/irq.h"
|
||||
#include "../jrd/tra.h"
|
||||
#include "../jrd/val.h"
|
||||
#include "../jrd/ods.h"
|
||||
#include "../jrd/btr.h"
|
||||
#include "../jrd/req.h"
|
||||
#include "../jrd/exe.h"
|
||||
#include "../jrd/met.h"
|
||||
#include "../jrd/lck.h"
|
||||
#include "../jrd/cmp_proto.h"
|
||||
#include "../jrd/dfw_proto.h"
|
||||
#include "../jrd/err_proto.h"
|
||||
#include "../jrd/exe_proto.h"
|
||||
#include "../yvalve/gds_proto.h"
|
||||
#include "../jrd/idx_proto.h"
|
||||
#include "../jrd/tra_proto.h"
|
||||
|
||||
#include "../jrd/lck_proto.h"
|
||||
#include "../jrd/met_proto.h"
|
||||
#include "../jrd/mov_proto.h"
|
||||
#include "../jrd/pcmet_proto.h"
|
||||
|
||||
using namespace Jrd;
|
||||
using namespace Firebird;
|
||||
|
||||
DATABASE DB = FILENAME "ODS.RDB";
|
||||
|
||||
|
||||
void PCMET_expression_index(thread_db* tdbb, const MetaName& name, USHORT& id, jrd_tra* transaction)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
* P C M E T _ e x p r e s s i o n _ i n d e x
|
||||
*
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Create a new expression index.
|
||||
*
|
||||
**************************************/
|
||||
jrd_rel* relation = NULL;
|
||||
index_desc idx;
|
||||
MemoryPool* new_pool = NULL;
|
||||
|
||||
SET_TDBB(tdbb);
|
||||
Jrd::Attachment* attachment = tdbb->getAttachment();
|
||||
#ifdef DEV_BUILD
|
||||
Database* dbb = tdbb->getDatabase();
|
||||
#endif
|
||||
|
||||
MOVE_CLEAR(&idx, sizeof(index_desc));
|
||||
|
||||
AutoCacheRequest request(tdbb, irq_c_exp_index, IRQ_REQUESTS);
|
||||
|
||||
FOR(REQUEST_HANDLE request)
|
||||
IDX IN RDB$INDICES CROSS
|
||||
REL IN RDB$RELATIONS OVER RDB$RELATION_NAME WITH
|
||||
IDX.RDB$EXPRESSION_BLR NOT MISSING AND
|
||||
IDX.RDB$INDEX_NAME EQ name.c_str()
|
||||
{
|
||||
if (!relation)
|
||||
{
|
||||
relation = MET_relation(tdbb, REL.RDB$RELATION_ID);
|
||||
if (relation->rel_name.length() == 0) {
|
||||
relation->rel_name = REL.RDB$RELATION_NAME;
|
||||
}
|
||||
|
||||
if (IDX.RDB$INDEX_ID && IDX.RDB$STATISTICS < 0.0)
|
||||
{
|
||||
SelectivityList selectivity(*tdbb->getDefaultPool());
|
||||
const USHORT localId = IDX.RDB$INDEX_ID - 1;
|
||||
IDX_statistics(tdbb, relation, localId, selectivity);
|
||||
DFW_update_index(name.c_str(), localId, selectivity, transaction);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (IDX.RDB$INDEX_ID)
|
||||
{
|
||||
IDX_delete_index(tdbb, relation, IDX.RDB$INDEX_ID - 1);
|
||||
MET_delete_dependencies(tdbb, name, obj_expression_index, transaction);
|
||||
MODIFY IDX
|
||||
IDX.RDB$INDEX_ID.NULL = TRUE;
|
||||
END_MODIFY
|
||||
}
|
||||
|
||||
if (IDX.RDB$INDEX_INACTIVE)
|
||||
return;
|
||||
|
||||
if (IDX.RDB$SEGMENT_COUNT)
|
||||
{
|
||||
// Msg359: segments not allowed in expression index %s
|
||||
ERR_post(Arg::Gds(isc_no_meta_update) <<
|
||||
Arg::Gds(isc_no_segments_err) << Arg::Str(name));
|
||||
}
|
||||
if (IDX.RDB$UNIQUE_FLAG)
|
||||
idx.idx_flags |= idx_unique;
|
||||
if (IDX.RDB$INDEX_TYPE == 1)
|
||||
idx.idx_flags |= idx_descending;
|
||||
|
||||
CompilerScratch* csb = 0;
|
||||
// allocate a new pool to contain the expression tree for the expression index
|
||||
new_pool = attachment->createPool();
|
||||
{ // scope
|
||||
Jrd::ContextPoolHolder context(tdbb, new_pool);
|
||||
MET_scan_relation(tdbb, relation);
|
||||
|
||||
if (!IDX.RDB$EXPRESSION_BLR.NULL)
|
||||
{
|
||||
idx.idx_expression = static_cast<ValueExprNode*>(MET_get_dependencies(
|
||||
tdbb, relation, NULL, 0, NULL, &IDX.RDB$EXPRESSION_BLR,
|
||||
&idx.idx_expression_statement, &csb, name, obj_expression_index, 0,
|
||||
transaction));
|
||||
}
|
||||
} // end scope
|
||||
|
||||
// fake a description of the index
|
||||
|
||||
idx.idx_count = 1;
|
||||
idx.idx_flags |= idx_expressn;
|
||||
idx.idx_expression->getDesc(tdbb, csb, &idx.idx_expression_desc);
|
||||
idx.idx_rpt[0].idx_itype =
|
||||
DFW_assign_index_type(tdbb, name,
|
||||
idx.idx_expression_desc.dsc_dtype,
|
||||
idx.idx_expression_desc.dsc_sub_type);
|
||||
idx.idx_rpt[0].idx_selectivity = 0;
|
||||
|
||||
delete csb;
|
||||
}
|
||||
}
|
||||
END_FOR
|
||||
|
||||
if (!relation)
|
||||
{
|
||||
if (new_pool)
|
||||
attachment->deletePool(new_pool);
|
||||
|
||||
// Msg308: can't create index %s
|
||||
ERR_post(Arg::Gds(isc_no_meta_update) <<
|
||||
Arg::Gds(isc_idx_create_err) << Arg::Str(name));
|
||||
}
|
||||
|
||||
// Actually create the index
|
||||
|
||||
SelectivityList selectivity(*tdbb->getDefaultPool());
|
||||
|
||||
jrd_tra* const current_transaction = tdbb->getTransaction();
|
||||
jrd_req* const current_request = tdbb->getRequest();
|
||||
|
||||
try
|
||||
{
|
||||
fb_assert(id <= dbb->dbb_max_idx);
|
||||
idx.idx_id = id;
|
||||
IDX_create_index(tdbb, relation, &idx, name.c_str(), &id, transaction, selectivity);
|
||||
|
||||
fb_assert(id == idx.idx_id);
|
||||
}
|
||||
catch (const Exception&)
|
||||
{
|
||||
tdbb->setTransaction(current_transaction);
|
||||
tdbb->setRequest(current_request);
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
tdbb->setTransaction(current_transaction);
|
||||
tdbb->setRequest(current_request);
|
||||
|
||||
DFW_update_index(name.c_str(), idx.idx_id, selectivity, transaction);
|
||||
|
||||
// Get rid of the pool containing the expression tree
|
||||
|
||||
attachment->deletePool(new_pool);
|
||||
}
|
||||
|
||||
|
||||
void PCMET_lookup_index(thread_db* tdbb, jrd_rel* relation, index_desc* idx)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
* P C M E T _ l o o k u p _ i n d e x
|
||||
*
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Lookup information about an index, in
|
||||
* the metadata cache if possible.
|
||||
*
|
||||
**************************************/
|
||||
SET_TDBB(tdbb);
|
||||
Jrd::Attachment* attachment = tdbb->getAttachment();
|
||||
|
||||
// Check the index blocks for the relation to see if we have a cached block
|
||||
|
||||
IndexBlock* index_block;
|
||||
for (index_block = relation->rel_index_blocks; index_block; index_block = index_block->idb_next)
|
||||
{
|
||||
if (index_block->idb_id == idx->idx_id)
|
||||
break;
|
||||
}
|
||||
|
||||
if (index_block && index_block->idb_expression)
|
||||
{
|
||||
idx->idx_expression = index_block->idb_expression;
|
||||
idx->idx_expression_statement = index_block->idb_expression_statement;
|
||||
memcpy(&idx->idx_expression_desc, &index_block->idb_expression_desc, sizeof(struct dsc));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(relation->rel_flags & REL_scanned) || (relation->rel_flags & REL_being_scanned))
|
||||
{
|
||||
MET_scan_relation(tdbb, relation);
|
||||
}
|
||||
|
||||
CompilerScratch* csb = NULL;
|
||||
AutoCacheRequest request(tdbb, irq_l_exp_index, IRQ_REQUESTS);
|
||||
|
||||
FOR(REQUEST_HANDLE request)
|
||||
IDX IN RDB$INDICES WITH
|
||||
IDX.RDB$RELATION_NAME EQ relation->rel_name.c_str() AND
|
||||
IDX.RDB$INDEX_ID EQ idx->idx_id + 1
|
||||
{
|
||||
if (idx->idx_expression_statement)
|
||||
{
|
||||
idx->idx_expression_statement->release(tdbb);
|
||||
idx->idx_expression_statement = NULL;
|
||||
}
|
||||
|
||||
// parse the blr, making sure to create the resulting expression
|
||||
// tree and request in its own pool so that it may be cached
|
||||
// with the index block in the "permanent" metadata cache
|
||||
|
||||
{ // scope
|
||||
Jrd::ContextPoolHolder context(tdbb, attachment->createPool());
|
||||
idx->idx_expression = static_cast<ValueExprNode*>(MET_parse_blob(
|
||||
tdbb, relation, &IDX.RDB$EXPRESSION_BLR, &csb,
|
||||
&idx->idx_expression_statement, false, false));
|
||||
} // end scope
|
||||
}
|
||||
END_FOR
|
||||
|
||||
if (csb)
|
||||
idx->idx_expression->getDesc(tdbb, csb, &idx->idx_expression_desc);
|
||||
|
||||
delete csb;
|
||||
|
||||
// if there is no existing index block for this index, create
|
||||
// one and link it in with the index blocks for this relation
|
||||
|
||||
if (!index_block)
|
||||
index_block = IDX_create_index_block(tdbb, relation, idx->idx_id);
|
||||
|
||||
// if we can't get the lock, no big deal: just give up on caching the index info
|
||||
|
||||
if (!LCK_lock(tdbb, index_block->idb_lock, LCK_SR, LCK_NO_WAIT))
|
||||
{
|
||||
// clear lock error from status vector
|
||||
fb_utils::init_status(tdbb->tdbb_status_vector);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// whether the index block already existed or was just created,
|
||||
// fill in the cached information about the index
|
||||
|
||||
index_block->idb_expression = idx->idx_expression;
|
||||
index_block->idb_expression_statement = idx->idx_expression_statement;
|
||||
memcpy(&index_block->idb_expression_desc, &idx->idx_expression_desc, sizeof(struct dsc));
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
/*
|
||||
* PROGRAM: JRD Access Method
|
||||
* MODULE: pcmet_proto.h
|
||||
* DESCRIPTION: Prototype header file for pcmet.cpp
|
||||
*
|
||||
* The contents of this file are subject to the Interbase Public
|
||||
* License Version 1.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy
|
||||
* of the License at http://www.Inprise.com/IPL.html
|
||||
*
|
||||
* Software distributed under the License is distributed on an
|
||||
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code was created by Inprise Corporation
|
||||
* and its predecessors. Portions created by Inprise Corporation are
|
||||
* Copyright (C) Inprise Corporation.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
*/
|
||||
|
||||
#ifndef JRD_PCMET_PROTO_H
|
||||
#define JRD_PCMET_PROTO_H
|
||||
|
||||
#include "../common/classes/fb_string.h"
|
||||
|
||||
namespace Jrd {
|
||||
class DeferredWork;
|
||||
class jrd_tra;
|
||||
class jrd_rel;
|
||||
struct index_desc;
|
||||
}
|
||||
|
||||
void PCMET_expression_index(Jrd::thread_db*, const Firebird::MetaName&, USHORT&, Jrd::jrd_tra*);
|
||||
void PCMET_lookup_index(Jrd::thread_db*, Jrd::jrd_rel*, Jrd::index_desc*);
|
||||
|
||||
#endif // JRD_PCMET_PROTO_H
|
Loading…
Reference in New Issue
Block a user