* bson_expression_map evaluates a bson expression from a given array of * document. This follows operator expressions as per aggregation expressions. * The input document should be a document containing the given field name that * points to an array of documents. * e.g. { "array": [{"_id": 1 ...}, {"_id": 2 ...}, ...]} * The expression is expected to be a single value bson document * e.g. {
| 822 | * will not match the size of the input array. |
| 823 | */ |
| 824 | Datum |
| 825 | bson_expression_map(PG_FUNCTION_ARGS) |
| 826 | { |
| 827 | pgbson *document = PG_GETARG_PGBSON_PACKED(0); |
| 828 | char *srcArrayName = text_to_cstring(PG_GETARG_TEXT_P(1)); |
| 829 | pgbson *expression = PG_GETARG_PGBSON_PACKED(2); |
| 830 | bool isNullOnEmpty = PG_GETARG_BOOL(3); |
| 831 | ExpressionVariableContext *variableContext = NULL; |
| 832 | pgbsonelement expressionElement; |
| 833 | pgbson_writer writer; |
| 834 | pgbson_array_writer arrayWriter; |
| 835 | |
| 836 | AggregationExpressionData expressionData; |
| 837 | memset(&expressionData, 0, sizeof(AggregationExpressionData)); |
| 838 | |
| 839 | PgbsonToSinglePgbsonElement(expression, &expressionElement); |
| 840 | bson_iter_t docIter; |
| 841 | PgbsonInitIterator(document, &docIter); |
| 842 | const bson_value_t *inputArray = NULL; |
| 843 | |
| 844 | while (bson_iter_next(&docIter)) |
| 845 | { |
| 846 | const char *key = bson_iter_key(&docIter); |
| 847 | if (strcmp(key, srcArrayName) == 0) |
| 848 | { |
| 849 | inputArray = bson_iter_value(&docIter); |
| 850 | break; |
| 851 | } |
| 852 | } |
| 853 | |
| 854 | /* Missing input Array */ |
| 855 | if (inputArray == NULL) |
| 856 | { |
| 857 | ereport(ERROR, errcode(ERRCODE_INTERNAL_ERROR), errmsg( |
| 858 | "Missing Input Array for bson_expression_map: '%s'", srcArrayName)); |
| 859 | } |
| 860 | else if (inputArray->value_type != BSON_TYPE_ARRAY) |
| 861 | { |
| 862 | ereport(ERROR, errcode(ERRCODE_INTERNAL_ERROR), errmsg( |
| 863 | "Input Array for bson_express_map of wrong type Name: '%s' Type: '%s'", |
| 864 | srcArrayName, BsonTypeName(inputArray->value_type))); |
| 865 | } |
| 866 | |
| 867 | /* Init AggregateExpressionData */ |
| 868 | const AggregationExpressionData *state; |
| 869 | const int argPosition = 2; |
| 870 | ParseAggregationExpressionContext context = { 0 }; |
| 871 | |
| 872 | SetCachedFunctionState( |
| 873 | state, |
| 874 | AggregationExpressionData, |
| 875 | argPosition, |
| 876 | ParseAggregationExpressionData, |
| 877 | &expressionElement.bsonValue, |
| 878 | &context); |
| 879 | |
| 880 | if (state == NULL) |
| 881 | { |
nothing calls this directly
no test coverage detected