LCOV - differential code coverage report
Current view: top level - src/backend/tcop - fastpath.c (source / functions) Coverage Total Hit UBC GNC CBC DCB
Current: ba12a202ce1b5581dc0ed149cf3f637d7897ad5d vs 2866d8c7dbfc9d882a7d80fef93fbbe763709932 Lines: 69.7 % 132 92 40 1 91 1
Current Date: 2026-08-27 14:31:44 +0300 Functions: 100.0 % 4 4 1 3
Baseline: lcov-20260827-baseline Branches: 40.0 % 115 46 69 46
Baseline Date: 2026-08-27 14:31:58 +0300 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(7,30] days: 100.0 % 1 1 1
(360..) days: 69.5 % 131 91 40 91
Function coverage date bins:
(360..) days: 100.0 % 4 4 1 3
Branch coverage date bins:
(360..) days: 40.0 % 115 46 69 46

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*-------------------------------------------------------------------------
                                  2                 :                :  *
                                  3                 :                :  * fastpath.c
                                  4                 :                :  *    routines to handle function requests from the frontend
                                  5                 :                :  *
                                  6                 :                :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
                                  7                 :                :  * Portions Copyright (c) 1994, Regents of the University of California
                                  8                 :                :  *
                                  9                 :                :  *
                                 10                 :                :  * IDENTIFICATION
                                 11                 :                :  *    src/backend/tcop/fastpath.c
                                 12                 :                :  *
                                 13                 :                :  * NOTES
                                 14                 :                :  *    This cruft is the server side of PQfn.  libpq's PQfn() was retired in
                                 15                 :                :  *    v20 and now always errors, but the server code is retained for the
                                 16                 :                :  *    benefit of older clients and the frontend LO interface.
                                 17                 :                :  *
                                 18                 :                :  *-------------------------------------------------------------------------
                                 19                 :                :  */
                                 20                 :                : #include "postgres.h"
                                 21                 :                : 
                                 22                 :                : #include "access/htup_details.h"
                                 23                 :                : #include "access/xact.h"
                                 24                 :                : #include "catalog/objectaccess.h"
                                 25                 :                : #include "catalog/pg_namespace.h"
                                 26                 :                : #include "catalog/pg_proc.h"
                                 27                 :                : #include "libpq/pqformat.h"
                                 28                 :                : #include "libpq/protocol.h"
                                 29                 :                : #include "mb/pg_wchar.h"
                                 30                 :                : #include "miscadmin.h"
                                 31                 :                : #include "tcop/fastpath.h"
                                 32                 :                : #include "tcop/tcopprot.h"
                                 33                 :                : #include "utils/acl.h"
                                 34                 :                : #include "utils/lsyscache.h"
                                 35                 :                : #include "utils/snapmgr.h"
                                 36                 :                : #include "utils/syscache.h"
                                 37                 :                : 
                                 38                 :                : 
                                 39                 :                : /*
                                 40                 :                :  * Formerly, this code attempted to cache the function and type info
                                 41                 :                :  * looked up by fetch_fp_info, but only for the duration of a single
                                 42                 :                :  * transaction command (since in theory the info could change between
                                 43                 :                :  * commands).  This was utterly useless, because postgres.c executes
                                 44                 :                :  * each fastpath call as a separate transaction command, and so the
                                 45                 :                :  * cached data could never actually have been reused.  If it had worked
                                 46                 :                :  * as intended, it would have had problems anyway with dangling references
                                 47                 :                :  * in the FmgrInfo struct.  So, forget about caching and just repeat the
                                 48                 :                :  * syscache fetches on each usage.  They're not *that* expensive.
                                 49                 :                :  */
                                 50                 :                : struct fp_info
                                 51                 :                : {
                                 52                 :                :     Oid         funcid;
                                 53                 :                :     FmgrInfo    flinfo;         /* function lookup info for funcid */
                                 54                 :                :     Oid         namespace;      /* other stuff from pg_proc */
                                 55                 :                :     Oid         rettype;
                                 56                 :                :     Oid         argtypes[FUNC_MAX_ARGS];
                                 57                 :                :     char        fname[NAMEDATALEN]; /* function name for logging */
                                 58                 :                : };
                                 59                 :                : 
                                 60                 :                : 
                                 61                 :                : static int16 parse_fcall_arguments(StringInfo msgBuf, struct fp_info *fip,
                                 62                 :                :                                    FunctionCallInfo fcinfo);
                                 63                 :                : 
                                 64                 :                : /* ----------------
                                 65                 :                :  *      SendFunctionResult
                                 66                 :                :  * ----------------
                                 67                 :                :  */
                                 68                 :                : static void
 8511 tgl@sss.pgh.pa.us          69                 :CBC        1343 : SendFunctionResult(Datum retval, bool isnull, Oid rettype, int16 format)
                                 70                 :                : {
                                 71                 :                :     StringInfoData buf;
                                 72                 :                : 
 1101 nathan@postgresql.or       73                 :           1343 :     pq_beginmessage(&buf, PqMsg_FunctionCallResponse);
                                 74                 :                : 
 8511 tgl@sss.pgh.pa.us          75         [ -  + ]:           1343 :     if (isnull)
                                 76                 :                :     {
 2002 heikki.linnakangas@i       77                 :UBC           0 :         pq_sendint32(&buf, -1);
                                 78                 :                :     }
                                 79                 :                :     else
                                 80                 :                :     {
 8511 tgl@sss.pgh.pa.us          81         [ -  + ]:CBC        1343 :         if (format == 0)
                                 82                 :                :         {
                                 83                 :                :             Oid         typoutput;
                                 84                 :                :             bool        typisvarlena;
                                 85                 :                :             char       *outputstr;
                                 86                 :                : 
 7788 tgl@sss.pgh.pa.us          87                 :UBC           0 :             getTypeOutputInfo(rettype, &typoutput, &typisvarlena);
 7450                            88                 :              0 :             outputstr = OidOutputFunctionCall(typoutput, retval);
  906 heikki.linnakangas@i       89                 :              0 :             pq_sendcountedtext(&buf, outputstr, strlen(outputstr));
 8511 tgl@sss.pgh.pa.us          90                 :              0 :             pfree(outputstr);
                                 91                 :                :         }
 8511 tgl@sss.pgh.pa.us          92         [ +  - ]:CBC        1343 :         else if (format == 1)
                                 93                 :                :         {
                                 94                 :                :             Oid         typsend;
                                 95                 :                :             bool        typisvarlena;
                                 96                 :                :             bytea      *outputbytes;
                                 97                 :                : 
 7788                            98                 :           1343 :             getTypeBinaryOutputInfo(rettype, &typsend, &typisvarlena);
 7450                            99                 :           1343 :             outputbytes = OidSendFunctionCall(typsend, retval);
 3242 andres@anarazel.de        100                 :           1343 :             pq_sendint32(&buf, VARSIZE(outputbytes) - VARHDRSZ);
 8511 tgl@sss.pgh.pa.us         101                 :           1343 :             pq_sendbytes(&buf, VARDATA(outputbytes),
                                102                 :           1343 :                          VARSIZE(outputbytes) - VARHDRSZ);
                                103                 :           1343 :             pfree(outputbytes);
                                104                 :                :         }
                                105                 :                :         else
 8437 tgl@sss.pgh.pa.us         106         [ #  # ]:UBC           0 :             ereport(ERROR,
                                107                 :                :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                                108                 :                :                      errmsg("unsupported format code: %d", format)));
                                109                 :                :     }
                                110                 :                : 
 9986 tgl@sss.pgh.pa.us         111                 :CBC        1343 :     pq_endmessage(&buf);
