mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-22 22:43:03 +01:00
Adjustments as per Adriano's comments
This commit is contained in:
parent
36d011f731
commit
1c2470c4cc
@ -1582,7 +1582,7 @@ BoolExprNode* RseBoolNode::pass1(thread_db* tdbb, CompilerScratch* csb)
|
||||
|
||||
void RseBoolNode::pass2Boolean1(thread_db* tdbb, CompilerScratch* csb)
|
||||
{
|
||||
if (!(rse->flags & RseNode::FLAG_VARIANT))
|
||||
if (rse->isInvariant())
|
||||
{
|
||||
nodFlags |= FLAG_INVARIANT;
|
||||
csb->csb_invariants.push(&impureOffset);
|
||||
|
@ -11321,7 +11321,7 @@ ValueExprNode* SubQueryNode::pass2(thread_db* tdbb, CompilerScratch* csb)
|
||||
if (!rse)
|
||||
ERR_post(Arg::Gds(isc_wish_list));
|
||||
|
||||
if (!(rse->flags & RseNode::FLAG_VARIANT))
|
||||
if (rse->isInvariant())
|
||||
{
|
||||
nodFlags |= FLAG_INVARIANT;
|
||||
csb->csb_invariants.push(&impureOffset);
|
||||
|
@ -5077,7 +5077,7 @@ StmtNode* ForNode::pass2(thread_db* tdbb, CompilerScratch* csb)
|
||||
|
||||
csb->csb_fors.add(cursor);
|
||||
|
||||
if (rse->flags & RseNode::FLAG_WRITELOCK)
|
||||
if (rse->hasWriteLock())
|
||||
withLock = true;
|
||||
|
||||
if (marks & MARK_MERGE)
|
||||
|
@ -547,10 +547,10 @@ void GEN_rse(DsqlCompilerScratch* dsqlScratch, RseNode* rse)
|
||||
for (const NestConst<RecordSourceNode>* const end = rse->dsqlStreams->items.end(); ptr != end; ++ptr)
|
||||
GEN_expr(dsqlScratch, *ptr);
|
||||
|
||||
if (rse->flags & RseNode::FLAG_WRITELOCK)
|
||||
if (rse->hasWriteLock())
|
||||
dsqlScratch->appendUChar(blr_writelock);
|
||||
|
||||
if (rse->flags & RseNode::FLAG_SKIP_LOCKED)
|
||||
if (rse->hasSkipLocked())
|
||||
dsqlScratch->appendUChar(blr_skip_locked);
|
||||
|
||||
if (rse->dsqlFirst)
|
||||
|
@ -2177,13 +2177,13 @@ static RseNode* pass1_rse_impl(DsqlCompilerScratch* dsqlScratch, RecordSourceNod
|
||||
parentRse->dsqlStreams = streamList = FB_NEW_POOL(pool) RecSourceListNode(pool, 1);
|
||||
streamList->items[0] = window;
|
||||
|
||||
if (rse->flags & RseNode::FLAG_WRITELOCK)
|
||||
if (rse->hasWriteLock())
|
||||
{
|
||||
parentRse->flags |= RseNode::FLAG_WRITELOCK;
|
||||
rse->flags &= ~RseNode::FLAG_WRITELOCK;
|
||||
}
|
||||
|
||||
if (rse->flags & RseNode::FLAG_SKIP_LOCKED)
|
||||
if (rse->hasSkipLocked())
|
||||
{
|
||||
parentRse->flags |= RseNode::FLAG_SKIP_LOCKED;
|
||||
rse->flags &= ~RseNode::FLAG_SKIP_LOCKED;
|
||||
|
@ -2951,9 +2951,7 @@ void RseNode::pass1Source(thread_db* tdbb, CompilerScratch* csb, RseNode* rse,
|
||||
// where we are just trying to inner join more than 2 streams. If possible,
|
||||
// try to flatten the tree out before we go any further.
|
||||
|
||||
const auto isLateral = (this->flags & RseNode::FLAG_LATERAL) != 0;
|
||||
|
||||
if (!isLateral &&
|
||||
if (!isLateral() &&
|
||||
rse->rse_jointype == blr_inner &&
|
||||
rse_jointype == blr_inner &&
|
||||
!rse_sorted && !rse_projection &&
|
||||
@ -3046,8 +3044,6 @@ RecordSource* RseNode::compile(thread_db* tdbb, Optimizer* opt, bool innerSubStr
|
||||
|
||||
BoolExprNodeStack conjunctStack;
|
||||
|
||||
const auto isLateral = (this->flags & RseNode::FLAG_LATERAL) != 0;
|
||||
|
||||
// pass RseNode boolean only to inner substreams because join condition
|
||||
// should never exclude records from outer substreams
|
||||
if (opt->isInnerJoin() || (opt->isLeftJoin() && innerSubStream))
|
||||
@ -3060,7 +3056,7 @@ RecordSource* RseNode::compile(thread_db* tdbb, Optimizer* opt, bool innerSubStr
|
||||
|
||||
StreamStateHolder stateHolder(csb, opt->getOuterStreams());
|
||||
|
||||
if (opt->isLeftJoin() || isLateral)
|
||||
if (opt->isLeftJoin() || isLateral())
|
||||
{
|
||||
stateHolder.activate();
|
||||
|
||||
|
@ -730,6 +730,41 @@ public:
|
||||
FLAG_SUB_QUERY = 0x100 // sub-query
|
||||
};
|
||||
|
||||
bool isInvariant() const
|
||||
{
|
||||
return (flags & FLAG_VARIANT) == 0;
|
||||
}
|
||||
|
||||
bool isSingular() const
|
||||
{
|
||||
return (flags & FLAG_SINGULAR) != 0;
|
||||
}
|
||||
|
||||
bool isScrollable() const
|
||||
{
|
||||
return (flags & FLAG_SCROLLABLE) != 0;
|
||||
}
|
||||
|
||||
bool isLateral() const
|
||||
{
|
||||
return (flags & FLAG_LATERAL) != 0;
|
||||
}
|
||||
|
||||
bool isSubQuery() const
|
||||
{
|
||||
return (flags & FLAG_SUB_QUERY) != 0;
|
||||
}
|
||||
|
||||
bool hasWriteLock() const
|
||||
{
|
||||
return (flags & FLAG_WRITELOCK) != 0;
|
||||
}
|
||||
|
||||
bool hasSkipLocked() const
|
||||
{
|
||||
return (flags & FLAG_SKIP_LOCKED) != 0;
|
||||
}
|
||||
|
||||
explicit RseNode(MemoryPool& pool)
|
||||
: TypedNode<RecordSourceNode, RecordSourceNode::TYPE_RSE>(pool),
|
||||
dsqlFirst(NULL),
|
||||
|
@ -1034,7 +1034,7 @@ RecordSource* Optimizer::compile(BoolExprNodeStack* parentStack)
|
||||
if (rse->rse_skip)
|
||||
rsb = FB_NEW_POOL(getPool()) SkipRowsStream(csb, rsb, rse->rse_skip);
|
||||
|
||||
if (rse->flags & RseNode::FLAG_WRITELOCK)
|
||||
if (rse->hasWriteLock())
|
||||
{
|
||||
for (const auto compileStream : compileStreams)
|
||||
{
|
||||
@ -1048,16 +1048,16 @@ RecordSource* Optimizer::compile(BoolExprNodeStack* parentStack)
|
||||
SCL_update, obj_relations, tail->csb_relation->rel_name);
|
||||
}
|
||||
|
||||
rsb = FB_NEW_POOL(getPool()) LockedStream(csb, rsb, (rse->flags & RseNode::FLAG_SKIP_LOCKED));
|
||||
rsb = FB_NEW_POOL(getPool()) LockedStream(csb, rsb, rse->hasSkipLocked());
|
||||
}
|
||||
|
||||
if (rse->rse_first)
|
||||
rsb = FB_NEW_POOL(getPool()) FirstRowsStream(csb, rsb, rse->rse_first);
|
||||
|
||||
if (rse->flags & RseNode::FLAG_SINGULAR)
|
||||
if (rse->isSingular())
|
||||
rsb = FB_NEW_POOL(getPool()) SingularStream(csb, rsb);
|
||||
|
||||
if (rse->flags & RseNode::FLAG_SCROLLABLE)
|
||||
if (rse->isScrollable())
|
||||
rsb = FB_NEW_POOL(getPool()) BufferedStream(csb, rsb);
|
||||
|
||||
return rsb;
|
||||
|
@ -1404,7 +1404,7 @@ RseNode* PAR_rse(thread_db* tdbb, CompilerScratch* csb, SSHORT rse_op)
|
||||
break;
|
||||
|
||||
case blr_skip_locked:
|
||||
if (!(rse->flags & RseNode::FLAG_WRITELOCK))
|
||||
if (!rse->hasWriteLock())
|
||||
{
|
||||
PAR_error(csb,
|
||||
Arg::Gds(isc_random) <<
|
||||
|
@ -70,18 +70,18 @@ void Select::printPlan(thread_db* tdbb, string& plan, bool detailed) const
|
||||
{
|
||||
if (detailed)
|
||||
{
|
||||
if (m_rse->flags & RseNode::FLAG_SUB_QUERY)
|
||||
if (m_rse->isSubQuery())
|
||||
{
|
||||
plan += "\nSub-query";
|
||||
|
||||
if (!(m_rse->flags & RseNode::FLAG_VARIANT))
|
||||
if (m_rse->isInvariant())
|
||||
plan += " (invariant)";
|
||||
}
|
||||
else if (m_cursorName.hasData())
|
||||
{
|
||||
plan += "\nCursor \"" + string(m_cursorName) + "\"";
|
||||
|
||||
if (m_rse->flags & RseNode::FLAG_SCROLLABLE)
|
||||
if (m_rse->isScrollable())
|
||||
plan += " (scrollable)";
|
||||
}
|
||||
else
|
||||
@ -179,7 +179,7 @@ void Cursor::close(thread_db* tdbb) const
|
||||
|
||||
bool Cursor::fetchNext(thread_db* tdbb) const
|
||||
{
|
||||
if (m_rse->flags & RseNode::FLAG_SCROLLABLE)
|
||||
if (m_rse->isScrollable())
|
||||
return fetchRelative(tdbb, 1);
|
||||
|
||||
if (!validate(tdbb))
|
||||
@ -215,7 +215,7 @@ bool Cursor::fetchNext(thread_db* tdbb) const
|
||||
|
||||
bool Cursor::fetchPrior(thread_db* tdbb) const
|
||||
{
|
||||
if (!(m_rse->flags & RseNode::FLAG_SCROLLABLE))
|
||||
if (!m_rse->isScrollable())
|
||||
{
|
||||
// error: invalid fetch direction
|
||||
status_exception::raise(Arg::Gds(isc_invalid_fetch_option) << Arg::Str("PRIOR"));
|
||||
@ -226,7 +226,7 @@ bool Cursor::fetchPrior(thread_db* tdbb) const
|
||||
|
||||
bool Cursor::fetchFirst(thread_db* tdbb) const
|
||||
{
|
||||
if (!(m_rse->flags & RseNode::FLAG_SCROLLABLE))
|
||||
if (!m_rse->isScrollable())
|
||||
{
|
||||
// error: invalid fetch direction
|
||||
status_exception::raise(Arg::Gds(isc_invalid_fetch_option) << Arg::Str("FIRST"));
|
||||
@ -237,7 +237,7 @@ bool Cursor::fetchFirst(thread_db* tdbb) const
|
||||
|
||||
bool Cursor::fetchLast(thread_db* tdbb) const
|
||||
{
|
||||
if (!(m_rse->flags & RseNode::FLAG_SCROLLABLE))
|
||||
if (!m_rse->isScrollable())
|
||||
{
|
||||
// error: invalid fetch direction
|
||||
status_exception::raise(Arg::Gds(isc_invalid_fetch_option) << Arg::Str("LAST"));
|
||||
@ -248,7 +248,7 @@ bool Cursor::fetchLast(thread_db* tdbb) const
|
||||
|
||||
bool Cursor::fetchAbsolute(thread_db* tdbb, SINT64 offset) const
|
||||
{
|
||||
if (!(m_rse->flags & RseNode::FLAG_SCROLLABLE))
|
||||
if (!m_rse->isScrollable())
|
||||
{
|
||||
// error: invalid fetch direction
|
||||
status_exception::raise(Arg::Gds(isc_invalid_fetch_option) << Arg::Str("ABSOLUTE"));
|
||||
@ -309,7 +309,7 @@ bool Cursor::fetchAbsolute(thread_db* tdbb, SINT64 offset) const
|
||||
|
||||
bool Cursor::fetchRelative(thread_db* tdbb, SINT64 offset) const
|
||||
{
|
||||
if (!(m_rse->flags & RseNode::FLAG_SCROLLABLE))
|
||||
if (!m_rse->isScrollable())
|
||||
{
|
||||
// error: invalid fetch direction
|
||||
status_exception::raise(Arg::Gds(isc_invalid_fetch_option) << Arg::Str("RELATIVE"));
|
||||
|
@ -75,7 +75,7 @@ namespace Jrd
|
||||
|
||||
// SubQuery class (simplified forward-only cursor)
|
||||
|
||||
class SubQuery : public Select
|
||||
class SubQuery final : public Select
|
||||
{
|
||||
public:
|
||||
SubQuery(const RecordSource* rsb, const RseNode* rse);
|
||||
@ -88,7 +88,7 @@ namespace Jrd
|
||||
|
||||
// Cursor class (wrapper around the whole access tree)
|
||||
|
||||
class Cursor : public Select
|
||||
class Cursor final : public Select
|
||||
{
|
||||
enum State { BOS, POSITIONED, EOS };
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user