MCPcopy Create free account
hub / github.com/documentdb/documentdb / HandleDensify

Function HandleDensify

pg_documentdb/src/aggregation/bson_densify.c:488–631  ·  view source on GitHub ↗

* Aggregation pipleine stage handler for `$densify`. * Converts to a window function which densifies the incoming documents based on the mode inline * which are later unwinded using bson_lookup_unwind. * * The query returned is of the form: * if densify_spec is: * {"partitionByFields": ["a"], "field": "b", "range": {"bounds": [10, 15], "step": 1 }} * SELECT bson_lookup_unwind(stage2.doc

Source from the content-addressed store, hash-verified

486 * for this we use a non window function `bson_densify_range_emptytable`
487 */
488Query *
489HandleDensify(const bson_value_t *existingValue, Query *query,
490 AggregationPipelineBuildContext *context)
491{
492 ReportFeatureUsage(FEATURE_STAGE_DENSIFY);
493
494 if (existingValue->value_type != BSON_TYPE_DOCUMENT)
495 {
496 ereport(ERROR, (errcode(ERRCODE_DOCUMENTDB_FAILEDTOPARSE),
497 errmsg(
498 "The $densify stage specification must be provided as an object, but encountered %s instead",
499 BsonTypeName(existingValue->value_type)),
500 errdetail_log(
501 "The $densify stage specification must be provided as an object, but encountered %s instead",
502 BsonTypeName(existingValue->value_type))));
503 }
504
505 RangeTblEntry *rte = linitial(query->rtable);
506
507 bool isCollectionDataTable = rte->rtekind == RTE_RELATION;
508
509 pgbson *densifySpec = PgbsonInitFromDocumentBsonValue(existingValue);
510 Const *densifySpecConst = MakeBsonConst(densifySpec);
511
512 DensifyArguments arguments;
513 memset(&arguments, 0, sizeof(DensifyArguments));
514 PopulateDensifyArgs(&arguments, densifySpec);
515
516 /*
517 * Special case for range mode densify.
518 * Generate documents in the range even when the collection is
519 * - Non existing.
520 * - Empty collection.
521 * - Filtered documents are 0.
522 *
523 * Convert base query to ... UNION ALL SELECT NULL, to add a NULL row
524 * at the end which will help generate the docs in the range.
525 *
526 * This is done due to the fact that projectors are not called
527 * if there are no rows.
528 */
529 if (arguments.densifyType == DENSIFY_TYPE_RANGE)
530 {
531 query = GenerateUnionAllWithSelectNullQuery(query, context);
532
533 /* We create union all query now its not a data table alone anymore */
534 isCollectionDataTable = false;
535 }
536
537 if (!isCollectionDataTable)
538 {
539 query = MigrateQueryToSubQuery(query, context);
540 }
541
542 TargetEntry *firstEntry = linitial(query->targetList);
543 Expr *docExpr = (Expr *) firstEntry->expr;
544
545 Expr *partitionByFieldsExpr = NULL;

Callers

nothing calls this directly

Calls 13

ReportFeatureUsageFunction · 0.85
BsonTypeNameFunction · 0.85
PopulateDensifyArgsFunction · 0.85
MigrateQueryToSubQueryFunction · 0.85
GetDensifyQueryExprsFunction · 0.85
BsonTypeIdFunction · 0.85
BsonEqualOperatorIdFunction · 0.85
BsonLessThanOperatorIdFunction · 0.85
MakeTextConstFunction · 0.85

Tested by

no test coverage detected