core implementation of insert command */
| 1057 | |
| 1058 | /* core implementation of insert command */ |
| 1059 | static Datum |
| 1060 | CommandInsertCore(PG_FUNCTION_ARGS, WriteMode writeMode, MemoryContext allocContext) |
| 1061 | { |
| 1062 | if (PG_ARGISNULL(1)) |
| 1063 | { |
| 1064 | ereport(ERROR, (errmsg("insert document cannot be NULL"))); |
| 1065 | } |
| 1066 | |
| 1067 | ThrowIfServerOrTransactionReadOnly(); |
| 1068 | |
| 1069 | pgbson *insertSpec = PG_GETARG_PGBSON(1); |
| 1070 | Datum databaseNameDatum = PG_ARGISNULL(0) ? (Datum) 0 : PG_GETARG_DATUM(0); |
| 1071 | |
| 1072 | pgbsonsequence *insertDocs = PG_GETARG_MAYBE_NULL_PGBSON_SEQUENCE(2); |
| 1073 | |
| 1074 | text *transactionId = NULL; |
| 1075 | if (!PG_ARGISNULL(3)) |
| 1076 | { |
| 1077 | transactionId = PG_GETARG_TEXT_P(3); |
| 1078 | } |
| 1079 | |
| 1080 | /* fetch TupleDesc for return value, not interested in resultTypeId */ |
| 1081 | Oid *resultTypeId = NULL; |
| 1082 | TupleDesc resultTupDesc; |
| 1083 | TypeFuncClass resultTypeClass = |
| 1084 | get_call_result_type(fcinfo, resultTypeId, &resultTupDesc); |
| 1085 | |
| 1086 | if (resultTypeClass != TYPEFUNC_COMPOSITE) |
| 1087 | { |
| 1088 | ereport(ERROR, (errmsg("return type must be a row type"))); |
| 1089 | } |
| 1090 | |
| 1091 | bson_iter_t insertCommandIter; |
| 1092 | PgbsonInitIterator(insertSpec, &insertCommandIter); |
| 1093 | MemoryContext oldContext = MemoryContextSwitchTo(allocContext); |
| 1094 | |
| 1095 | /* we first validate insert command BSON and build a specification */ |
| 1096 | BatchInsertionSpec *batchSpec = BuildBatchInsertionSpec(&insertCommandIter, |
| 1097 | insertDocs, |
| 1098 | &databaseNameDatum); |
| 1099 | |
| 1100 | ReportInsertFeatureUsage(list_length(batchSpec->documents)); |
| 1101 | BatchInsertionResult batchResult; |
| 1102 | batchResult.resultMemoryContext = allocContext; |
| 1103 | MemoryContextSwitchTo(oldContext); |
| 1104 | if (list_length(batchSpec->documents) == 0) |
| 1105 | { |
| 1106 | /* Don't create the collection if there are no documents to insert */ |
| 1107 | batchResult.rowsInserted = 0; |
| 1108 | batchResult.ok = 1; |
| 1109 | batchResult.writeErrors = NIL; |
| 1110 | } |
| 1111 | else |
| 1112 | { |
| 1113 | /* open collection */ |
| 1114 | Datum collectionNameDatum = CStringGetTextDatum(batchSpec->collectionName); |
| 1115 | MongoCollection *collection = |
| 1116 | GetMongoCollectionByNameDatum(databaseNameDatum, collectionNameDatum, |
no test coverage detected