* Implements the kill_op command. * The command takes a killOp wire protocol compatible command spec and makes an attempt to cancel * the operation uniquely identified by the `op` field in the command spec. * The op field is of the format : . * where * shardId is the unique identifier for the PG backend process running the operation. * opId is the microsecond timestamp of when
| 89 | * See src/commands/current_op.c for more details |
| 90 | */ |
| 91 | Datum |
| 92 | command_kill_op(PG_FUNCTION_ARGS) |
| 93 | { |
| 94 | pgbson *commandSpec = PG_GETARG_PGBSON(0); |
| 95 | ParsedKillOpArgs parsedArgs; |
| 96 | memset(&parsedArgs, 0, sizeof(ParsedKillOpArgs)); |
| 97 | |
| 98 | ValidateAndParseKillOpCommand(commandSpec, &parsedArgs); |
| 99 | |
| 100 | /* |
| 101 | * We need a null terminated string for pg_strtoint64 |
| 102 | */ |
| 103 | char *shardIdString = palloc(parsedArgs.shardIdView.length + 1); /* +1 for null terminator */ |
| 104 | memcpy(shardIdString, parsedArgs.shardIdView.string, parsedArgs.shardIdView.length); |
| 105 | shardIdString[parsedArgs.shardIdView.length] = '\0'; |
| 106 | int64 shardId = pg_strtoint64(shardIdString); |
| 107 | |
| 108 | if (shardId <= SINGLE_NODE_ID) |
| 109 | { |
| 110 | ereport(ERROR, (errcode(ERRCODE_DOCUMENTDB_BADVALUE), |
| 111 | errmsg("Invalid shardid: %s", shardIdString), |
| 112 | errdetail_log( |
| 113 | "Invalid shardid: %s, shardId provided doesn't match the" |
| 114 | " expected format from currentOp", shardIdString))); |
| 115 | } |
| 116 | |
| 117 | int nargs = 0; |
| 118 | bool readOnly = false; |
| 119 | Oid *argTypes = NULL; |
| 120 | Datum *argValues = NULL; |
| 121 | char *argNulls; |
| 122 | |
| 123 | const char *killOpQuery = GetOperationCancellationQuery(shardId, &parsedArgs.opIdView, |
| 124 | &nargs, &argTypes, &argValues, |
| 125 | &argNulls, |
| 126 | GetDefaultOperationCancellationQuery); |
| 127 | |
| 128 | /* If hook doesn't provide any query it's no-op success */ |
| 129 | if (killOpQuery != NULL && nargs > 0 && argTypes != NULL && |
| 130 | argValues != NULL && argNulls != NULL) |
| 131 | { |
| 132 | bool isNull = false; |
| 133 | ExtensionExecuteQueryWithArgsViaSPI(killOpQuery, nargs, argTypes, argValues, |
| 134 | argNulls, readOnly, SPI_OK_SELECT, &isNull); |
| 135 | } |
| 136 | |
| 137 | /* Build success response */ |
| 138 | pgbson_writer writer; |
| 139 | PgbsonWriterInit(&writer); |
| 140 | |
| 141 | StringInfo shardName = makeStringInfo(); |
| 142 | int processId = shardId % SINGLE_NODE_ID; |
| 143 | int shardNameId = (int) ((shardId - processId) / SINGLE_NODE_ID); |
| 144 | appendStringInfo(shardName, "shard%d", shardNameId); |
| 145 | |
| 146 | PgbsonWriterAppendUtf8(&writer, "shard", 5, shardName->data); |
| 147 | PgbsonWriterAppendInt32OrDouble(&writer, "shardid", 7, processId); |
| 148 | PgbsonWriterAppendDouble(&writer, "ok", 2, 1.0); |
nothing calls this directly
no test coverage detected