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

Generated by: LCOV version 2.1-beta2-3-g6141622