LCOV - differential code coverage report
Current view: top level - src/backend/tcop - fastpath.c (source / functions) Coverage Total Hit UBC CBC
Current: c70b6db34ffeab48beef1fb4ce61bcad3772b8dd vs 06473f5a344df8c9594ead90a609b86f6724cff8 Lines: 69.7 % 132 92 40 92
Current Date: 2025-09-06 07:49:51 +0900 Functions: 100.0 % 4 4 4
Baseline: lcov-20250906-005545-baseline Branches: 40.0 % 115 46 69 46
Baseline Date: 2025-09-05 08:21:35 +0100 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(360..) days: 69.7 % 132 92 40 92
Function coverage date bins:
(360..) days: 100.0 % 4 4 4
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-2025, 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.
                                 15                 :                :  *
                                 16                 :                :  *-------------------------------------------------------------------------
                                 17                 :                :  */
                                 18                 :                : #include "postgres.h"
                                 19                 :                : 
                                 20                 :                : #include "access/htup_details.h"
                                 21                 :                : #include "access/xact.h"
                                 22                 :                : #include "catalog/objectaccess.h"
                                 23                 :                : #include "catalog/pg_namespace.h"
                                 24                 :                : #include "catalog/pg_proc.h"
                                 25                 :                : #include "libpq/pqformat.h"
                                 26                 :                : #include "libpq/protocol.h"
                                 27                 :                : #include "mb/pg_wchar.h"
                                 28                 :                : #include "miscadmin.h"
                                 29                 :                : #include "tcop/fastpath.h"
                                 30                 :                : #include "tcop/tcopprot.h"
                                 31                 :                : #include "utils/acl.h"
                                 32                 :                : #include "utils/lsyscache.h"
                                 33                 :                : #include "utils/snapmgr.h"
                                 34                 :                : #include "utils/syscache.h"
                                 35                 :                : 
                                 36                 :                : 
                                 37                 :                : /*
                                 38                 :                :  * Formerly, this code attempted to cache the function and type info
                                 39                 :                :  * looked up by fetch_fp_info, but only for the duration of a single
                                 40                 :                :  * transaction command (since in theory the info could change between
                                 41                 :                :  * commands).  This was utterly useless, because postgres.c executes
                                 42                 :                :  * each fastpath call as a separate transaction command, and so the
                                 43                 :                :  * cached data could never actually have been reused.  If it had worked
                                 44                 :                :  * as intended, it would have had problems anyway with dangling references
                                 45                 :                :  * in the FmgrInfo struct.  So, forget about caching and just repeat the
                                 46                 :                :  * syscache fetches on each usage.  They're not *that* expensive.
                                 47                 :                :  */
                                 48                 :                : struct fp_info
                                 49                 :                : {
                                 50                 :                :     Oid         funcid;
                                 51                 :                :     FmgrInfo    flinfo;         /* function lookup info for funcid */
                                 52                 :                :     Oid         namespace;      /* other stuff from pg_proc */
                                 53                 :                :     Oid         rettype;
                                 54                 :                :     Oid         argtypes[FUNC_MAX_ARGS];
                                 55                 :                :     char        fname[NAMEDATALEN]; /* function name for logging */
                                 56                 :                : };
                                 57                 :                : 
                                 58                 :                : 
                                 59                 :                : static int16 parse_fcall_arguments(StringInfo msgBuf, struct fp_info *fip,
                                 60                 :                :                                    FunctionCallInfo fcinfo);
                                 61                 :                : 
                                 62                 :                : /* ----------------
                                 63                 :                :  *      SendFunctionResult
                                 64                 :                :  * ----------------
                                 65                 :                :  */
                                 66                 :                : static void
 8156 tgl@sss.pgh.pa.us          67                 :CBC        1084 : SendFunctionResult(Datum retval, bool isnull, Oid rettype, int16 format)
                                 68                 :                : {
                                 69                 :                :     StringInfoData buf;
                                 70                 :                : 
  746 nathan@postgresql.or       71                 :           1084 :     pq_beginmessage(&buf, PqMsg_FunctionCallResponse);
                                 72                 :                : 
 8156 tgl@sss.pgh.pa.us          73         [ -  + ]:           1084 :     if (isnull)
                                 74                 :                :     {
 1647 heikki.linnakangas@i       75                 :UBC           0 :         pq_sendint32(&buf, -1);
                                 76                 :                :     }
                                 77                 :                :     else
                                 78                 :                :     {
 8156 tgl@sss.pgh.pa.us          79         [ -  + ]:CBC        1084 :         if (format == 0)
                                 80                 :                :         {
                                 81                 :                :             Oid         typoutput;
                                 82                 :                :             bool        typisvarlena;
                                 83                 :                :             char       *outputstr;
                                 84                 :                : 
 7433 tgl@sss.pgh.pa.us          85                 :UBC           0 :             getTypeOutputInfo(rettype, &typoutput, &typisvarlena);
 7095                            86                 :              0 :             outputstr = OidOutputFunctionCall(typoutput, retval);
  551 heikki.linnakangas@i       87                 :              0 :             pq_sendcountedtext(&buf, outputstr, strlen(outputstr));
 8156 tgl@sss.pgh.pa.us          88                 :              0 :             pfree(outputstr);
                                 89                 :                :         }
 8156 tgl@sss.pgh.pa.us          90         [ +  - ]:CBC        1084 :         else if (format == 1)
                                 91                 :                :         {
                                 92                 :                :             Oid         typsend;
                                 93                 :                :             bool        typisvarlena;
                                 94                 :                :             bytea      *outputbytes;
                                 95                 :                : 
 7433                            96                 :           1084 :             getTypeBinaryOutputInfo(rettype, &typsend, &typisvarlena);
 7095                            97                 :           1084 :             outputbytes = OidSendFunctionCall(typsend, retval);
 2887 andres@anarazel.de         98                 :           1084 :             pq_sendint32(&buf, VARSIZE(outputbytes) - VARHDRSZ);
 8156 tgl@sss.pgh.pa.us          99                 :           1084 :             pq_sendbytes(&buf, VARDATA(outputbytes),
                                100                 :           1084 :                          VARSIZE(outputbytes) - VARHDRSZ);
                                101                 :           1084 :             pfree(outputbytes);
                                102                 :                :         }
                                103                 :                :         else
 8082 tgl@sss.pgh.pa.us         104         [ #  # ]:UBC           0 :             ereport(ERROR,
                                105                 :                :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                                106                 :                :                      errmsg("unsupported format code: %d", format)));
                                107                 :                :     }
                                108                 :                : 
 9631 tgl@sss.pgh.pa.us         109                 :CBC        1084 :     pq_endmessage(&buf);
