* DensifyDocsFromState returns an array pgbson with the current document and all other * documents added to densify the list * e.g. * document = {b: 10, a: 1} * step = { "": 2 } * minValue = {"": 6} * maxValue = {"": 14} * then this function would return: * if document is the last row in the group then * {"_": [ {b: 6}, {b: 8}, {b: 10, a: 1}, {b: 12}, {b: 14} ]} * * otherwise densifies
| 949 | * If the time unit is present the returned array is date values. |
| 950 | */ |
| 951 | static pgbson * |
| 952 | DensifyDocsFromState(const pgbson *document, bson_value_t *minValue, |
| 953 | bson_value_t *maxValue, |
| 954 | const pgbson *partitionBy, DensifyWindowState *state) |
| 955 | { |
| 956 | pgbson_writer writer; |
| 957 | PgbsonWriterInit(&writer); |
| 958 | pgbson_array_writer arrayWriter; |
| 959 | PgbsonWriterStartArray(&writer, DENSIFY_RESULT_FIELD, |
| 960 | DENSIFY_RESULT_FIELD_LENGTH, &arrayWriter); |
| 961 | |
| 962 | bool includeMaxBound = false; |
| 963 | bson_value_t lastMinUpdatedValue = { 0 }; |
| 964 | bson_value_t currentFieldValue = { 0 }; |
| 965 | |
| 966 | DensifyArguments *arguments = &state->arguments; |
| 967 | PartitionAwareState *partitionState = &state->partitionAwareState; |
| 968 | |
| 969 | if (!partitionState->skipRows) |
| 970 | { |
| 971 | if (document != NULL) |
| 972 | { |
| 973 | PgbsonGetBsonValueAtPath(document, arguments->field.string, |
| 974 | ¤tFieldValue); |
| 975 | CheckFieldValue(¤tFieldValue, state); |
| 976 | } |
| 977 | |
| 978 | bool overflowedFromInt = false; |
| 979 | bool isComparisionValid = true; |
| 980 | int upperBoundCompareResult = maxValue->value_type == BSON_TYPE_EOD ? -1 : |
| 981 | CompareBsonValueAndType(¤tFieldValue, |
| 982 | maxValue, |
| 983 | &overflowedFromInt); |
| 984 | |
| 985 | if (minValue->value_type == BSON_TYPE_EOD || |
| 986 | minValue->value_type == BSON_TYPE_NULL) |
| 987 | { |
| 988 | /* |
| 989 | * Generally EOD and NULL values are placed before regular values in an ASC sort |
| 990 | * so whenever the minValue is any of these we can make the min=currentFieldValue |
| 991 | * and write the document. |
| 992 | * By doing this we progress till we start finding regular value where densification |
| 993 | * can be done |
| 994 | */ |
| 995 | *minValue = currentFieldValue; |
| 996 | } |
| 997 | |
| 998 | int compareResult = CompareBsonValueAndType(¤tFieldValue, minValue, |
| 999 | &isComparisionValid); |
| 1000 | |
| 1001 | if (upperBoundCompareResult > 0) |
| 1002 | { |
| 1003 | /* Doc is out of upper bound add all pending step values and mark the state to skip rows for next set of documents */ |
| 1004 | partitionState->skipRows = true; |
| 1005 | lastMinUpdatedValue = GenerateAndWriteDocumentsInRange(minValue, maxValue, |
| 1006 | partitionBy, state, |
| 1007 | &arrayWriter, |
| 1008 | includeMaxBound); |
no test coverage detected