* Helper for BsonOrderBy that accepts a options to strictly check the types of documents involved * in the ordering. * Few cases require the type to be same e.g. $sort in `$setWindowFields` stage */
| 2860 | * Few cases require the type to be same e.g. $sort in `$setWindowFields` stage |
| 2861 | */ |
| 2862 | static Datum |
| 2863 | BsonOrderbyCore(pgbson *document, pgbson *filter, const char *collationString, |
| 2864 | bool validateSort, CustomOrderByOptions options) |
| 2865 | { |
| 2866 | bson_iter_t documentIterator; |
| 2867 | pgbsonelement filterElement; |
| 2868 | TraverseOrderByValidateState state = { |
| 2869 | { 0 }, NULL, { 0 }, options, collationString, 0, false |
| 2870 | }; |
| 2871 | |
| 2872 | pgbson_writer writer; |
| 2873 | PgbsonInitIterator(document, &documentIterator); |
| 2874 | PgbsonToSinglePgbsonElement(filter, &filterElement); |
| 2875 | uint32_t filterPathLength = filterElement.pathLength; |
| 2876 | filterElement.pathLength = 0; |
| 2877 | |
| 2878 | if (TryCheckMetaScoreOrderBy(&filterElement.bsonValue)) |
| 2879 | { |
| 2880 | PgbsonWriterInit(&writer); |
| 2881 | double ranking = EvaluateMetaTextScore(document); |
| 2882 | PgbsonWriterAppendDouble(&writer, "rank", 4, ranking); |
| 2883 | PG_RETURN_POINTER(PgbsonWriterGetPgbson(&writer)); |
| 2884 | } |
| 2885 | |
| 2886 | if (!BsonValueIsNumber(&filterElement.bsonValue) && validateSort) |
| 2887 | { |
| 2888 | ereport(ERROR, (errcode(ERRCODE_DOCUMENTDB_BADVALUE), |
| 2889 | errmsg("Sort direction value %s is not valid", |
| 2890 | BsonValueToJsonForLogging( |
| 2891 | &filterElement.bsonValue)))); |
| 2892 | } |
| 2893 | |
| 2894 | int32_t orderBy = BsonValueAsInt32(&filterElement.bsonValue); |
| 2895 | state.isOrderByMin = orderBy == 1; |
| 2896 | |
| 2897 | TraverseBson(&documentIterator, filterElement.path, &state.traverseState, |
| 2898 | &OrderByExecutionFuncs); |
| 2899 | |
| 2900 | /* Match order by outputs similar to what the index produces for terms */ |
| 2901 | PgbsonWriterInit(&writer); |
| 2902 | if (state.orderByValue.value_type == BSON_TYPE_EOD) |
| 2903 | { |
| 2904 | /* here we write an empty path and minKey so it's sorted first. */ |
| 2905 | state.orderByValue.value_type = BSON_TYPE_UNDEFINED; |
| 2906 | } |
| 2907 | |
| 2908 | PgbsonWriterAppendValue(&writer, filterElement.path, filterPathLength, |
| 2909 | &state.orderByValue); |
| 2910 | |
| 2911 | /* append the collation for use in bson_orderby_compare */ |
| 2912 | if (IsCollationApplicable(collationString)) |
| 2913 | { |
| 2914 | PgbsonWriterAppendUtf8(&writer, "collation", 9, collationString); |
| 2915 | } |
| 2916 | |
| 2917 | if (options == CustomOrderByOptions_SetReverseFlag) |
| 2918 | { |
| 2919 | /* if the order by is min, we set the reverse flag to true */ |
no test coverage detected