| 186 | } |
| 187 | |
| 188 | bool BinaryBoolNode::executeAnd(thread_db* tdbb, Request* request) const |
| 189 | { |
| 190 | // If either operand is false, then the result is false; |
| 191 | // If both are true, the result is true; |
| 192 | // Otherwise, the result is NULL. |
| 193 | // |
| 194 | // op 1 op 2 result |
| 195 | // ---- ---- ------ |
| 196 | // F F F |
| 197 | // F T F |
| 198 | // F N F |
| 199 | // T F F |
| 200 | // T T T |
| 201 | // T N N |
| 202 | // N F F |
| 203 | // N T N |
| 204 | // N N N |
| 205 | |
| 206 | const bool value1 = arg1->execute(tdbb, request); |
| 207 | |
| 208 | // Save null state and get other operand. |
| 209 | const USHORT firstnull = request->req_flags & req_null; |
| 210 | request->req_flags &= ~req_null; |
| 211 | |
| 212 | if (!value1 && !firstnull) |
| 213 | { |
| 214 | // First term is false, why the whole expression is false. |
| 215 | // NULL flag is already turned off a few lines above. |
| 216 | return false; |
| 217 | } |
| 218 | |
| 219 | const bool value2 = arg2->execute(tdbb, request); |
| 220 | const USHORT secondnull = request->req_flags & req_null; |
| 221 | request->req_flags &= ~req_null; |
| 222 | |
| 223 | if (!value2 && !secondnull) |
| 224 | return false; // at least one operand was false |
| 225 | |
| 226 | if (value1 && value2) |
| 227 | return true; // both true |
| 228 | |
| 229 | // otherwise, return null |
| 230 | request->req_flags |= req_null; |
| 231 | return false; |
| 232 | } |
| 233 | |
| 234 | bool BinaryBoolNode::executeOr(thread_db* tdbb, Request* request) const |
| 235 | { |