| 191 | } |
| 192 | |
| 193 | bool FilteredStream::evaluateBoolean(thread_db* tdbb) const |
| 194 | { |
| 195 | Request* const request = tdbb->getRequest(); |
| 196 | |
| 197 | // For ANY and ALL clauses (ALL is handled as a negated ANY), |
| 198 | // we must first detect them, and then make sure that the returned |
| 199 | // results are correct. This mainly entails making sure that |
| 200 | // there are in fact records in the source stream to test against. |
| 201 | // If there were none, the response must be FALSE. |
| 202 | // Also, if the result of the column comparison is always |
| 203 | // NULL, this must also be returned as NULL. |
| 204 | // (Note that normally, an AND of a NULL and a FALSE would be FALSE, not NULL). |
| 205 | |
| 206 | // This all depends on evl.cpp putting the unoptimized expression |
| 207 | // in the rsb. The unoptimized expression always has the |
| 208 | // select expression on the left, and the column comparison |
| 209 | // on the right. |
| 210 | |
| 211 | // ANY/ALL select node pointer |
| 212 | const BoolExprNode* select_node; |
| 213 | |
| 214 | // ANY/ALL column node pointer |
| 215 | const BoolExprNode* column_node = m_anyBoolean; |
| 216 | |
| 217 | if (column_node && (m_ansiAny || m_ansiAll)) |
| 218 | { |
| 219 | // see if there's a select node to work with |
| 220 | |
| 221 | const BinaryBoolNode* booleanNode = nodeAs<BinaryBoolNode>(column_node); |
| 222 | |
| 223 | if (booleanNode && booleanNode->blrOp == blr_and) |
| 224 | { |
| 225 | select_node = booleanNode->arg1; |
| 226 | column_node = booleanNode->arg2; |
| 227 | } |
| 228 | else |
| 229 | select_node = NULL; |
| 230 | } |
| 231 | |
| 232 | if (column_node && m_ansiAny) |
| 233 | { |
| 234 | if (m_ansiNot) |
| 235 | { |
| 236 | // do NOT ANY |
| 237 | // if the subquery was the empty set |
| 238 | // (numTrue + numFalse + numUnknown = 0) |
| 239 | // or if all were false |
| 240 | // (numTrue + numUnknown = 0), |
| 241 | // NOT ANY is true |
| 242 | |
| 243 | bool any_null = false; // some records true for ANY/ALL |
| 244 | bool any_true = false; // some records true for ANY/ALL |
| 245 | |
| 246 | while (m_next->getRecord(tdbb)) |
| 247 | { |
| 248 | if (m_boolean->execute(tdbb, request)) |
| 249 | { |
| 250 | // found a TRUE value |
nothing calls this directly
no test coverage detected