| 112 | } |
| 113 | |
| 114 | bool RecursiveStream::internalGetRecord(thread_db* tdbb) const |
| 115 | { |
| 116 | JRD_reschedule(tdbb); |
| 117 | |
| 118 | Request* const request = tdbb->getRequest(); |
| 119 | record_param* const rpb = &request->req_rpb[m_stream]; |
| 120 | Impure* const impure = request->getImpure<Impure>(m_impure); |
| 121 | Impure* const saveImpure = request->getImpure<Impure>(m_saveOffset); |
| 122 | |
| 123 | if (!(impure->irsb_flags & irsb_open)) |
| 124 | { |
| 125 | rpb->rpb_number.setValid(false); |
| 126 | return false; |
| 127 | } |
| 128 | |
| 129 | const size_t rpbsSize = sizeof(record_param) * m_innerStreams.getCount(); |
| 130 | Record* const record = request->req_rpb[m_stream].rpb_record; |
| 131 | Record* const mapRecord = request->req_rpb[m_mapStream].rpb_record; |
| 132 | |
| 133 | const RecordSource* rsb; |
| 134 | |
| 135 | switch (impure->irsb_mode) |
| 136 | { |
| 137 | case ROOT: |
| 138 | rsb = m_root; |
| 139 | break; |
| 140 | |
| 141 | case RECURSE: |
| 142 | { |
| 143 | // Stop infinite recursion of bad queries |
| 144 | if (impure->irsb_level > MAX_RECURSE_LEVEL) |
| 145 | status_exception::raise(Arg::Gds(isc_req_max_clones_exceeded)); |
| 146 | |
| 147 | // Save where we are |
| 148 | UCHAR* const tmp = FB_NEW_POOL(*tdbb->getDefaultPool()) UCHAR[m_saveSize + rpbsSize]; |
| 149 | memcpy(tmp, saveImpure, m_saveSize); |
| 150 | |
| 151 | UCHAR* p = tmp + m_saveSize; |
| 152 | for (FB_SIZE_T i = 0; i < m_innerStreams.getCount(); i++) |
| 153 | { |
| 154 | const StreamType stream = m_innerStreams[i]; |
| 155 | record_param* const rpb = &request->req_rpb[stream]; |
| 156 | memmove(p, rpb, sizeof(record_param)); |
| 157 | p += sizeof(record_param); |
| 158 | |
| 159 | // Don't overwrite record contents at next level of recursion. |
| 160 | // RSE_open() and company will allocate new record if needed. |
| 161 | rpb->rpb_record = NULL; |
| 162 | } |
| 163 | impure->irsb_stack = tmp; |
| 164 | |
| 165 | impure->irsb_data = FB_NEW_POOL(*request->req_pool) UCHAR[record->getLength()]; |
| 166 | record->copyDataTo(impure->irsb_data); |
| 167 | |
| 168 | const Impure r = *impure; |
| 169 | memset(saveImpure, 0, m_saveSize); |
| 170 | *impure = r; |
| 171 |
nothing calls this directly
no test coverage detected