8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 02:03:04 +01:00

Adjustments as per Adriano's comments

This commit is contained in:
Dmitry Yemanov 2023-01-04 12:08:11 +03:00
parent 36d011f731
commit 1c2470c4cc
11 changed files with 60 additions and 29 deletions

View File

@ -1582,7 +1582,7 @@ BoolExprNode* RseBoolNode::pass1(thread_db* tdbb, CompilerScratch* csb)
void RseBoolNode::pass2Boolean1(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; nodFlags |= FLAG_INVARIANT;
csb->csb_invariants.push(&impureOffset); csb->csb_invariants.push(&impureOffset);

View File

@ -11321,7 +11321,7 @@ ValueExprNode* SubQueryNode::pass2(thread_db* tdbb, CompilerScratch* csb)
if (!rse) if (!rse)
ERR_post(Arg::Gds(isc_wish_list)); ERR_post(Arg::Gds(isc_wish_list));
if (!(rse->flags & RseNode::FLAG_VARIANT)) if (rse->isInvariant())
{ {
nodFlags |= FLAG_INVARIANT; nodFlags |= FLAG_INVARIANT;
csb->csb_invariants.push(&impureOffset); csb->csb_invariants.push(&impureOffset);

View File

@ -5077,7 +5077,7 @@ StmtNode* ForNode::pass2(thread_db* tdbb, CompilerScratch* csb)
csb->csb_fors.add(cursor); csb->csb_fors.add(cursor);
if (rse->flags & RseNode::FLAG_WRITELOCK) if (rse->hasWriteLock())
withLock = true; withLock = true;
if (marks & MARK_MERGE) if (marks & MARK_MERGE)

View File

@ -547,10 +547,10 @@ void GEN_rse(DsqlCompilerScratch* dsqlScratch, RseNode* rse)
for (const NestConst<RecordSourceNode>* const end = rse->dsqlStreams->items.end(); ptr != end; ++ptr) for (const NestConst<RecordSourceNode>* const end = rse->dsqlStreams->items.end(); ptr != end; ++ptr)
GEN_expr(dsqlScratch, *ptr); GEN_expr(dsqlScratch, *ptr);
if (rse->flags & RseNode::FLAG_WRITELOCK) if (rse->hasWriteLock())
dsqlScratch->appendUChar(blr_writelock); dsqlScratch->appendUChar(blr_writelock);
if (rse->flags & RseNode::FLAG_SKIP_LOCKED) if (rse->hasSkipLocked())
dsqlScratch->appendUChar(blr_skip_locked); dsqlScratch->appendUChar(blr_skip_locked);
if (rse->dsqlFirst) if (rse->dsqlFirst)

View File

@ -2177,13 +2177,13 @@ static RseNode* pass1_rse_impl(DsqlCompilerScratch* dsqlScratch, RecordSourceNod
parentRse->dsqlStreams = streamList = FB_NEW_POOL(pool) RecSourceListNode(pool, 1); parentRse->dsqlStreams = streamList = FB_NEW_POOL(pool) RecSourceListNode(pool, 1);
streamList->items[0] = window; streamList->items[0] = window;
if (rse->flags & RseNode::FLAG_WRITELOCK) if (rse->hasWriteLock())
{ {
parentRse->flags |= RseNode::FLAG_WRITELOCK; parentRse->flags |= RseNode::FLAG_WRITELOCK;
rse->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; parentRse->flags |= RseNode::FLAG_SKIP_LOCKED;
rse->flags &= ~RseNode::FLAG_SKIP_LOCKED; rse->flags &= ~RseNode::FLAG_SKIP_LOCKED;

View File

@ -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, // 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. // 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->rse_jointype == blr_inner &&
rse_jointype == blr_inner && rse_jointype == blr_inner &&
!rse_sorted && !rse_projection && !rse_sorted && !rse_projection &&
@ -3046,8 +3044,6 @@ RecordSource* RseNode::compile(thread_db* tdbb, Optimizer* opt, bool innerSubStr
BoolExprNodeStack conjunctStack; BoolExprNodeStack conjunctStack;
const auto isLateral = (this->flags & RseNode::FLAG_LATERAL) != 0;
// pass RseNode boolean only to inner substreams because join condition // pass RseNode boolean only to inner substreams because join condition
// should never exclude records from outer substreams // should never exclude records from outer substreams
if (opt->isInnerJoin() || (opt->isLeftJoin() && innerSubStream)) 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()); StreamStateHolder stateHolder(csb, opt->getOuterStreams());
if (opt->isLeftJoin() || isLateral) if (opt->isLeftJoin() || isLateral())
{ {
stateHolder.activate(); stateHolder.activate();

View File

@ -730,6 +730,41 @@ public:
FLAG_SUB_QUERY = 0x100 // sub-query 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) explicit RseNode(MemoryPool& pool)
: TypedNode<RecordSourceNode, RecordSourceNode::TYPE_RSE>(pool), : TypedNode<RecordSourceNode, RecordSourceNode::TYPE_RSE>(pool),
dsqlFirst(NULL), dsqlFirst(NULL),

View File

@ -1034,7 +1034,7 @@ RecordSource* Optimizer::compile(BoolExprNodeStack* parentStack)
if (rse->rse_skip) if (rse->rse_skip)
rsb = FB_NEW_POOL(getPool()) SkipRowsStream(csb, rsb, 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) for (const auto compileStream : compileStreams)
{ {
@ -1048,16 +1048,16 @@ RecordSource* Optimizer::compile(BoolExprNodeStack* parentStack)
SCL_update, obj_relations, tail->csb_relation->rel_name); 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) if (rse->rse_first)
rsb = FB_NEW_POOL(getPool()) FirstRowsStream(csb, rsb, 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); 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); rsb = FB_NEW_POOL(getPool()) BufferedStream(csb, rsb);
return rsb; return rsb;

View File

@ -1404,7 +1404,7 @@ RseNode* PAR_rse(thread_db* tdbb, CompilerScratch* csb, SSHORT rse_op)
break; break;
case blr_skip_locked: case blr_skip_locked:
if (!(rse->flags & RseNode::FLAG_WRITELOCK)) if (!rse->hasWriteLock())
{ {
PAR_error(csb, PAR_error(csb,
Arg::Gds(isc_random) << Arg::Gds(isc_random) <<

View File

@ -70,18 +70,18 @@ void Select::printPlan(thread_db* tdbb, string& plan, bool detailed) const
{ {
if (detailed) if (detailed)
{ {
if (m_rse->flags & RseNode::FLAG_SUB_QUERY) if (m_rse->isSubQuery())
{ {
plan += "\nSub-query"; plan += "\nSub-query";
if (!(m_rse->flags & RseNode::FLAG_VARIANT)) if (m_rse->isInvariant())
plan += " (invariant)"; plan += " (invariant)";
} }
else if (m_cursorName.hasData()) else if (m_cursorName.hasData())
{ {
plan += "\nCursor \"" + string(m_cursorName) + "\""; plan += "\nCursor \"" + string(m_cursorName) + "\"";
if (m_rse->flags & RseNode::FLAG_SCROLLABLE) if (m_rse->isScrollable())
plan += " (scrollable)"; plan += " (scrollable)";
} }
else else
@ -179,7 +179,7 @@ void Cursor::close(thread_db* tdbb) const
bool Cursor::fetchNext(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); return fetchRelative(tdbb, 1);
if (!validate(tdbb)) if (!validate(tdbb))
@ -215,7 +215,7 @@ bool Cursor::fetchNext(thread_db* tdbb) const
bool Cursor::fetchPrior(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 // error: invalid fetch direction
status_exception::raise(Arg::Gds(isc_invalid_fetch_option) << Arg::Str("PRIOR")); 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 bool Cursor::fetchFirst(thread_db* tdbb) const
{ {
if (!(m_rse->flags & RseNode::FLAG_SCROLLABLE)) if (!m_rse->isScrollable())
{ {
// error: invalid fetch direction // error: invalid fetch direction
status_exception::raise(Arg::Gds(isc_invalid_fetch_option) << Arg::Str("FIRST")); 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 bool Cursor::fetchLast(thread_db* tdbb) const
{ {
if (!(m_rse->flags & RseNode::FLAG_SCROLLABLE)) if (!m_rse->isScrollable())
{ {
// error: invalid fetch direction // error: invalid fetch direction
status_exception::raise(Arg::Gds(isc_invalid_fetch_option) << Arg::Str("LAST")); 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 bool Cursor::fetchAbsolute(thread_db* tdbb, SINT64 offset) const
{ {
if (!(m_rse->flags & RseNode::FLAG_SCROLLABLE)) if (!m_rse->isScrollable())
{ {
// error: invalid fetch direction // error: invalid fetch direction
status_exception::raise(Arg::Gds(isc_invalid_fetch_option) << Arg::Str("ABSOLUTE")); 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 bool Cursor::fetchRelative(thread_db* tdbb, SINT64 offset) const
{ {
if (!(m_rse->flags & RseNode::FLAG_SCROLLABLE)) if (!m_rse->isScrollable())
{ {
// error: invalid fetch direction // error: invalid fetch direction
status_exception::raise(Arg::Gds(isc_invalid_fetch_option) << Arg::Str("RELATIVE")); status_exception::raise(Arg::Gds(isc_invalid_fetch_option) << Arg::Str("RELATIVE"));

View File

@ -75,7 +75,7 @@ namespace Jrd
// SubQuery class (simplified forward-only cursor) // SubQuery class (simplified forward-only cursor)
class SubQuery : public Select class SubQuery final : public Select
{ {
public: public:
SubQuery(const RecordSource* rsb, const RseNode* rse); SubQuery(const RecordSource* rsb, const RseNode* rse);
@ -88,7 +88,7 @@ namespace Jrd
// Cursor class (wrapper around the whole access tree) // Cursor class (wrapper around the whole access tree)
class Cursor : public Select class Cursor final : public Select
{ {
enum State { BOS, POSITIONED, EOS }; enum State { BOS, POSITIONED, EOS };