| 1009 | |
| 1010 | |
| 1011 | static bool |
| 1012 | StreamingDestReceiverReceive(TupleTableSlot *slot, |
| 1013 | DestReceiver *destReceiver) |
| 1014 | { |
| 1015 | StreamingTupleDestReceiver *receiver = |
| 1016 | (StreamingTupleDestReceiver *) destReceiver; |
| 1017 | BsonStoreTupleDestReceiverBase *base = &receiver->base; |
| 1018 | |
| 1019 | bool isNull = false; |
| 1020 | Datum result = slot_getattr(slot, 1, &isNull); |
| 1021 | if (isNull) |
| 1022 | { |
| 1023 | /* |
| 1024 | * For streaming receivers: NULL data rows are skipped. |
| 1025 | * Return true (continue) so the executor keeps sending rows. |
| 1026 | */ |
| 1027 | return true; |
| 1028 | } |
| 1029 | |
| 1030 | pgbson *documentValue = DatumGetPgBsonPacked(result); |
| 1031 | uint32_t datumSize = VARSIZE_ANY_EXHDR(documentValue); |
| 1032 | |
| 1033 | if (datumSize > BSON_MAX_ALLOWED_SIZE) |
| 1034 | { |
| 1035 | ereport(ERROR, (errcode(ERRCODE_DOCUMENTDB_BSONOBJECTTOOLARGE), |
| 1036 | errmsg("Size %u is larger than MaxDocumentSize %u", |
| 1037 | datumSize, BSON_MAX_ALLOWED_SIZE))); |
| 1038 | } |
| 1039 | |
| 1040 | receiver->streamingAccumulatedSize += datumSize; |
| 1041 | |
| 1042 | int64_t totalSize = base->currentAccumulatedSize + datumSize + |
| 1043 | PER_DOC_OVERHEAD; |
| 1044 | |
| 1045 | bool sizeLimitReached = (totalSize >= BSON_MAX_ALLOWED_SIZE && |
| 1046 | base->numRowsFetched > 0); |
| 1047 | if (sizeLimitReached || |
| 1048 | base->numRowsFetched >= (uint32_t) base->batchSize) |
| 1049 | { |
| 1050 | receiver->terminationReason = sizeLimitReached ? |
| 1051 | TerminationReason_BatchSizeLimit : |
| 1052 | TerminationReason_BatchItemLimit; |
| 1053 | return false; |
| 1054 | } |
| 1055 | |
| 1056 | MemoryContext oldContext = MemoryContextSwitchTo(base->writerContext); |
| 1057 | PgbsonArrayWriterWriteDocument(base->writer, documentValue); |
| 1058 | MemoryContextSwitchTo(oldContext); |
| 1059 | |
| 1060 | base->numRowsFetched++; |
| 1061 | base->currentAccumulatedSize += (datumSize + PER_DOC_OVERHEAD); |
| 1062 | |
| 1063 | /* Process continuation token (column 2) and update the cursor map. */ |
| 1064 | bool isContinuationNull = false; |
| 1065 | Datum continuationDatum = slot_getattr(slot, 2, &isContinuationNull); |
| 1066 | if (!isContinuationNull) |
| 1067 | { |
| 1068 | pgbson *continuation = DatumGetPgBsonPacked(continuationDatum); |
nothing calls this directly
no test coverage detected