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 |