11006 scrappy@hub.org           112                 :           1343 : }
                                113                 :                : 
                                114                 :                : /*
                                115                 :                :  * fetch_fp_info
                                116                 :                :  *
                                117                 :                :  * Performs catalog lookups to load a struct fp_info 'fip' for the
                                118                 :                :  * function 'func_id'.
                                119                 :                :  */
                                120                 :                : static void
 3354 tgl@sss.pgh.pa.us         121                 :           1343 : fetch_fp_info(Oid func_id, struct fp_info *fip)
                                122                 :                : {
                                123                 :                :     HeapTuple   func_htp;
                                124                 :                :     Form_pg_proc pp;
                                125                 :                : 
 8268 neilc@samurai.com         126         [ -  + ]:           1343 :     Assert(fip != NULL);
                                127                 :                : 
                                128                 :                :     /*
                                129                 :                :      * Since the validity of this structure is determined by whether the
                                130                 :                :      * funcid is OK, we clear the funcid here.  It must not be set to the
                                131                 :                :      * correct value until we are about to return with a good struct fp_info,
                                132                 :                :      * since we can be interrupted (i.e., with an ereport(ERROR, ...)) at any
                                133                 :                :      * time.  [No longer really an issue since we don't save the struct
                                134                 :                :      * fp_info across transactions anymore, but keep it anyway.]
                                135                 :                :      */
 7821 tgl@sss.pgh.pa.us         136   [ +  -  +  -  :          89981 :     MemSet(fip, 0, sizeof(struct fp_info));
                                     +  -  +  -  +  
                                                 + ]
10581 bruce@momjian.us          137                 :           1343 :     fip->funcid = InvalidOid;
                                138                 :                : 
 6038 rhaas@postgresql.org      139                 :           1343 :     func_htp = SearchSysCache1(PROCOID, ObjectIdGetDatum(func_id));
10581 bruce@momjian.us          140         [ -  + ]:           1343 :     if (!HeapTupleIsValid(func_htp))
 8437 tgl@sss.pgh.pa.us         141         [ #  # ]:UBC           0 :         ereport(ERROR,
                                142                 :                :                 (errcode(ERRCODE_UNDEFINED_FUNCTION),
                                143                 :                :                  errmsg("function with OID %u does not exist", func_id)));
10581 bruce@momjian.us          144                 :CBC        1343 :     pp = (Form_pg_proc) GETSTRUCT(func_htp);
                                145                 :                : 
                                146                 :                :     /* reject pg_proc entries that are unsafe to call via fastpath */
 1945 tgl@sss.pgh.pa.us         147   [ +  -  -  + ]:           1343 :     if (pp->prokind != PROKIND_FUNCTION || pp->proretset)
 1945 tgl@sss.pgh.pa.us         148         [ #  # ]:UBC           0 :         ereport(ERROR,
                                149                 :                :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                                150                 :                :                  errmsg("cannot call function \"%s\" via fastpath interface",
                                151                 :                :                         NameStr(pp->proname))));
                                152                 :                : 
                                153                 :                :     /* watch out for catalog entries with more than FUNC_MAX_ARGS args */
 7821 tgl@sss.pgh.pa.us         154         [ -  + ]:CBC        1343 :     if (pp->pronargs > FUNC_MAX_ARGS)
 7821 tgl@sss.pgh.pa.us         155         [ #  # ]:UBC           0 :         elog(ERROR, "function %s has more than %d arguments",
                                156                 :                :              NameStr(pp->proname), FUNC_MAX_ARGS);
                                157                 :                : 
 8511 tgl@sss.pgh.pa.us         158                 :CBC        1343 :     fip->namespace = pp->pronamespace;
                                159                 :           1343 :     fip->rettype = pp->prorettype;
 7821                           160                 :           1343 :     memcpy(fip->argtypes, pp->proargtypes.values, pp->pronargs * sizeof(Oid));
 7252                           161                 :           1343 :     strlcpy(fip->fname, NameStr(pp->proname), NAMEDATALEN);
                                162                 :                : 
 9415                           163                 :           1343 :     ReleaseSysCache(func_htp);
                                164                 :                : 
 1945                           165                 :           1343 :     fmgr_info(func_id, &fip->flinfo);
                                166                 :                : 
                                167                 :                :     /*
                                168                 :                :      * This must be last!
                                169                 :                :      */
