/// <summary>
        /// Visits a SqlAliasedCollectionExpression and transforms the documents accordingly.
        /// </summary>
        /// <param name="collectionExpression">The collection expression to visit.</param>
        /// <param name="documents">The documents to transform.</param>
        /// <returns>The transformed documents according to the collection expression.</returns>
        public override IEnumerable <CosmosElement> Visit(SqlAliasedCollectionExpression collectionExpression, IEnumerable <CosmosElement> documents)
        {
            //If the query was:

            //SELECT *
            //FROM c

            //and the document was:
            //{
            //    "name" : "John"
            //}

            //Then this function would return:
            //{
            //    "c" : { "name" : "John" }
            //}

            //which is just wrapping the original document in the identifier.

            // Get the sub collection
            CollectionEvaluationResult collectionEvaluationResult = collectionExpression.Collection.Accept(
                SqlInterpreterCollectionVisitor.Singleton,
                documents);
            string identifer = collectionEvaluationResult.Identifer;

            // Figure out what the alias should be
            int    aliasCounter = 0;
            string alias;

            if (collectionExpression.Alias != null)
            {
                alias = collectionExpression.Alias.Value;
            }
            else if (identifer != null)
            {
                alias = identifer;
            }
            else
            {
                alias = $"#{aliasCounter++}";
            }

            // Wrap the collection in the alias so it's easier to bind later
            foreach (Tuple <CosmosElement, string> subDocumentAndRid in collectionEvaluationResult.SubDocumentsAndRids)
            {
                Dictionary <string, CosmosElement> wrappedDocument = new Dictionary <string, CosmosElement>
                {
                    [alias] = subDocumentAndRid.Item1,

                    //// Add the _rid so that we can break ties for sort later
                    ["_rid"] = CosmosString.Create(subDocumentAndRid.Item2)
                };

                yield return(CosmosObject.Create(wrappedDocument));
            }
        }
        /// <summary>
        /// Visits a SqlArrayIteratorCollectionExpression and transforms the documents accordingly.
        /// </summary>
        /// <param name="collectionExpression">The collection expression to visit.</param>
        /// <param name="documents">The documents to transform.</param>
        /// <returns>The transformed documents according to the collection expression.</returns>
        public override IEnumerable <CosmosElement> Visit(SqlArrayIteratorCollectionExpression collectionExpression, IEnumerable <CosmosElement> documents)
        {
            //If the query was:

            //SELECT p
            //FROM p in c.parents

            //and the document was
            //{
            //    "parents" : [{"name" : "John"}, {"name" : "Sally"}]
            //}

            //then the results would be:

            //{ "p" : {"name" : "John"} }

            //and

            //{ "p" : {"name" : "Sally"} }

            //Notice that the result set is larger than the input
            //This is because we emitted one document for each parent in the original document
            //and wrapped it in the provided alias.

            // throw away the identifer since we always have an alias
            CollectionEvaluationResult collectionEvaluationResult = collectionExpression.Collection.Accept(
                SqlInterpreterCollectionVisitor.Singleton,
                documents);

            // Wrap the collection in the alias so it's easier to bind later
            foreach (Tuple <CosmosElement, string> subDocumentAndRid in collectionEvaluationResult.SubDocumentsAndRids)
            {
                CosmosElement document = subDocumentAndRid.Item1;
                string        rid      = subDocumentAndRid.Item2;
                if (document is CosmosArray array)
                {
                    foreach (CosmosElement item in array)
                    {
                        Dictionary <string, CosmosElement> wrappedDocument = new Dictionary <string, CosmosElement>
                        {
                            [collectionExpression.Identifier.Value] = item,

                            //// Add the _rid so that we can break ties for sort later
                            ["_rid"] = CosmosString.Create(rid),
                        };
                        yield return(CosmosObject.Create(wrappedDocument));
                    }
                }
            }
        }