10651 scrappy@hub.org           110                 :           1084 : }
                                111                 :                : 
                                112                 :                : /*
                                113                 :                :  * fetch_fp_info
                                114                 :                :  *
                                115                 :                :  * Performs catalog lookups to load a struct fp_info 'fip' for the
                                116                 :                :  * function 'func_id'.
                                117                 :                :  */
                                118                 :                : static void
 2999 tgl@sss.pgh.pa.us         119                 :           1084 : fetch_fp_info(Oid func_id, struct fp_info *fip)
                                120                 :                : {
                                121                 :                :     HeapTuple   func_htp;
                                122                 :                :     Form_pg_proc pp;
                                123                 :                : 
 7913 neilc@samurai.com         124         [ -  + ]:           1084 :     Assert(fip != NULL);
                                125                 :                : 
                                126                 :                :     /*
                                127                 :                :      * Since the validity of this structure is determined by whether the
                                128                 :                :      * funcid is OK, we clear the funcid here.  It must not be set to the
                                129                 :                :      * correct value until we are about to return with a good struct fp_info,
                                130                 :                :      * since we can be interrupted (i.e., with an ereport(ERROR, ...)) at any
                                131                 :                :      * time.  [No longer really an issue since we don't save the struct
                                132                 :                :      * fp_info across transactions anymore, but keep it anyway.]
                                133                 :                :      */
 7466 tgl@sss.pgh.pa.us         134   [ +  -  +  -  :          72628 :     MemSet(fip, 0, sizeof(struct fp_info));
                                     +  -  +  -  +  
                                                 + ]
10226 bruce@momjian.us          135                 :           1084 :     fip->funcid = InvalidOid;
                                136                 :                : 
 5683 rhaas@postgresql.org      137                 :           1084 :     func_htp = SearchSysCache1(PROCOID, ObjectIdGetDatum(func_id));
10226 bruce@momjian.us          138         [ -  + ]:           1084 :     if (!HeapTupleIsValid(func_htp))
 8082 tgl@sss.pgh.pa.us         139         [ #  # ]:UBC           0 :         ereport(ERROR,
                                140                 :                :                 (errcode(ERRCODE_UNDEFINED_FUNCTION),
                                141                 :                :                  errmsg("function with OID %u does not exist", func_id)));
10226 bruce@momjian.us          142                 :CBC        1084 :     pp = (Form_pg_proc) GETSTRUCT(func_htp);
                                143                 :                : 
                                144                 :                :     /* reject pg_proc entries that are unsafe to call via fastpath */
 1590 tgl@sss.pgh.pa.us         145   [ +  -  -  + ]:           1084 :     if (pp->prokind != PROKIND_FUNCTION || pp->proretset)
 1590 tgl@sss.pgh.pa.us         146         [ #  # ]:UBC           0 :         ereport(ERROR,
                                147                 :                :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                                148                 :                :                  errmsg("cannot call function \"%s\" via fastpath interface",
                                149                 :                :                         NameStr(pp->proname))));
                                150                 :                : 
                                151                 :                :     /* watch out for catalog entries with more than FUNC_MAX_ARGS args */
 7466 tgl@sss.pgh.pa.us         152         [ -  + ]:CBC        1084 :     if (pp->pronargs > FUNC_MAX_ARGS)
 7466 tgl@sss.pgh.pa.us         153         [ #  # ]:UBC           0 :         elog(ERROR, "function %s has more than %d arguments",
                                154                 :                :              NameStr(pp->proname), FUNC_MAX_ARGS);
                                155                 :                : 
 8156 tgl@sss.pgh.pa.us         156                 :CBC        1084 :     fip->namespace = pp->pronamespace;
                                157                 :           1084 :     fip->rettype = pp->prorettype;
 7466                           158                 :           1084 :     memcpy(fip->argtypes, pp->proargtypes.values, pp->pronargs * sizeof(Oid));
 6897                           159                 :           1084 :     strlcpy(fip->fname, NameStr(pp->proname), NAMEDATALEN);
                                160                 :                : 
 9060                           161                 :           1084 :     ReleaseSysCache(func_htp);
                                162                 :                : 
 1590                           163                 :           1084 :     fmgr_info(func_id, &fip->flinfo);
                                164                 :                : 
                                165                 :                :     /*
                                166                 :                :      * This must be last!
                                167                 :                :      */
