| 1399 | }; |
| 1400 | |
| 1401 | class RecursiveStream final : public RecordStream |
| 1402 | { |
| 1403 | static const FB_SIZE_T MAX_RECURSE_LEVEL = 1024; |
| 1404 | |
| 1405 | enum Mode { ROOT, RECURSE }; |
| 1406 | |
| 1407 | struct Impure: public RecordSource::Impure |
| 1408 | { |
| 1409 | USHORT irsb_level; |
| 1410 | Mode irsb_mode; |
| 1411 | UCHAR* irsb_stack; |
| 1412 | UCHAR* irsb_data; |
| 1413 | }; |
| 1414 | |
| 1415 | public: |
| 1416 | RecursiveStream(CompilerScratch* csb, StreamType stream, StreamType mapStream, |
| 1417 | RecordSource* root, RecordSource* inner, |
| 1418 | const MapNode* rootMap, const MapNode* innerMap, |
| 1419 | const StreamList& innerStreams, |
| 1420 | ULONG saveOffset); |
| 1421 | |
| 1422 | void close(thread_db* tdbb) const override; |
| 1423 | |
| 1424 | bool refetchRecord(thread_db* tdbb) const override; |
| 1425 | WriteLockResult lockRecord(thread_db* tdbb) const override; |
| 1426 | |
| 1427 | void getChildren(Firebird::Array<const RecordSource*>& children) const override; |
| 1428 | |
| 1429 | void print(thread_db* tdbb, Firebird::string& plan, |
| 1430 | bool detailed, unsigned level, bool recurse) const override; |
| 1431 | |
| 1432 | void markRecursive() override; |
| 1433 | void invalidateRecords(Request* request) const override; |
| 1434 | void findUsedStreams(StreamList& streams, bool expandAll = false) const override; |
| 1435 | bool isDependent(const StreamList& streams) const override; |
| 1436 | |
| 1437 | protected: |
| 1438 | void internalOpen(thread_db* tdbb) const override; |
| 1439 | bool internalGetRecord(thread_db* tdbb) const override; |
| 1440 | |
| 1441 | private: |
| 1442 | void cleanupLevel(Request* request, Impure* impure) const; |
| 1443 | |
| 1444 | const StreamType m_mapStream; |
| 1445 | NestConst<RecordSource> m_root; |
| 1446 | NestConst<RecordSource> m_inner; |
| 1447 | const MapNode* const m_rootMap; |
| 1448 | const MapNode* const m_innerMap; |
| 1449 | StreamList m_innerStreams; |
| 1450 | const ULONG m_saveOffset; |
| 1451 | FB_SIZE_T m_saveSize; |
| 1452 | }; |
| 1453 | |
| 1454 | class ConditionalStream : public RecordSource |
| 1455 | { |