* HandleFunctionRequest * * Server side of PQfn (fastpath function calls from the frontend). * This corresponds to the libpq protocol symbol "F". * * INPUT: * postgres.c has already read the message body and will pass it in * msgBuf. * * Note: palloc()s done here and in the called function do not need to be * cleaned up explicitly. We are called from PostgresMain() in the * MessageCo
| 185 | * control returns to PostgresMain. |
| 186 | */ |
| 187 | void |
| 188 | HandleFunctionRequest(StringInfo msgBuf) |
| 189 | { |
| 190 | LOCAL_FCINFO(fcinfo, FUNC_MAX_ARGS); |
| 191 | Oid fid; |
| 192 | AclResult aclresult; |
| 193 | int16 rformat; |
| 194 | Datum retval; |
| 195 | struct fp_info my_fp; |
| 196 | struct fp_info *fip; |
| 197 | bool callit; |
| 198 | bool was_logged = false; |
| 199 | char msec_str[32]; |
| 200 | |
| 201 | /* |
| 202 | * We only accept COMMIT/ABORT if we are in an aborted transaction, and |
| 203 | * COMMIT/ABORT cannot be executed through the fastpath interface. |
| 204 | */ |
| 205 | if (IsAbortedTransactionBlockState()) |
| 206 | ereport(ERROR, |
| 207 | (errcode(ERRCODE_IN_FAILED_SQL_TRANSACTION), |
| 208 | errmsg("current transaction is aborted, " |
| 209 | "commands ignored until end of transaction block"))); |
| 210 | |
| 211 | /* |
| 212 | * Now that we know we are in a valid transaction, set snapshot in case |
| 213 | * needed by function itself or one of the datatype I/O routines. |
| 214 | */ |
| 215 | PushActiveSnapshot(GetTransactionSnapshot()); |
| 216 | |
| 217 | /* |
| 218 | * Begin parsing the buffer contents. |
| 219 | */ |
| 220 | fid = (Oid) pq_getmsgint(msgBuf, 4); /* function oid */ |
| 221 | |
| 222 | /* |
| 223 | * There used to be a lame attempt at caching lookup info here. Now we |
| 224 | * just do the lookups on every call. |
| 225 | */ |
| 226 | fip = &my_fp; |
| 227 | fetch_fp_info(fid, fip); |
| 228 | |
| 229 | /* Log as soon as we have the function OID and name */ |
| 230 | if (log_statement == LOGSTMT_ALL) |
| 231 | { |
| 232 | ereport(LOG, |
| 233 | (errmsg("fastpath function call: \"%s\" (OID %u)", |
| 234 | fip->fname, fid))); |
| 235 | was_logged = true; |
| 236 | } |
| 237 | |
| 238 | /* |
| 239 | * Check permission to access and call function. Since we didn't go |
| 240 | * through a normal name lookup, we need to check schema usage too. |
| 241 | */ |
| 242 | aclresult = pg_namespace_aclcheck(fip->namespace, GetUserId(), ACL_USAGE); |
| 243 | if (aclresult != ACLCHECK_OK) |
| 244 | aclcheck_error(aclresult, OBJECT_SCHEMA, |
no test coverage detected