| 1156 | |
| 1157 | if (vector->mayHaveNulls()) { |
| 1158 | mayHaveNulls = true; |
| 1159 | break; |
| 1160 | } |
| 1161 | } |
| 1162 | |
| 1163 | if (mayHaveNulls) { |
| 1164 | LocalSelectivityVector nonNullHolder(context); |
| 1165 | if (removeSureNulls(rows, context, nonNullHolder)) { |
| 1166 | ScopedVarSetter noMoreNulls(context.mutableNullsPruned(), true); |
| 1167 | if (nonNullHolder.get()->hasSelections()) { |
| 1168 | evalAll(*nonNullHolder.get(), context, result); |
| 1169 | } |
| 1170 | auto rawNonNulls = nonNullHolder.get()->asRange().bits(); |
| 1171 | addNulls(rows, rawNonNulls, context, result); |
| 1172 | return; |
| 1173 | } |
| 1174 | } |
| 1175 | } |
| 1176 | evalAll(rows, context, result); |
| 1177 | } |
| 1178 | |
| 1179 | // Optimization that attempts to cache results for inputs that are dictionary |
| 1180 | // encoded and use the same base vector between subsequent input batches. Since |
| 1181 | // this hold onto a reference to the base vector and the cached results, it can |
| 1182 | // be memory intensive. Therefore in order to reduce this consumption and ensure |
| 1183 | // it is only employed for cases where it can be useful, it only starts caching |
| 1184 | // result after it encounters the same base at least twice. |
| 1185 | void Expr::evalWithMemo( |
| 1186 | const SelectivityVector& rows, |
| 1187 | EvalCtx& context, |
| 1188 | VectorPtr& result) { |
| 1189 | VectorPtr base; |
| 1190 | distinctFields_[0]->evalSpecialForm(rows, context, base); |
| 1191 | |
| 1192 | if (base.get() != baseOfDictionaryRawPtr_ || |
| 1193 | baseOfDictionaryWeakPtr_.expired()) { |
| 1194 | baseOfDictionaryRepeats_ = 0; |
| 1195 | baseOfDictionaryWeakPtr_ = base; |
| 1196 | baseOfDictionaryRawPtr_ = base.get(); |
| 1197 | context.releaseVector(baseOfDictionary_); |
nothing calls this directly
no test coverage detected