"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/jrd/RecordSourceNodes.cpp" between
Firebird-3.0.2.32703-0.tar.bz2 and Firebird-3.0.4.33054-0.tar.bz2

About: Firebird is a relational database offering many ANSI SQL standard features.

RecordSourceNodes.cpp  (Firebird-3.0.2.32703-0.tar.bz2):RecordSourceNodes.cpp  (Firebird-3.0.4.33054-0.tar.bz2)
skipping to change at line 518 skipping to change at line 518
MET_scan_relation(tdbb, node->relation); MET_scan_relation(tdbb, node->relation);
} }
else if (node->relation->rel_flags & REL_sys_triggers) else if (node->relation->rel_flags & REL_sys_triggers)
MET_parse_sys_trigger(tdbb, node->relation); MET_parse_sys_trigger(tdbb, node->relation);
// generate a stream for the relation reference, assuming it is a real re ference // generate a stream for the relation reference, assuming it is a real re ference
if (parseContext) if (parseContext)
{ {
node->stream = PAR_context(csb, &node->context); node->stream = PAR_context(csb, &node->context);
fb_assert(node->stream <= MAX_STREAMS);
csb->csb_rpt[node->stream].csb_relation = node->relation; csb->csb_rpt[node->stream].csb_relation = node->relation;
csb->csb_rpt[node->stream].csb_alias = aliasString; csb->csb_rpt[node->stream].csb_alias = aliasString;
if (csb->csb_g_flags & csb_get_dependencies) if (csb->csb_g_flags & csb_get_dependencies)
PAR_dependency(tdbb, csb, node->stream, (SSHORT) -1, ""); PAR_dependency(tdbb, csb, node->stream, (SSHORT) -1, "");
} }
else else
delete aliasString; delete aliasString;
skipping to change at line 586 skipping to change at line 585
} }
RelationSourceNode* RelationSourceNode::copy(thread_db* tdbb, NodeCopier& copier ) const RelationSourceNode* RelationSourceNode::copy(thread_db* tdbb, NodeCopier& copier ) const
{ {
if (!copier.remap) if (!copier.remap)
BUGCHECK(221); // msg 221 (CMP) copy: cannot remap BUGCHECK(221); // msg 221 (CMP) copy: cannot remap
RelationSourceNode* newSource = FB_NEW_POOL(*tdbb->getDefaultPool()) Rela tionSourceNode( RelationSourceNode* newSource = FB_NEW_POOL(*tdbb->getDefaultPool()) Rela tionSourceNode(
*tdbb->getDefaultPool()); *tdbb->getDefaultPool());
// Last entry in the remap contains the the original stream number.
// Get that stream number so that the flags can be copied
// into the newly created child stream.
const StreamType relativeStream = stream ? copier.remap[stream - 1] : str
eam;
newSource->stream = copier.csb->nextStream(); newSource->stream = copier.csb->nextStream();
copier.remap[stream] = newSource->stream; copier.remap[stream] = newSource->stream;
newSource->context = context; newSource->context = context;
newSource->relation = relation; newSource->relation = relation;
newSource->view = view; newSource->view = view;
CompilerScratch::csb_repeat* element = CMP_csb_element(copier.csb, newSou rce->stream); CompilerScratch::csb_repeat* element = CMP_csb_element(copier.csb, newSou rce->stream);
element->csb_relation = newSource->relation; element->csb_relation = newSource->relation;
element->csb_view = newSource->view; element->csb_view = newSource->view;
element->csb_view_stream = copier.remap[0]; element->csb_view_stream = copier.remap[0];
/*
If there was a parent stream no., then copy the flags
from that stream to its children streams. (Bug 10164/10166)
For e.g. consider a view V1 with 2 streams:
stream #1 from table T1
stream #2 from table T2
consider a procedure P1 with 2 streams:
stream #1 from table X
stream #2 from view V1
During pass1 of procedure request, the engine tries to expand
all the views into their base tables. It creates a compiler
scratch block which initially looks like this:
stream 1 -------- X
stream 2 -------- V1
while expanding V1 the engine calls copy() with nod_relation.
A new stream 3 is created. Now the CompilerScratch looks like:
stream 1 -------- X
stream 2 -------- V1 map [2,3,4]
stream 3 -------- T1
stream 4 -------- T2
After T1 stream has been created the flags are copied from
stream #1 because V1's definition said the original stream
number for T1 was 1. However since its being merged with
the procedure request, stream #1 belongs to a different table.
The flags should be copied from stream 2 i.e. V1.
Since we didn't do this properly before, V1's children got
tagged with whatever flags X possesed leading to various
errors.
*/
copier.csb->inheritViewFlags(newSource->stream, csb_no_dbkey);
if (alias.hasData()) if (alias.hasData())
{ {
element->csb_alias = FB_NEW_POOL(*tdbb->getDefaultPool()) element->csb_alias = FB_NEW_POOL(*tdbb->getDefaultPool())
string(*tdbb->getDefaultPool(), alias); string(*tdbb->getDefaultPool(), alias);
} }
/** If there was a parent stream no., then copy the flags
from that stream to its children streams. (Bug 10164/10166)
For e.g.
consider a view V1 with 2 streams
stream #1 from table T1
stream #2 from table T2
consider a procedure P1 with 2 streams
stream #1 from table X
stream #2 from view V1
During pass1 of procedure request, the engine tries to expand
all the views into their base tables. It creates a compiler
scratch block which initially looks like this
stream 1 -------- X
stream 2 -------- V1
while expanding V1 the engine calls copy() with nod_relat
ion.
A new stream 3 is created. Now the CompilerScratch looks
like
stream 1 -------- X
stream 2 -------- V1 map [2,3]
stream 3 -------- T1
After T1 stream has been created the flags are copied fro
m
stream #1 because V1's definition said the original strea
m
number for T1 was 1. However since its being merged with
the procedure request, stream #1 belongs to a different t
able.
The flags should be copied from stream 2 i.e. V1. We can
get
this info from variable remap.
Since we didn't do this properly before, V1's children go
t
tagged with whatever flags X possesed leading to various
errors.
We now store the proper stream no in relativeStream and
later use it to copy the flags. -Sudesh (03/05/99)
**/
copier.csb->csb_rpt[newSource->stream].csb_flags |=
copier.csb->csb_rpt[relativeStream].csb_flags & csb_no_dbkey;
return newSource; return newSource;
} }
void RelationSourceNode::ignoreDbKey(thread_db* tdbb, CompilerScratch* csb) cons t void RelationSourceNode::ignoreDbKey(thread_db* tdbb, CompilerScratch* csb) cons t
{ {
csb->csb_rpt[stream].csb_flags |= csb_no_dbkey; csb->csb_rpt[stream].csb_flags |= csb_no_dbkey;
const CompilerScratch::csb_repeat* tail = &csb->csb_rpt[stream]; const CompilerScratch::csb_repeat* tail = &csb->csb_rpt[stream];
const jrd_rel* relation = tail->csb_relation; const jrd_rel* relation = tail->csb_relation;
if (relation) if (relation)
skipping to change at line 683 skipping to change at line 680
jrd_rel* const parentView = csb->csb_view; jrd_rel* const parentView = csb->csb_view;
const StreamType viewStream = csb->csb_view_stream; const StreamType viewStream = csb->csb_view_stream;
jrd_rel* relationView = relation; jrd_rel* relationView = relation;
CMP_post_resource(&csb->csb_resources, relationView, Resource::rsc_relati on, relationView->rel_id); CMP_post_resource(&csb->csb_resources, relationView, Resource::rsc_relati on, relationView->rel_id);
view = parentView; view = parentView;
CompilerScratch::csb_repeat* const element = CMP_csb_element(csb, stream) ; CompilerScratch::csb_repeat* const element = CMP_csb_element(csb, stream) ;
element->csb_view = parentView; element->csb_view = parentView;
fb_assert(viewStream <= MAX_STREAMS);
element->csb_view_stream = viewStream; element->csb_view_stream = viewStream;
// in the case where there is a parent view, find the context name // in the case where there is a parent view, find the context name
if (parentView) if (parentView)
{ {
const ViewContexts& ctx = parentView->rel_view_contexts; const ViewContexts& ctx = parentView->rel_view_contexts;
const USHORT key = context; const USHORT key = context;
FB_SIZE_T pos; FB_SIZE_T pos;
skipping to change at line 805 skipping to change at line 801
*boolean = andNode; *boolean = andNode;
} }
else else
*boolean = node; *boolean = node;
} }
} }
void RelationSourceNode::pass2Rse(thread_db* tdbb, CompilerScratch* csb) void RelationSourceNode::pass2Rse(thread_db* tdbb, CompilerScratch* csb)
{ {
fb_assert(stream <= MAX_STREAMS);
csb->csb_rpt[stream].activate(); csb->csb_rpt[stream].activate();
pass2(tdbb, csb); pass2(tdbb, csb);
} }
RecordSource* RelationSourceNode::compile(thread_db* tdbb, OptimizerBlk* opt, bo ol /*innerSubStream*/) RecordSource* RelationSourceNode::compile(thread_db* tdbb, OptimizerBlk* opt, bo ol /*innerSubStream*/)
{ {
// we have found a base relation; record its stream // we have found a base relation; record its stream
// number in the streams array as a candidate for // number in the streams array as a candidate for
// merging into a river // merging into a river
skipping to change at line 1078 skipping to change at line 1073
} }
ProcedureSourceNode* ProcedureSourceNode::copy(thread_db* tdbb, NodeCopier& copi er) const ProcedureSourceNode* ProcedureSourceNode::copy(thread_db* tdbb, NodeCopier& copi er) const
{ {
if (!copier.remap) if (!copier.remap)
BUGCHECK(221); // msg 221 (CMP) copy: cannot remap BUGCHECK(221); // msg 221 (CMP) copy: cannot remap
ProcedureSourceNode* newSource = FB_NEW_POOL(*tdbb->getDefaultPool()) Pro cedureSourceNode( ProcedureSourceNode* newSource = FB_NEW_POOL(*tdbb->getDefaultPool()) Pro cedureSourceNode(
*tdbb->getDefaultPool()); *tdbb->getDefaultPool());
if (isSubRoutine)
newSource->procedure = procedure;
else
{
newSource->procedure = MET_lookup_procedure_id(tdbb, procedureId,
false, false, 0);
if (!newSource->procedure)
{
string name;
name.printf("id %d", procedureId);
delete newSource;
ERR_post(Arg::Gds(isc_prcnotdef) << name);
}
}
// dimitr: See the appropriate code and comment in NodeCopier (in nod_arg ument). // dimitr: See the appropriate code and comment in NodeCopier (in nod_arg ument).
// We must copy the message first and only then use the new pointer to // We must copy the message first and only then use the new pointer to
// copy the inputs properly. // copy the inputs properly.
newSource->in_msg = copier.copy(tdbb, in_msg); newSource->in_msg = copier.copy(tdbb, in_msg);
{ // scope { // scope
AutoSetRestore<MessageNode*> autoMessage(&copier.message, newSour ce->in_msg); AutoSetRestore<MessageNode*> autoMessage(&copier.message, newSour ce->in_msg);
newSource->sourceList = copier.copy(tdbb, sourceList); newSource->sourceList = copier.copy(tdbb, sourceList);
newSource->targetList = copier.copy(tdbb, targetList); newSource->targetList = copier.copy(tdbb, targetList);
} }
newSource->stream = copier.csb->nextStream(); newSource->stream = copier.csb->nextStream();
copier.remap[stream] = newSource->stream; copier.remap[stream] = newSource->stream;
newSource->context = context; newSource->context = context;
newSource->procedure = isSubRoutine ? procedure :
MET_lookup_procedure_id(tdbb, procedureId, false, false, 0);
newSource->isSubRoutine = isSubRoutine; newSource->isSubRoutine = isSubRoutine;
newSource->procedureId = procedureId; newSource->procedureId = procedureId;
newSource->view = view; newSource->view = view;
CompilerScratch::csb_repeat* element = CMP_csb_element(copier.csb, newSou rce->stream); CompilerScratch::csb_repeat* element = CMP_csb_element(copier.csb, newSou rce->stream);
element->csb_procedure = newSource->procedure; element->csb_procedure = newSource->procedure;
element->csb_view = newSource->view; element->csb_view = newSource->view;
element->csb_view_stream = copier.remap[0]; element->csb_view_stream = copier.remap[0];
// dimitr: I doubt we need to inherit this flag for procedures.
// They don't have a DBKEY to be concatenated.
// Neither they have a stream map to be expanded.
copier.csb->inheritViewFlags(newSource->stream, csb_no_dbkey);
if (alias.hasData()) if (alias.hasData())
{ {
element->csb_alias = FB_NEW_POOL(*tdbb->getDefaultPool()) element->csb_alias = FB_NEW_POOL(*tdbb->getDefaultPool())
string(*tdbb->getDefaultPool(), alias); string(*tdbb->getDefaultPool(), alias);
} }
copier.csb->csb_rpt[newSource->stream].csb_flags |=
copier.csb->csb_rpt[stream].csb_flags & csb_no_dbkey;
return newSource; return newSource;
} }
RecordSourceNode* ProcedureSourceNode::pass1(thread_db* tdbb, CompilerScratch* c sb) RecordSourceNode* ProcedureSourceNode::pass1(thread_db* tdbb, CompilerScratch* c sb)
{ {
doPass1(tdbb, csb, sourceList.getAddress()); doPass1(tdbb, csb, sourceList.getAddress());
doPass1(tdbb, csb, targetList.getAddress()); doPass1(tdbb, csb, targetList.getAddress());
doPass1(tdbb, csb, in_msg.getAddress()); doPass1(tdbb, csb, in_msg.getAddress());
return this; return this;
} }
skipping to change at line 1142 skipping to change at line 1151
CMP_post_procedure_access(tdbb, csb, procedure); CMP_post_procedure_access(tdbb, csb, procedure);
CMP_post_resource(&csb->csb_resources, procedure, Resource::rsc_p rocedure, procedureId); CMP_post_resource(&csb->csb_resources, procedure, Resource::rsc_p rocedure, procedureId);
} }
jrd_rel* const parentView = csb->csb_view; jrd_rel* const parentView = csb->csb_view;
const StreamType viewStream = csb->csb_view_stream; const StreamType viewStream = csb->csb_view_stream;
view = parentView; view = parentView;
CompilerScratch::csb_repeat* const element = CMP_csb_element(csb, stream) ; CompilerScratch::csb_repeat* const element = CMP_csb_element(csb, stream) ;
element->csb_view = parentView; element->csb_view = parentView;
fb_assert(viewStream <= MAX_STREAMS);
element->csb_view_stream = viewStream; element->csb_view_stream = viewStream;
// in the case where there is a parent view, find the context name // in the case where there is a parent view, find the context name
if (parentView) if (parentView)
{ {
const ViewContexts& ctx = parentView->rel_view_contexts; const ViewContexts& ctx = parentView->rel_view_contexts;
const USHORT key = context; const USHORT key = context;
FB_SIZE_T pos; FB_SIZE_T pos;
skipping to change at line 1171 skipping to change at line 1179
RecordSourceNode* ProcedureSourceNode::pass2(thread_db* tdbb, CompilerScratch* c sb) RecordSourceNode* ProcedureSourceNode::pass2(thread_db* tdbb, CompilerScratch* c sb)
{ {
ExprNode::doPass2(tdbb, csb, sourceList.getAddress()); ExprNode::doPass2(tdbb, csb, sourceList.getAddress());
ExprNode::doPass2(tdbb, csb, targetList.getAddress()); ExprNode::doPass2(tdbb, csb, targetList.getAddress());
ExprNode::doPass2(tdbb, csb, in_msg.getAddress()); ExprNode::doPass2(tdbb, csb, in_msg.getAddress());
return this; return this;
} }
void ProcedureSourceNode::pass2Rse(thread_db* tdbb, CompilerScratch* csb) void ProcedureSourceNode::pass2Rse(thread_db* tdbb, CompilerScratch* csb)
{ {
fb_assert(stream <= MAX_STREAMS);
csb->csb_rpt[stream].activate(); csb->csb_rpt[stream].activate();
pass2(tdbb, csb); pass2(tdbb, csb);
} }
RecordSource* ProcedureSourceNode::compile(thread_db* tdbb, OptimizerBlk* opt, b ool /*innerSubStream*/) RecordSource* ProcedureSourceNode::compile(thread_db* tdbb, OptimizerBlk* opt, b ool /*innerSubStream*/)
{ {
opt->beds.add(stream); opt->beds.add(stream);
opt->localStreams.add(stream); opt->localStreams.add(stream);
skipping to change at line 1242 skipping to change at line 1249
// Parse an aggregate reference. // Parse an aggregate reference.
AggregateSourceNode* AggregateSourceNode::parse(thread_db* tdbb, CompilerScratch * csb) AggregateSourceNode* AggregateSourceNode::parse(thread_db* tdbb, CompilerScratch * csb)
{ {
SET_TDBB(tdbb); SET_TDBB(tdbb);
AggregateSourceNode* node = FB_NEW_POOL(*tdbb->getDefaultPool()) Aggregat eSourceNode( AggregateSourceNode* node = FB_NEW_POOL(*tdbb->getDefaultPool()) Aggregat eSourceNode(
*tdbb->getDefaultPool()); *tdbb->getDefaultPool());
node->stream = PAR_context(csb, NULL); node->stream = PAR_context(csb, NULL);
fb_assert(node->stream <= MAX_STREAMS);
node->rse = PAR_rse(tdbb, csb); node->rse = PAR_rse(tdbb, csb);
node->group = PAR_sort(tdbb, csb, blr_group_by, true); node->group = PAR_sort(tdbb, csb, blr_group_by, true);
node->map = parseMap(tdbb, csb, node->stream); node->map = parseMap(tdbb, csb, node->stream);
return node; return node;
} }
string AggregateSourceNode::internalPrint(NodePrinter& printer) const string AggregateSourceNode::internalPrint(NodePrinter& printer) const
{ {
RecordSourceNode::internalPrint(printer); RecordSourceNode::internalPrint(printer);
skipping to change at line 1411 skipping to change at line 1417
} }
AggregateSourceNode* AggregateSourceNode::copy(thread_db* tdbb, NodeCopier& copi er) const AggregateSourceNode* AggregateSourceNode::copy(thread_db* tdbb, NodeCopier& copi er) const
{ {
if (!copier.remap) if (!copier.remap)
BUGCHECK(221); // msg 221 (CMP) copy: cannot remap BUGCHECK(221); // msg 221 (CMP) copy: cannot remap
AggregateSourceNode* newSource = FB_NEW_POOL(*tdbb->getDefaultPool()) Agg regateSourceNode( AggregateSourceNode* newSource = FB_NEW_POOL(*tdbb->getDefaultPool()) Agg regateSourceNode(
*tdbb->getDefaultPool()); *tdbb->getDefaultPool());
fb_assert(stream <= MAX_STREAMS);
newSource->stream = copier.csb->nextStream(); newSource->stream = copier.csb->nextStream();
// fb_assert(newSource->stream <= MAX_UCHAR);
copier.remap[stream] = newSource->stream; copier.remap[stream] = newSource->stream;
CMP_csb_element(copier.csb, newSource->stream); CMP_csb_element(copier.csb, newSource->stream);
copier.csb->csb_rpt[newSource->stream].csb_flags |= copier.csb->inheritViewFlags(newSource->stream, csb_no_dbkey);
copier.csb->csb_rpt[stream].csb_flags & csb_no_dbkey;
newSource->rse = rse->copy(tdbb, copier); newSource->rse = rse->copy(tdbb, copier);
if (group) if (group)
newSource->group = group->copy(tdbb, copier); newSource->group = group->copy(tdbb, copier);
newSource->map = map->copy(tdbb, copier); newSource->map = map->copy(tdbb, copier);
return newSource; return newSource;
} }
void AggregateSourceNode::ignoreDbKey(thread_db* tdbb, CompilerScratch* csb) con st void AggregateSourceNode::ignoreDbKey(thread_db* tdbb, CompilerScratch* csb) con st
{ {
rse->ignoreDbKey(tdbb, csb); rse->ignoreDbKey(tdbb, csb);
} }
RecordSourceNode* AggregateSourceNode::pass1(thread_db* tdbb, CompilerScratch* c sb) RecordSourceNode* AggregateSourceNode::pass1(thread_db* tdbb, CompilerScratch* c sb)
{ {
fb_assert(stream <= MAX_STREAMS);
csb->csb_rpt[stream].csb_flags |= csb_no_dbkey; csb->csb_rpt[stream].csb_flags |= csb_no_dbkey;
rse->ignoreDbKey(tdbb, csb); rse->ignoreDbKey(tdbb, csb);
doPass1(tdbb, csb, rse.getAddress()); doPass1(tdbb, csb, rse.getAddress());
doPass1(tdbb, csb, map.getAddress()); doPass1(tdbb, csb, map.getAddress());
doPass1(tdbb, csb, group.getAddress()); doPass1(tdbb, csb, group.getAddress());
return this; return this;
} }
void AggregateSourceNode::pass1Source(thread_db* tdbb, CompilerScratch* csb, Rse Node* /*rse*/, void AggregateSourceNode::pass1Source(thread_db* tdbb, CompilerScratch* csb, Rse Node* /*rse*/,
BoolExprNode** /*boolean*/, RecordSourceNodeStack& stack) BoolExprNode** /*boolean*/, RecordSourceNodeStack& stack)
{ {
stack.push(this); // Assume that the source will be used. Push it o n the final stream stack. stack.push(this); // Assume that the source will be used. Push it o n the final stream stack.
fb_assert(stream <= MAX_STREAMS);
pass1(tdbb, csb); pass1(tdbb, csb);
jrd_rel* const parentView = csb->csb_view; jrd_rel* const parentView = csb->csb_view;
const StreamType viewStream = csb->csb_view_stream; const StreamType viewStream = csb->csb_view_stream;
CompilerScratch::csb_repeat* const element = CMP_csb_element(csb, stream) ; CompilerScratch::csb_repeat* const element = CMP_csb_element(csb, stream) ;
element->csb_view = parentView; element->csb_view = parentView;
fb_assert(viewStream <= MAX_STREAMS);
element->csb_view_stream = viewStream; element->csb_view_stream = viewStream;
} }
RecordSourceNode* AggregateSourceNode::pass2(thread_db* tdbb, CompilerScratch* c sb) RecordSourceNode* AggregateSourceNode::pass2(thread_db* tdbb, CompilerScratch* c sb)
{ {
rse->pass2Rse(tdbb, csb); rse->pass2Rse(tdbb, csb);
ExprNode::doPass2(tdbb, csb, map.getAddress()); ExprNode::doPass2(tdbb, csb, map.getAddress());
ExprNode::doPass2(tdbb, csb, group.getAddress()); ExprNode::doPass2(tdbb, csb, group.getAddress());
fb_assert(stream <= MAX_STREAMS);
processMap(tdbb, csb, map, &csb->csb_rpt[stream].csb_internal_format); processMap(tdbb, csb, map, &csb->csb_rpt[stream].csb_internal_format);
csb->csb_rpt[stream].csb_format = csb->csb_rpt[stream].csb_internal_forma t; csb->csb_rpt[stream].csb_format = csb->csb_rpt[stream].csb_internal_forma t;
return this; return this;
} }
void AggregateSourceNode::pass2Rse(thread_db* tdbb, CompilerScratch* csb) void AggregateSourceNode::pass2Rse(thread_db* tdbb, CompilerScratch* csb)
{ {
fb_assert(stream <= MAX_STREAMS);
csb->csb_rpt[stream].activate(); csb->csb_rpt[stream].activate();
pass2(tdbb, csb); pass2(tdbb, csb);
} }
bool AggregateSourceNode::containsStream(StreamType checkStream) const bool AggregateSourceNode::containsStream(StreamType checkStream) const
{ {
// for aggregates, check current RseNode, if not found then check // for aggregates, check current RseNode, if not found then check
// the sub-rse // the sub-rse
skipping to change at line 1606 skipping to change at line 1603
// Make the node, parse the context number, get a stream assigned, // Make the node, parse the context number, get a stream assigned,
// and get the number of sub-RseNode's. // and get the number of sub-RseNode's.
UnionSourceNode* node = FB_NEW_POOL(*tdbb->getDefaultPool()) UnionSourceN ode( UnionSourceNode* node = FB_NEW_POOL(*tdbb->getDefaultPool()) UnionSourceN ode(
*tdbb->getDefaultPool()); *tdbb->getDefaultPool());
node->recursive = blrOp == blr_recurse; node->recursive = blrOp == blr_recurse;
node->stream = PAR_context(csb, NULL); node->stream = PAR_context(csb, NULL);
fb_assert(node->stream <= MAX_STREAMS);
// assign separate context for mapped record if union is recursive // assign separate context for mapped record if union is recursive
StreamType stream2 = node->stream; StreamType stream2 = node->stream;
if (node->recursive) if (node->recursive)
{ {
stream2 = PAR_context(csb, 0); stream2 = PAR_context(csb, 0);
node->mapStream = stream2; node->mapStream = stream2;
} }
skipping to change at line 1740 skipping to change at line 1736
UnionSourceNode* UnionSourceNode::copy(thread_db* tdbb, NodeCopier& copier) cons t UnionSourceNode* UnionSourceNode::copy(thread_db* tdbb, NodeCopier& copier) cons t
{ {
if (!copier.remap) if (!copier.remap)
BUGCHECK(221); // msg 221 (CMP) copy: cannot remap BUGCHECK(221); // msg 221 (CMP) copy: cannot remap
UnionSourceNode* newSource = FB_NEW_POOL(*tdbb->getDefaultPool()) UnionSo urceNode( UnionSourceNode* newSource = FB_NEW_POOL(*tdbb->getDefaultPool()) UnionSo urceNode(
*tdbb->getDefaultPool()); *tdbb->getDefaultPool());
newSource->recursive = recursive; newSource->recursive = recursive;
fb_assert(stream <= MAX_STREAMS);
newSource->stream = copier.csb->nextStream(); newSource->stream = copier.csb->nextStream();
copier.remap[stream] = newSource->stream; copier.remap[stream] = newSource->stream;
CMP_csb_element(copier.csb, newSource->stream); CMP_csb_element(copier.csb, newSource->stream);
StreamType oldStream = stream; copier.csb->inheritViewFlags(newSource->stream, csb_no_dbkey);
StreamType newStream = newSource->stream;
if (newSource->recursive) if (newSource->recursive)
{ {
oldStream = mapStream; newSource->mapStream = copier.csb->nextStream();
fb_assert(oldStream <= MAX_STREAMS); copier.remap[mapStream] = newSource->mapStream;
newStream = copier.csb->nextStream(); CMP_csb_element(copier.csb, newSource->mapStream);
newSource->mapStream = newStream;
copier.remap[oldStream] = newStream;
CMP_csb_element(copier.csb, newStream);
}
copier.csb->csb_rpt[newStream].csb_flags |= copier.csb->inheritViewFlags(newSource->mapStream, csb_no_dbkey);
copier.csb->csb_rpt[oldStream].csb_flags & csb_no_dbkey; }
const NestConst<RseNode>* ptr = clauses.begin(); const NestConst<RseNode>* ptr = clauses.begin();
const NestConst<MapNode>* ptr2 = maps.begin(); const NestConst<MapNode>* ptr2 = maps.begin();
for (const NestConst<RseNode>* const end = clauses.end(); ptr != end; ++p tr, ++ptr2) for (const NestConst<RseNode>* const end = clauses.end(); ptr != end; ++p tr, ++ptr2)
{ {
newSource->clauses.add((*ptr)->copy(tdbb, copier)); newSource->clauses.add((*ptr)->copy(tdbb, copier));
newSource->maps.add((*ptr2)->copy(tdbb, copier)); newSource->maps.add((*ptr2)->copy(tdbb, copier));
} }
skipping to change at line 1800 skipping to change at line 1790
{ {
doPass1(tdbb, csb, ptr->getAddress()); doPass1(tdbb, csb, ptr->getAddress());
doPass1(tdbb, csb, ptr2->getAddress()); doPass1(tdbb, csb, ptr2->getAddress());
} }
jrd_rel* const parentView = csb->csb_view; jrd_rel* const parentView = csb->csb_view;
const StreamType viewStream = csb->csb_view_stream; const StreamType viewStream = csb->csb_view_stream;
CompilerScratch::csb_repeat* const element = CMP_csb_element(csb, stream) ; CompilerScratch::csb_repeat* const element = CMP_csb_element(csb, stream) ;
element->csb_view = parentView; element->csb_view = parentView;
fb_assert(viewStream <= MAX_STREAMS);
element->csb_view_stream = viewStream; element->csb_view_stream = viewStream;
} }
// Process a union clause of a RseNode. // Process a union clause of a RseNode.
RecordSourceNode* UnionSourceNode::pass2(thread_db* tdbb, CompilerScratch* csb) RecordSourceNode* UnionSourceNode::pass2(thread_db* tdbb, CompilerScratch* csb)
{ {
SET_TDBB(tdbb); SET_TDBB(tdbb);
// make up a format block sufficiently large to hold instantiated record // make up a format block sufficiently large to hold instantiated record
skipping to change at line 1835 skipping to change at line 1824
} }
if (recursive) if (recursive)
csb->csb_rpt[mapStream].csb_format = *format; csb->csb_rpt[mapStream].csb_format = *format;
return this; return this;
} }
void UnionSourceNode::pass2Rse(thread_db* tdbb, CompilerScratch* csb) void UnionSourceNode::pass2Rse(thread_db* tdbb, CompilerScratch* csb)
{ {
fb_assert(stream <= MAX_STREAMS);
csb->csb_rpt[stream].activate(); csb->csb_rpt[stream].activate();
pass2(tdbb, csb); pass2(tdbb, csb);
} }
bool UnionSourceNode::containsStream(StreamType checkStream) const bool UnionSourceNode::containsStream(StreamType checkStream) const
{ {
// for unions, check current RseNode, if not found then check // for unions, check current RseNode, if not found then check
// all sub-rse's // all sub-rse's
skipping to change at line 2026 skipping to change at line 2014
WindowSourceNode* newSource = FB_NEW_POOL(*tdbb->getDefaultPool()) Window SourceNode( WindowSourceNode* newSource = FB_NEW_POOL(*tdbb->getDefaultPool()) Window SourceNode(
*tdbb->getDefaultPool()); *tdbb->getDefaultPool());
newSource->rse = rse->copy(tdbb, copier); newSource->rse = rse->copy(tdbb, copier);
for (ObjectsArray<Partition>::const_iterator inputPartition = partitions. begin(); for (ObjectsArray<Partition>::const_iterator inputPartition = partitions. begin();
inputPartition != partitions.end(); inputPartition != partitions.end();
++inputPartition) ++inputPartition)
{ {
fb_assert(inputPartition->stream <= MAX_STREAMS);
Partition& copyPartition = newSource->partitions.add(); Partition& copyPartition = newSource->partitions.add();
copyPartition.stream = copier.csb->nextStream(); copyPartition.stream = copier.csb->nextStream();
// fb_assert(copyPartition.stream <= MAX_UCHAR);
copier.remap[inputPartition->stream] = copyPartition.stream; copier.remap[inputPartition->stream] = copyPartition.stream;
CMP_csb_element(copier.csb, copyPartition.stream); CMP_csb_element(copier.csb, copyPartition.stream);
copier.csb->inheritViewFlags(copyPartition.stream, csb_no_dbkey);
if (inputPartition->group) if (inputPartition->group)
copyPartition.group = inputPartition->group->copy(tdbb, c opier); copyPartition.group = inputPartition->group->copy(tdbb, c opier);
if (inputPartition->regroup) if (inputPartition->regroup)
copyPartition.regroup = inputPartition->regroup->copy(tdb b, copier); copyPartition.regroup = inputPartition->regroup->copy(tdb b, copier);
if (inputPartition->order) if (inputPartition->order)
copyPartition.order = inputPartition->order->copy(tdbb, c opier); copyPartition.order = inputPartition->order->copy(tdbb, c opier);
copyPartition.map = inputPartition->map->copy(tdbb, copier); copyPartition.map = inputPartition->map->copy(tdbb, copier);
} }
return newSource; return newSource;
skipping to change at line 2059 skipping to change at line 2046
{ {
rse->ignoreDbKey(tdbb, csb); rse->ignoreDbKey(tdbb, csb);
} }
RecordSourceNode* WindowSourceNode::pass1(thread_db* tdbb, CompilerScratch* csb) RecordSourceNode* WindowSourceNode::pass1(thread_db* tdbb, CompilerScratch* csb)
{ {
for (ObjectsArray<Partition>::iterator partition = partitions.begin(); for (ObjectsArray<Partition>::iterator partition = partitions.begin();
partition != partitions.end(); partition != partitions.end();
++partition) ++partition)
{ {
fb_assert(partition->stream <= MAX_STREAMS);
csb->csb_rpt[partition->stream].csb_flags |= csb_no_dbkey; csb->csb_rpt[partition->stream].csb_flags |= csb_no_dbkey;
} }
rse->ignoreDbKey(tdbb, csb); rse->ignoreDbKey(tdbb, csb);
doPass1(tdbb, csb, rse.getAddress()); doPass1(tdbb, csb, rse.getAddress());
for (ObjectsArray<Partition>::iterator partition = partitions.begin(); for (ObjectsArray<Partition>::iterator partition = partitions.begin();
partition != partitions.end(); partition != partitions.end();
++partition) ++partition)
{ {
skipping to change at line 2088 skipping to change at line 2074
void WindowSourceNode::pass1Source(thread_db* tdbb, CompilerScratch* csb, RseNod e* /*rse*/, void WindowSourceNode::pass1Source(thread_db* tdbb, CompilerScratch* csb, RseNod e* /*rse*/,
BoolExprNode** /*boolean*/, RecordSourceNodeStack& stack) BoolExprNode** /*boolean*/, RecordSourceNodeStack& stack)
{ {
stack.push(this); // Assume that the source will be used. Push it o n the final stream stack. stack.push(this); // Assume that the source will be used. Push it o n the final stream stack.
pass1(tdbb, csb); pass1(tdbb, csb);
jrd_rel* const parentView = csb->csb_view; jrd_rel* const parentView = csb->csb_view;
const StreamType viewStream = csb->csb_view_stream; const StreamType viewStream = csb->csb_view_stream;
fb_assert(viewStream <= MAX_STREAMS);
for (ObjectsArray<Partition>::iterator partition = partitions.begin(); for (ObjectsArray<Partition>::iterator partition = partitions.begin();
partition != partitions.end(); partition != partitions.end();
++partition) ++partition)
{ {
CompilerScratch::csb_repeat* const element = CMP_csb_element(csb, partition->stream); CompilerScratch::csb_repeat* const element = CMP_csb_element(csb, partition->stream);
element->csb_view = parentView; element->csb_view = parentView;
element->csb_view_stream = viewStream; element->csb_view_stream = viewStream;
} }
} }
skipping to change at line 2112 skipping to change at line 2097
rse->pass2Rse(tdbb, csb); rse->pass2Rse(tdbb, csb);
for (ObjectsArray<Partition>::iterator partition = partitions.begin(); for (ObjectsArray<Partition>::iterator partition = partitions.begin();
partition != partitions.end(); partition != partitions.end();
++partition) ++partition)
{ {
ExprNode::doPass2(tdbb, csb, partition->map.getAddress()); ExprNode::doPass2(tdbb, csb, partition->map.getAddress());
ExprNode::doPass2(tdbb, csb, partition->group.getAddress()); ExprNode::doPass2(tdbb, csb, partition->group.getAddress());
ExprNode::doPass2(tdbb, csb, partition->order.getAddress()); ExprNode::doPass2(tdbb, csb, partition->order.getAddress());
fb_assert(partition->stream <= MAX_STREAMS);
processMap(tdbb, csb, partition->map, &csb->csb_rpt[partition->st ream].csb_internal_format); processMap(tdbb, csb, partition->map, &csb->csb_rpt[partition->st ream].csb_internal_format);
csb->csb_rpt[partition->stream].csb_format = csb->csb_rpt[partition->stream].csb_format =
csb->csb_rpt[partition->stream].csb_internal_format; csb->csb_rpt[partition->stream].csb_internal_format;
} }
for (ObjectsArray<Partition>::iterator partition = partitions.begin(); for (ObjectsArray<Partition>::iterator partition = partitions.begin();
partition != partitions.end(); partition != partitions.end();
++partition) ++partition)
{ {
ExprNode::doPass2(tdbb, csb, partition->regroup.getAddress()); ExprNode::doPass2(tdbb, csb, partition->regroup.getAddress());
 End of changes. 34 change blocks. 
94 lines changed or deleted 70 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)