10581 bruce@momjian.us          170                 :           1343 :     fip->funcid = func_id;
11006 scrappy@hub.org           171                 :           1343 : }
                                172                 :                : 
                                173                 :                : 
                                174                 :                : /*
                                175                 :                :  * HandleFunctionRequest
                                176                 :                :  *
                                177                 :                :  * Server side of PQfn (fastpath function calls from the frontend).
                                178                 :                :  * This corresponds to the libpq protocol symbol "F".
                                179                 :                :  *
                                180                 :                :  * INPUT:
                                181                 :                :  *      postgres.c has already read the message body and will pass it in
                                182                 :                :  *      msgBuf.
                                183                 :                :  *
                                184                 :                :  * Note: palloc()s done here and in the called function do not need to be
                                185                 :                :  * cleaned up explicitly.  We are called from PostgresMain() in the
                                186                 :                :  * MessageContext memory context, which will be automatically reset when
                                187                 :                :  * control returns to PostgresMain.
                                188                 :                :  */
                                189                 :                : void
 8531 tgl@sss.pgh.pa.us         190                 :           1343 : HandleFunctionRequest(StringInfo msgBuf)
                                191                 :                : {
 2770 andres@anarazel.de        192                 :           1343 :     LOCAL_FCINFO(fcinfo, FUNC_MAX_ARGS);
                                193                 :                :     Oid         fid;
                                194                 :                :     AclResult   aclresult;
                                195                 :                :     int16       rformat;
                                196                 :                :     Datum       retval;
                                197                 :                :     struct fp_info my_fp;
                                198                 :                :     struct fp_info *fip;
                                199                 :                :     bool        callit;
 7293 tgl@sss.pgh.pa.us         200                 :           1343 :     bool        was_logged = false;
                                201                 :                :     char        msec_str[32];
                                202                 :                : 
                                203                 :                :     /*
                                204                 :                :      * We only accept COMMIT/ABORT if we are in an aborted transaction, and
                                205                 :                :      * COMMIT/ABORT cannot be executed through the fastpath interface.
                                206                 :                :      */
 8531                           207         [ -  + ]:           1343 :     if (IsAbortedTransactionBlockState())
 8437 tgl@sss.pgh.pa.us         208         [ #  # ]:UBC           0 :         ereport(ERROR,
                                209                 :                :                 (errcode(ERRCODE_IN_FAILED_SQL_TRANSACTION),
                                210                 :                :                  errmsg("current transaction is aborted, "
                                211                 :                :                         "commands ignored until end of transaction block")));
                                212                 :                : 
                                213                 :                :     /*
                                214                 :                :      * Now that we know we are in a valid transaction, set snapshot in case
                                215                 :                :      * needed by function itself or one of the datatype I/O routines.
                                216                 :                :      */
 6681 alvherre@alvh.no-ip.      217                 :CBC        1343 :     PushActiveSnapshot(GetTransactionSnapshot());
                                218                 :                : 
                                219                 :                :     /*
                                220                 :                :      * Begin parsing the buffer contents.
                                221                 :                :      */
 3354 tgl@sss.pgh.pa.us         222                 :           1343 :     fid = (Oid) pq_getmsgint(msgBuf, 4);    /* function oid */
                                223                 :                : 
                                224                 :                :     /*
                                225                 :                :      * There used to be a lame attempt at caching lookup info here. Now we
                                226                 :                :      * just do the lookups on every call.
                                227                 :                :      */
 9218                           228                 :           1343 :     fip = &my_fp;
                                229                 :           1343 :     fetch_fp_info(fid, fip);
                                230                 :                : 
                                231                 :                :     /* Log as soon as we have the function OID and name */
 7252                           232         [ +  + ]:           1343 :     if (log_statement == LOGSTMT_ALL)
                                233                 :                :     {
                                234         [ +  - ]:            803 :         ereport(LOG,
                                235                 :                :                 (errmsg("fastpath function call: \"%s\" (OID %u)",
                                236                 :                :                         fip->fname, fid)));
                                237                 :            803 :         was_logged = true;
                                238                 :                :     }
                                239                 :                : 
                                240                 :                :     /*
                                241                 :                :      * Check permission to access and call function.  Since we didn't go
                                242                 :                :      * through a normal name lookup, we need to check schema usage too.
                                243                 :                :      */
 1383 peter@eisentraut.org      244                 :           1343 :     aclresult = object_aclcheck(NamespaceRelationId, fip->namespace, GetUserId(), ACL_USAGE);
 8511 tgl@sss.pgh.pa.us         245         [ -  + ]:           1343 :     if (aclresult != ACLCHECK_OK)
 3190 peter_e@gmx.net           246                 :UBC           0 :         aclcheck_error(aclresult, OBJECT_SCHEMA,
 8427 tgl@sss.pgh.pa.us         247                 :              0 :                        get_namespace_name(fip->namespace));
 4892 rhaas@postgresql.org      248         [ -  + ]:CBC        1343 :     InvokeNamespaceSearchHook(fip->namespace, true);
                                249                 :                : 
 1383 peter@eisentraut.org      250                 :           1343 :     aclresult = object_aclcheck(ProcedureRelationId, fid, GetUserId(), ACL_EXECUTE);
 8531 tgl@sss.pgh.pa.us         251         [ -  + ]:           1343 :     if (aclresult != ACLCHECK_OK)
 3190 peter_e@gmx.net           252                 :UBC           0 :         aclcheck_error(aclresult, OBJECT_FUNCTION,
 8427 tgl@sss.pgh.pa.us         253                 :              0 :                        get_func_name(fid));
 4885 rhaas@postgresql.org      254         [ -  + ]:CBC        1343 :     InvokeFunctionExecuteHook(fid);
                                255                 :                : 
                                256                 :                :     /*
                                257                 :                :      * Prepare function call info block and insert arguments.
                                258                 :                :      *
                                259                 :                :      * Note: for now we pass collation = InvalidOid, so collation-sensitive
                                260                 :                :      * functions can't be called this way.  Perhaps we should pass
                                261                 :                :      * DEFAULT_COLLATION_OID, instead?
                                262                 :                :      */
 2770 andres@anarazel.de        263                 :           1343 :     InitFunctionCallInfoData(*fcinfo, &fip->flinfo, 0, InvalidOid, NULL, NULL);
                                264                 :                : 
 2002 heikki.linnakangas@i      265                 :           1343 :     rformat = parse_fcall_arguments(msgBuf, fip, fcinfo);
                                266                 :                : 
                                267                 :                :     /* Verify we reached the end of the message where expected. */
 8512 tgl@sss.pgh.pa.us         268                 :           1343 :     pq_getmsgend(msgBuf);
                                269                 :                : 
                                270                 :                :     /*
                                271                 :                :      * If func is strict, must not call it for null args.
                                272                 :                :      */
 8511                           273                 :           1343 :     callit = true;
                                274         [ +  - ]:           1343 :     if (fip->flinfo.fn_strict)
                                275                 :                :     {
                                276                 :                :         int         i;
                                277                 :                : 
 2770 andres@anarazel.de        278         [ +  + ]:           3906 :         for (i = 0; i < fcinfo->nargs; i++)
                                279                 :                :         {
                                280         [ -  + ]:           2563 :             if (fcinfo->args[i].isnull)
                                281                 :                :             {
 8511 tgl@sss.pgh.pa.us         282                 :UBC           0 :                 callit = false;
                                283                 :              0 :                 break;
                                284                 :                :             }
                                285                 :                :         }
                                286                 :                :     }
                                287                 :                : 
 8511 tgl@sss.pgh.pa.us         288         [ +  - ]:CBC        1343 :     if (callit)
                                289                 :                :     {
                                290                 :                :         /* Okay, do it ... */
 2770 andres@anarazel.de        291                 :           1343 :         retval = FunctionCallInvoke(fcinfo);
                                292                 :                :     }
                                293                 :                :     else
                                294                 :                :     {
 2770 andres@anarazel.de        295                 :UBC           0 :         fcinfo->isnull = true;
 8511 tgl@sss.pgh.pa.us         296                 :              0 :         retval = (Datum) 0;
                                297                 :                :     }
                                298                 :                : 
                                299                 :                :     /* ensure we do at least one CHECK_FOR_INTERRUPTS per function call */
 7379 tgl@sss.pgh.pa.us         300         [ -  + ]:CBC        1343 :     CHECK_FOR_INTERRUPTS();
                                301                 :                : 
 2770 andres@anarazel.de        302                 :           1343 :     SendFunctionResult(retval, fcinfo->isnull, fip->rettype, rformat);
                                303                 :                : 
                                304                 :                :     /* We no longer need the snapshot */
 6681 alvherre@alvh.no-ip.      305                 :           1343 :     PopActiveSnapshot();
                                306                 :                : 
                                307                 :                :     /*
                                308                 :                :      * Emit duration logging if appropriate.
                                309                 :                :      */
 7293 tgl@sss.pgh.pa.us         310      [ -  -  + ]:           1343 :     switch (check_log_duration(msec_str, was_logged))
                                311                 :                :     {
 7293 tgl@sss.pgh.pa.us         312                 :UBC           0 :         case 1:
                                313         [ #  # ]:              0 :             ereport(LOG,
                                314                 :                :                     (errmsg("duration: %s ms", msec_str)));
                                315                 :              0 :             break;
                                316                 :              0 :         case 2:
                                317         [ #  # ]:              0 :             ereport(LOG,
                                318                 :                :                     (errmsg("duration: %s ms  fastpath function call: \"%s\" (OID %u)",
                                319                 :                :                             msec_str, fip->fname, fid)));
                                320                 :              0 :             break;
                                321                 :                :     }
 8512 tgl@sss.pgh.pa.us         322                 :CBC        1343 : }
                                323                 :                : 
                                324                 :                : /*
                                325                 :                :  * Parse function arguments in a 3.0 protocol message
                                326                 :                :  *
                                327                 :                :  * Argument values are loaded into *fcinfo, and the desired result format
                                328                 :                :  * is returned.
                                329                 :                :  */
                                330                 :                : static int16
 3354                           331                 :           1343 : parse_fcall_arguments(StringInfo msgBuf, struct fp_info *fip,
                                332                 :                :                       FunctionCallInfo fcinfo)
                                333                 :                : {
                                334                 :                :     int         nargs;
                                335                 :                :     int         i;
                                336                 :                :     int         numAFormats;
 8512                           337                 :           1343 :     int16      *aformats = NULL;
                                338                 :                :     StringInfoData abuf;
                                339                 :                : 
                                340                 :                :     /* Get the argument format codes */
                                341                 :           1343 :     numAFormats = pq_getmsgint(msgBuf, 2);
                                342         [ +  - ]:           1343 :     if (numAFormats > 0)
                                343                 :                :     {
   10 michael@paquier.xyz       344                 :GNC        1343 :         aformats = palloc_array(int16, numAFormats);
 8512 tgl@sss.pgh.pa.us         345         [ +  + ]:CBC        2686 :         for (i = 0; i < numAFormats; i++)
                                346                 :           1343 :             aformats[i] = pq_getmsgint(msgBuf, 2);
                                347                 :                :     }
                                348                 :                : 
                                349                 :           1343 :     nargs = pq_getmsgint(msgBuf, 2);    /* # of arguments */
                                350                 :                : 
 9587                           351   [ +  -  -  + ]:           1343 :     if (fip->flinfo.fn_nargs != nargs || nargs > FUNC_MAX_ARGS)
 8437 tgl@sss.pgh.pa.us         352         [ #  # ]:UBC           0 :         ereport(ERROR,
                                353                 :                :                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
                                354                 :                :                  errmsg("function call message contains %d arguments but function requires %d",
                                355                 :                :                         nargs, fip->flinfo.fn_nargs)));
                                356                 :                : 
 8512 tgl@sss.pgh.pa.us         357                 :CBC        1343 :     fcinfo->nargs = nargs;
                                358                 :                : 
 8511                           359   [ -  +  -  - ]:           1343 :     if (numAFormats > 1 && numAFormats != nargs)
 8437 tgl@sss.pgh.pa.us         360         [ #  # ]:UBC           0 :         ereport(ERROR,
                                361                 :                :                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
                                362                 :                :                  errmsg("function call message contains %d argument formats but %d arguments",
                                363                 :                :                         numAFormats, nargs)));
                                364                 :                : 
 8511 tgl@sss.pgh.pa.us         365                 :CBC        1343 :     initStringInfo(&abuf);
                                366                 :                : 
                                367                 :                :     /*
                                368                 :                :      * Copy supplied arguments into arg vector.
                                369                 :                :      */
 9587                           370         [ +  + ]:           3906 :     for (i = 0; i < nargs; ++i)
                                371                 :                :     {
                                372                 :                :         int         argsize;
                                373                 :                :         int16       aformat;
                                374                 :                : 
 8531                           375                 :           2563 :         argsize = pq_getmsgint(msgBuf, 4);
 8511                           376         [ -  + ]:           2563 :         if (argsize == -1)
                                377                 :                :         {
 2770 andres@anarazel.de        378                 :UBC           0 :             fcinfo->args[i].isnull = true;
                                379                 :                :         }
                                380                 :                :         else
                                381                 :                :         {
 2770 andres@anarazel.de        382                 :CBC        2563 :             fcinfo->args[i].isnull = false;
 7450 tgl@sss.pgh.pa.us         383         [ -  + ]:           2563 :             if (argsize < 0)
 7450 tgl@sss.pgh.pa.us         384         [ #  # ]:UBC           0 :                 ereport(ERROR,
                                385                 :                :                         (errcode(ERRCODE_PROTOCOL_VIOLATION),
                                386                 :                :                          errmsg("invalid argument size %d in function call message",
                                387                 :                :                                 argsize)));
                                388                 :                : 
                                389                 :                :             /* Reset abuf to empty, and insert raw data into it */
 7117 neilc@samurai.com         390                 :CBC        2563 :             resetStringInfo(&abuf);
 7450 tgl@sss.pgh.pa.us         391                 :           2563 :             appendBinaryStringInfo(&abuf,
                                392                 :           2563 :                                    pq_getmsgbytes(msgBuf, argsize),
                                393                 :                :                                    argsize);
                                394                 :                :         }
                                395                 :                : 
 8511                           396         [ -  + ]:           2563 :         if (numAFormats > 1)
 8511 tgl@sss.pgh.pa.us         397                 :UBC           0 :             aformat = aformats[i];
 8511 tgl@sss.pgh.pa.us         398         [ +  - ]:CBC        2563 :         else if (numAFormats > 0)
                                399                 :           2563 :             aformat = aformats[0];
                                400                 :                :         else
 8511 tgl@sss.pgh.pa.us         401                 :UBC           0 :             aformat = 0;        /* default = text */
                                402                 :                : 
 8511 tgl@sss.pgh.pa.us         403         [ -  + ]:CBC        2563 :         if (aformat == 0)
                                404                 :                :         {
                                405                 :                :             Oid         typinput;
                                406                 :                :             Oid         typioparam;
                                407                 :                :             char       *pstring;
                                408                 :                : 
 8117 tgl@sss.pgh.pa.us         409                 :UBC           0 :             getTypeInputInfo(fip->argtypes[i], &typinput, &typioparam);
                                410                 :                : 
                                411                 :                :             /*
                                412                 :                :              * Since stringinfo.c keeps a trailing null in place even for
                                413                 :                :              * binary data, the contents of abuf are a valid C string.  We
                                414                 :                :              * have to do encoding conversion before calling the typinput
                                415                 :                :              * routine, though.
                                416                 :                :              */
 7450                           417         [ #  # ]:              0 :             if (argsize == -1)
                                418                 :              0 :                 pstring = NULL;
                                419                 :                :             else
                                420                 :              0 :                 pstring = pg_client_to_server(abuf.data, argsize);
                                421                 :                : 
 2770 andres@anarazel.de        422                 :              0 :             fcinfo->args[i].value = OidInputFunctionCall(typinput, pstring,
                                423                 :                :                                                          typioparam, -1);
                                424                 :                :             /* Free result of encoding conversion, if any */
 7450 tgl@sss.pgh.pa.us         425   [ #  #  #  # ]:              0 :             if (pstring && pstring != abuf.data)
 8511                           426                 :              0 :                 pfree(pstring);
                                427                 :                :         }
 8511 tgl@sss.pgh.pa.us         428         [ +  - ]:CBC        2563 :         else if (aformat == 1)
                                429                 :                :         {
                                430                 :                :             Oid         typreceive;
                                431                 :                :             Oid         typioparam;
                                432                 :                :             StringInfo  bufptr;
                                433                 :                : 
                                434                 :                :             /* Call the argument type's binary input converter */
 8117                           435                 :           2563 :             getTypeBinaryInputInfo(fip->argtypes[i], &typreceive, &typioparam);
                                436                 :                : 
 7450                           437         [ -  + ]:           2563 :             if (argsize == -1)
 7450 tgl@sss.pgh.pa.us         438                 :UBC           0 :                 bufptr = NULL;
                                439                 :                :             else
 7450 tgl@sss.pgh.pa.us         440                 :CBC        2563 :                 bufptr = &abuf;
                                441                 :                : 
 2770 andres@anarazel.de        442                 :           2563 :             fcinfo->args[i].value = OidReceiveFunctionCall(typreceive, bufptr,
                                443                 :                :                                                            typioparam, -1);
                                444                 :                : 
                                445                 :                :             /* Trouble if it didn't eat the whole buffer */
 7450 tgl@sss.pgh.pa.us         446   [ +  -  -  + ]:           2563 :             if (argsize != -1 && abuf.cursor != abuf.len)
 8437 tgl@sss.pgh.pa.us         447         [ #  # ]:UBC           0 :                 ereport(ERROR,
                                448                 :                :                         (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
                                449                 :                :                          errmsg("incorrect binary data format in function argument %d",
                                450                 :                :                                 i + 1)));
                                451                 :                :         }
                                452                 :                :         else
                                453         [ #  # ]:              0 :             ereport(ERROR,
                                454                 :                :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                                455                 :                :                      errmsg("unsupported format code: %d", aformat)));
                                456                 :                :     }
                                457                 :                : 
                                458                 :                :     /* Return result format code */
 8511 tgl@sss.pgh.pa.us         459                 :CBC        1343 :     return (int16) pq_getmsgint(msgBuf, 2);
                                460                 :                : }
        

Generated by: LCOV version 2.0-1