* $lookup semantics: For each document from a collection d1, find all documents from a * collection t2, where t1.localField = t2.foreignField. * * After the matching is done bson_dollar_lookup_project() formats the output appropriately. * * Input to the method: * 1. A document from the t1 * 2. Number of matched douments from t2 * 3. An array of matched documents from t2. *
| 1988 | * |
| 1989 | */ |
| 1990 | static pgbson * |
| 1991 | BsonLookUpProject(pgbson *sourceDocument, int numMatched, Datum *matchedDocument, |
| 1992 | bool *matchedNulls, char *matchedDocsFieldName) |
| 1993 | { |
| 1994 | /* |
| 1995 | * Creating an addField spec of the form |
| 1996 | * |
| 1997 | * "asFieldname" |
| 1998 | * matchedArray[0] -> matchedArray[1] -> ..... -> matchedArray[n] |
| 1999 | * |
| 2000 | */ |
| 2001 | BsonIntermediatePathNode *root = MakeRootNode(); |
| 2002 | StringView matchedDocsView = CreateStringViewFromString(matchedDocsFieldName); |
| 2003 | |
| 2004 | bool treatLeafDataAsConstant = true; |
| 2005 | ParseAggregationExpressionContext ignoreContext = { 0 }; |
| 2006 | BsonLeafArrayWithFieldPathNode *matchedDocsNode = |
| 2007 | TraverseDottedPathAndAddLeafArrayNode( |
| 2008 | &matchedDocsView, |
| 2009 | root, |
| 2010 | BsonDefaultCreateIntermediateNode, |
| 2011 | treatLeafDataAsConstant); |
| 2012 | |
| 2013 | int matchedIndex = 0; |
| 2014 | for (int i = 0; i < numMatched; i++) |
| 2015 | { |
| 2016 | /* Skip NULL elements that can arise from LEFT JOIN with no match */ |
| 2017 | if (matchedNulls[i]) |
| 2018 | { |
| 2019 | continue; |
| 2020 | } |
| 2021 | |
| 2022 | bson_value_t documentBsonValue = ConvertPgbsonToBsonValue( |
| 2023 | (pgbson *) matchedDocument[i]); |
| 2024 | |
| 2025 | const char *relativePath = NULL; |
| 2026 | AddValueNodeToLeafArrayWithField(matchedDocsNode, relativePath, |
| 2027 | matchedIndex, |
| 2028 | &documentBsonValue, |
| 2029 | BsonDefaultCreateLeafNode, |
| 2030 | treatLeafDataAsConstant, |
| 2031 | &ignoreContext); |
| 2032 | matchedIndex++; |
| 2033 | } |
| 2034 | |
| 2035 | |
| 2036 | /* Executing the addFieldSpec and returning the pgbson */ |
| 2037 | pgbson_writer writer; |
| 2038 | bson_iter_t documentIterator; |
| 2039 | PgbsonWriterInit(&writer); |
| 2040 | PgbsonInitIterator(sourceDocument, &documentIterator); |
| 2041 | bool projectNonMatchingField = true; |
| 2042 | ProjectDocumentState projectDocState = { |
| 2043 | .isPositionalAlreadyEvaluated = false, |
| 2044 | .parentDocument = sourceDocument, |
| 2045 | .topLevelPendingProjectionState = NULL, |
| 2046 | .skipIntermediateArrayFields = false, |
| 2047 | }; |
no test coverage detected