10226 bruce@momjian.us          168                 :           1084 :     fip->funcid = func_id;
10651 scrappy@hub.org           169                 :           1084 : }
                                170                 :                : 
                                171                 :                : 
                                172                 :                : /*
                                173                 :                :  * HandleFunctionRequest
                                174                 :                :  *
                                175                 :                :  * Server side of PQfn (fastpath function calls from the frontend).
                                176                 :                :  * This corresponds to the libpq protocol symbol "F".
                                177                 :                :  *
                                178                 :                :  * INPUT:
                                179                 :                :  *      postgres.c has already read the message body and will pass it in
                                180                 :                :  *      msgBuf.
                                181                 :                :  *
                                182                 :                :  * Note: palloc()s done here and in the called function do not need to be
                                183                 :                :  * cleaned up explicitly.  We are called from PostgresMain() in the
                                184                 :                :  * MessageContext memory context, which will be automatically reset when
                                185                 :                :  * control returns to PostgresMain.
                                186                 :                :  */
                                187                 :                : void
 8176 tgl@sss.pgh.pa.us         188                 :           1084 : HandleFunctionRequest(StringInfo msgBuf)
                                189                 :                : {
 2415 andres@anarazel.de        190                 :           1084 :     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;
 6938 tgl@sss.pgh.pa.us         198                 :           1084 :     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                 :                :      */
 8176                           205         [ -  + ]:           1084 :     if (IsAbortedTransactionBlockState())
 8082 tgl@sss.pgh.pa.us         206         [ #  # ]:UBC           0 :         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                 :                :      */
 6326 alvherre@alvh.no-ip.      215                 :CBC        1084 :     PushActiveSnapshot(GetTransactionSnapshot());
                                216                 :                : 
                                217                 :                :     /*
                                218                 :                :      * Begin parsing the buffer contents.
                                219                 :                :      */
 2999 tgl@sss.pgh.pa.us         220                 :           1084 :     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                 :                :      */
 8863                           226                 :           1084 :     fip = &my_fp;
                                227                 :           1084 :     fetch_fp_info(fid, fip);
                                228                 :                : 
                                229                 :                :     /* Log as soon as we have the function OID and name */
 6897                           230         [ +  + ]:           1084 :     if (log_statement == LOGSTMT_ALL)
                                231                 :                :     {
                                232         [ +  - ]:            544 :         ereport(LOG,
                                233                 :                :                 (errmsg("fastpath function call: \"%s\" (OID %u)",
                                234                 :                :                         fip->fname, fid)));
                                235                 :            544 :         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                 :                :      */
 1028 peter@eisentraut.org      242                 :           1084 :     aclresult = object_aclcheck(NamespaceRelationId, fip->namespace, GetUserId(), ACL_USAGE);
 8156 tgl@sss.pgh.pa.us         243         [ -  + ]:           1084 :     if (aclresult != ACLCHECK_OK)
 2835 peter_e@gmx.net           244                 :UBC           0 :         aclcheck_error(aclresult, OBJECT_SCHEMA,
 8072 tgl@sss.pgh.pa.us         245                 :              0 :                        get_namespace_name(fip->namespace));
 4537 rhaas@postgresql.org      246         [ -  + ]:CBC        1084 :     InvokeNamespaceSearchHook(fip->namespace, true);
                                247                 :                : 
 1028 peter@eisentraut.org      248                 :           1084 :     aclresult = object_aclcheck(ProcedureRelationId, fid, GetUserId(), ACL_EXECUTE);
 8176 tgl@sss.pgh.pa.us         249         [ -  + ]:           1084 :     if (aclresult != ACLCHECK_OK)
 2835 peter_e@gmx.net           250                 :UBC           0 :         aclcheck_error(aclresult, OBJECT_FUNCTION,
 8072 tgl@sss.pgh.pa.us         251                 :              0 :                        get_func_name(fid));
 4530 rhaas@postgresql.org      252         [ -  + ]:CBC        1084 :     InvokeFunctionExecuteHook(fid);
                                253                 :                : 
                                254                 :                :     /*
                                255                 :                :      * Prepare function call info block and insert arguments.
                                256                 :                :      *
                                257                 :                :      * Note: for now we pass collation = InvalidOid, so collation-sensitive
                                258                 :                :      * functions can't be called this way.  Perhaps we should pass
                                259                 :                :      * DEFAULT_COLLATION_OID, instead?
                                260                 :                :      */
 2415 andres@anarazel.de        261                 :           1084 :     InitFunctionCallInfoData(*fcinfo, &fip->flinfo, 0, InvalidOid, NULL, NULL);
                                262                 :                : 
 1647 heikki.linnakangas@i      263                 :           1084 :     rformat = parse_fcall_arguments(msgBuf, fip, fcinfo);
                                264                 :                : 
                                265                 :                :     /* Verify we reached the end of the message where expected. */
 8157 tgl@sss.pgh.pa.us         266                 :           1084 :     pq_getmsgend(msgBuf);
                                267                 :                : 
                                268                 :                :     /*
                                269                 :                :      * If func is strict, must not call it for null args.
                                270                 :                :      */
 8156                           271                 :           1084 :     callit = true;
                                272         [ +  - ]:           1084 :     if (fip->flinfo.fn_strict)
                                273                 :                :     {
                                274                 :                :         int         i;
                                275                 :                : 
 2415 andres@anarazel.de        276         [ +  + ]:           3137 :         for (i = 0; i < fcinfo->nargs; i++)
                                277                 :                :         {
                                278         [ -  + ]:           2053 :             if (fcinfo->args[i].isnull)
                                279                 :                :             {
 8156 tgl@sss.pgh.pa.us         280                 :UBC           0 :                 callit = false;
                                281                 :              0 :                 break;
                                282                 :                :             }
                                283                 :                :         }
                                284                 :                :     }
                                285                 :                : 
 8156 tgl@sss.pgh.pa.us         286         [ +  - ]:CBC        1084 :     if (callit)
                                287                 :                :     {
                                288                 :                :         /* Okay, do it ... */
 2415 andres@anarazel.de        289                 :           1084 :         retval = FunctionCallInvoke(fcinfo);
                                290                 :                :     }
                                291                 :                :     else
                                292                 :                :     {
 2415 andres@anarazel.de        293                 :UBC           0 :         fcinfo->isnull = true;
 8156 tgl@sss.pgh.pa.us         294                 :              0 :         retval = (Datum) 0;
                                295                 :                :     }
                                296                 :                : 
                                297                 :                :     /* ensure we do at least one CHECK_FOR_INTERRUPTS per function call */
 7024 tgl@sss.pgh.pa.us         298         [ -  + ]:CBC        1084 :     CHECK_FOR_INTERRUPTS();
                                299                 :                : 
 2415 andres@anarazel.de        300                 :           1084 :     SendFunctionResult(retval, fcinfo->isnull, fip->rettype, rformat);
                                301                 :                : 
                                302                 :                :     /* We no longer need the snapshot */
 6326 alvherre@alvh.no-ip.      303                 :           1084 :     PopActiveSnapshot();
                                304                 :                : 
                                305                 :                :     /*
                                306                 :                :      * Emit duration logging if appropriate.
                                307                 :                :      */
 6938 tgl@sss.pgh.pa.us         308      [ -  -  + ]:           1084 :     switch (check_log_duration(msec_str, was_logged))
                                309                 :                :     {
 6938 tgl@sss.pgh.pa.us         310                 :UBC           0 :         case 1:
                                311         [ #  # ]:              0 :             ereport(LOG,
                                312                 :                :                     (errmsg("duration: %s ms", msec_str)));
                                313                 :              0 :             break;
                                314                 :              0 :         case 2:
                                315         [ #  # ]:              0 :             ereport(LOG,
                                316                 :                :                     (errmsg("duration: %s ms  fastpath function call: \"%s\" (OID %u)",
                                317                 :                :                             msec_str, fip->fname, fid)));
                                318                 :              0 :             break;
                                319                 :                :     }
 8157 tgl@sss.pgh.pa.us         320                 :CBC        1084 : }
                                321                 :                : 
                                322                 :                : /*
                                323                 :                :  * Parse function arguments in a 3.0 protocol message
                                324                 :                :  *
                                325                 :                :  * Argument values are loaded into *fcinfo, and the desired result format
                                326                 :                :  * is returned.
                                327                 :                :  */
                                328                 :                : static int16
 2999                           329                 :           1084 : parse_fcall_arguments(StringInfo msgBuf, struct fp_info *fip,
                                330                 :                :                       FunctionCallInfo fcinfo)
                                331                 :                : {
                                332                 :                :     int         nargs;
                                333                 :                :     int         i;
                                334                 :                :     int         numAFormats;
 8157                           335                 :           1084 :     int16      *aformats = NULL;
                                336                 :                :     StringInfoData abuf;
                                337                 :                : 
                                338                 :                :     /* Get the argument format codes */
                                339                 :           1084 :     numAFormats = pq_getmsgint(msgBuf, 2);
                                340         [ +  - ]:           1084 :     if (numAFormats > 0)
                                341                 :                :     {
                                342                 :           1084 :         aformats = (int16 *) palloc(numAFormats * sizeof(int16));
                                343         [ +  + ]:           2168 :         for (i = 0; i < numAFormats; i++)
                                344                 :           1084 :             aformats[i] = pq_getmsgint(msgBuf, 2);
                                345                 :                :     }
                                346                 :                : 
                                347                 :           1084 :     nargs = pq_getmsgint(msgBuf, 2);    /* # of arguments */
                                348                 :                : 
 9232                           349   [ +  -  -  + ]:           1084 :     if (fip->flinfo.fn_nargs != nargs || nargs > FUNC_MAX_ARGS)
 8082 tgl@sss.pgh.pa.us         350         [ #  # ]:UBC           0 :         ereport(ERROR,
                                351                 :                :                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
                                352                 :                :                  errmsg("function call message contains %d arguments but function requires %d",
                                353                 :                :                         nargs, fip->flinfo.fn_nargs)));
                                354                 :                : 
 8157 tgl@sss.pgh.pa.us         355                 :CBC        1084 :     fcinfo->nargs = nargs;
                                356                 :                : 
 8156                           357   [ -  +  -  - ]:           1084 :     if (numAFormats > 1 && numAFormats != nargs)
 8082 tgl@sss.pgh.pa.us         358         [ #  # ]:UBC           0 :         ereport(ERROR,
                                359                 :                :                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
                                360                 :                :                  errmsg("function call message contains %d argument formats but %d arguments",
                                361                 :                :                         numAFormats, nargs)));
                                362                 :                : 
 8156 tgl@sss.pgh.pa.us         363                 :CBC        1084 :     initStringInfo(&abuf);
                                364                 :                : 
                                365                 :                :     /*
                                366                 :                :      * Copy supplied arguments into arg vector.
                                367                 :                :      */
 9232                           368         [ +  + ]:           3137 :     for (i = 0; i < nargs; ++i)
                                369                 :                :     {
                                370                 :                :         int         argsize;
                                371                 :                :         int16       aformat;
                                372                 :                : 
 8176                           373                 :           2053 :         argsize = pq_getmsgint(msgBuf, 4);
 8156                           374         [ -  + ]:           2053 :         if (argsize == -1)
                                375                 :                :         {
 2415 andres@anarazel.de        376                 :UBC           0 :             fcinfo->args[i].isnull = true;
                                377                 :                :         }
                                378                 :                :         else
                                379                 :                :         {
 2415 andres@anarazel.de        380                 :CBC        2053 :             fcinfo->args[i].isnull = false;
 7095 tgl@sss.pgh.pa.us         381         [ -  + ]:           2053 :             if (argsize < 0)
 7095 tgl@sss.pgh.pa.us         382         [ #  # ]:UBC           0 :                 ereport(ERROR,
                                383                 :                :                         (errcode(ERRCODE_PROTOCOL_VIOLATION),
                                384                 :                :                          errmsg("invalid argument size %d in function call message",
                                385                 :                :                                 argsize)));
                                386                 :                : 
                                387                 :                :             /* Reset abuf to empty, and insert raw data into it */
 6762 neilc@samurai.com         388                 :CBC        2053 :             resetStringInfo(&abuf);
 7095 tgl@sss.pgh.pa.us         389                 :           2053 :             appendBinaryStringInfo(&abuf,
                                390                 :           2053 :                                    pq_getmsgbytes(msgBuf, argsize),
                                391                 :                :                                    argsize);
                                392                 :                :         }
                                393                 :                : 
 8156                           394         [ -  + ]:           2053 :         if (numAFormats > 1)
 8156 tgl@sss.pgh.pa.us         395                 :UBC           0 :             aformat = aformats[i];
 8156 tgl@sss.pgh.pa.us         396         [ +  - ]:CBC        2053 :         else if (numAFormats > 0)
                                397                 :           2053 :             aformat = aformats[0];
                                398                 :                :         else
 8156 tgl@sss.pgh.pa.us         399                 :UBC           0 :             aformat = 0;        /* default = text */
                                400                 :                : 
 8156 tgl@sss.pgh.pa.us         401         [ -  + ]:CBC        2053 :         if (aformat == 0)
                                402                 :                :         {
                                403                 :                :             Oid         typinput;
                                404                 :                :             Oid         typioparam;
                                405                 :                :             char       *pstring;
                                406                 :                : 
 7762 tgl@sss.pgh.pa.us         407                 :UBC           0 :             getTypeInputInfo(fip->argtypes[i], &typinput, &typioparam);
                                408                 :                : 
                                409                 :                :             /*
                                410                 :                :              * Since stringinfo.c keeps a trailing null in place even for
                                411                 :                :              * binary data, the contents of abuf are a valid C string.  We
                                412                 :                :              * have to do encoding conversion before calling the typinput
                                413                 :                :              * routine, though.
                                414                 :                :              */
 7095                           415         [ #  # ]:              0 :             if (argsize == -1)
                                416                 :              0 :                 pstring = NULL;
                                417                 :                :             else
                                418                 :              0 :                 pstring = pg_client_to_server(abuf.data, argsize);
                                419                 :                : 
 2415 andres@anarazel.de        420                 :              0 :             fcinfo->args[i].value = OidInputFunctionCall(typinput, pstring,
                                421                 :                :                                                          typioparam, -1);
                                422                 :                :             /* Free result of encoding conversion, if any */
 7095 tgl@sss.pgh.pa.us         423   [ #  #  #  # ]:              0 :             if (pstring && pstring != abuf.data)
 8156                           424                 :              0 :                 pfree(pstring);
                                425                 :                :         }
 8156 tgl@sss.pgh.pa.us         426         [ +  - ]:CBC        2053 :         else if (aformat == 1)
                                427                 :                :         {
                                428                 :                :             Oid         typreceive;
                                429                 :                :             Oid         typioparam;
                                430                 :                :             StringInfo  bufptr;
                                431                 :                : 
                                432                 :                :             /* Call the argument type's binary input converter */
 7762                           433                 :           2053 :             getTypeBinaryInputInfo(fip->argtypes[i], &typreceive, &typioparam);
                                434                 :                : 
 7095                           435         [ -  + ]:           2053 :             if (argsize == -1)
 7095 tgl@sss.pgh.pa.us         436                 :UBC           0 :                 bufptr = NULL;
                                437                 :                :             else
 7095 tgl@sss.pgh.pa.us         438                 :CBC        2053 :                 bufptr = &abuf;
                                439                 :                : 
 2415 andres@anarazel.de        440                 :           2053 :             fcinfo->args[i].value = OidReceiveFunctionCall(typreceive, bufptr,
                                441                 :                :                                                            typioparam, -1);
                                442                 :                : 
                                443                 :                :             /* Trouble if it didn't eat the whole buffer */
 7095 tgl@sss.pgh.pa.us         444   [ +  -  -  + ]:           2053 :             if (argsize != -1 && abuf.cursor != abuf.len)
 8082 tgl@sss.pgh.pa.us         445         [ #  # ]:UBC           0 :                 ereport(ERROR,
                                446                 :                :                         (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
                                447                 :                :                          errmsg("incorrect binary data format in function argument %d",
                                448                 :                :                                 i + 1)));
                                449                 :                :         }
                                450                 :                :         else
                                451         [ #  # ]:              0 :             ereport(ERROR,
                                452                 :                :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                                453                 :                :                      errmsg("unsupported format code: %d", aformat)));
                                454                 :                :     }
                                455                 :                : 
                                456                 :                :     /* Return result format code */
 8156 tgl@sss.pgh.pa.us         457                 :CBC        1084 :     return (int16) pq_getmsgint(msgBuf, 2);
                                458                 :                : }
        

Generated by: LCOV version 2.4-beta