LCOV - differential code coverage report
Current view: top level - src/bin/psql - large_obj.c (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage 16@8cea358b128 vs 17@8cea358b128 Lines: 53.3 % 107 57 50 57
Current Date: 2024-04-14 14:21:10 Functions: 85.7 % 7 6 1 6
Baseline: 16@8cea358b128 Branches: 42.0 % 50 21 29 21
Baseline Date: 2024-04-14 14:21:09 Line coverage date bins:
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed (240..) days: 53.3 % 107 57 50 57
Function coverage date bins:
(240..) days: 85.7 % 7 6 1 6
Branch coverage date bins:
(240..) days: 42.0 % 50 21 29 21

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*
                                  2                 :                :  * psql - the PostgreSQL interactive terminal
                                  3                 :                :  *
                                  4                 :                :  * Copyright (c) 2000-2024, PostgreSQL Global Development Group
                                  5                 :                :  *
                                  6                 :                :  * src/bin/psql/large_obj.c
                                  7                 :                :  */
                                  8                 :                : #include "postgres_fe.h"
                                  9                 :                : 
                                 10                 :                : #include "common.h"
                                 11                 :                : #include "common/logging.h"
                                 12                 :                : #include "fe_utils/cancel.h"
                                 13                 :                : #include "large_obj.h"
                                 14                 :                : #include "settings.h"
                                 15                 :                : 
                                 16                 :                : static void print_lo_result(const char *fmt,...) pg_attribute_printf(1, 2);
                                 17                 :                : 
                                 18                 :                : static void
 6294 neilc@samurai.com          19                 :CBC          22 : print_lo_result(const char *fmt,...)
                                 20                 :                : {
                                 21                 :                :     va_list     ap;
                                 22                 :                : 
                                 23         [ +  + ]:             22 :     if (!pset.quiet)
                                 24                 :                :     {
                                 25         [ -  + ]:              1 :         if (pset.popt.topt.format == PRINT_HTML)
 6294 neilc@samurai.com          26                 :UBC           0 :             fputs("<p>", pset.queryFout);
                                 27                 :                : 
 6294 neilc@samurai.com          28                 :CBC           1 :         va_start(ap, fmt);
                                 29                 :              1 :         vfprintf(pset.queryFout, fmt, ap);
                                 30                 :              1 :         va_end(ap);
                                 31                 :                : 
                                 32         [ -  + ]:              1 :         if (pset.popt.topt.format == PRINT_HTML)
 6294 neilc@samurai.com          33                 :UBC           0 :             fputs("</p>\n", pset.queryFout);
                                 34                 :                :         else
 6294 neilc@samurai.com          35                 :CBC           1 :             fputs("\n", pset.queryFout);
                                 36                 :                :     }
                                 37                 :                : 
                                 38         [ -  + ]:             22 :     if (pset.logfile)
                                 39                 :                :     {
 6294 neilc@samurai.com          40                 :UBC           0 :         va_start(ap, fmt);
                                 41                 :              0 :         vfprintf(pset.logfile, fmt, ap);
                                 42                 :              0 :         va_end(ap);
                                 43                 :              0 :         fputs("\n", pset.logfile);
                                 44                 :                :     }
 6294 neilc@samurai.com          45                 :CBC          22 : }
                                 46                 :                : 
                                 47                 :                : 
                                 48                 :                : /*
                                 49                 :                :  * Prepare to do a large-object operation.  We *must* be inside a transaction
                                 50                 :                :  * block for all these operations, so start one if needed.
                                 51                 :                :  *
                                 52                 :                :  * Returns true if okay, false if failed.  *own_transaction is set to indicate
                                 53                 :                :  * if we started our own transaction or not.
                                 54                 :                :  */
                                 55                 :                : static bool
 7596 tgl@sss.pgh.pa.us          56                 :             22 : start_lo_xact(const char *operation, bool *own_transaction)
                                 57                 :                : {
                                 58                 :                :     PGTransactionStatusType tstatus;
                                 59                 :                :     PGresult   *res;
                                 60                 :                : 
                                 61                 :             22 :     *own_transaction = false;
                                 62                 :                : 
                                 63         [ -  + ]:             22 :     if (!pset.db)
                                 64                 :                :     {
 1840 peter@eisentraut.org       65                 :UBC           0 :         pg_log_error("%s: not connected to a database", operation);
 7596 tgl@sss.pgh.pa.us          66                 :              0 :         return false;
                                 67                 :                :     }
                                 68                 :                : 
 7596 tgl@sss.pgh.pa.us          69                 :CBC          22 :     tstatus = PQtransactionStatus(pset.db);
                                 70                 :                : 
                                 71   [ +  -  -  - ]:             22 :     switch (tstatus)
                                 72                 :                :     {
                                 73                 :             22 :         case PQTRANS_IDLE:
                                 74                 :                :             /* need to start our own xact */
 3461 fujii@postgresql.org       75         [ -  + ]:             22 :             if (!(res = PSQLexec("BEGIN")))
 7596 tgl@sss.pgh.pa.us          76                 :UBC           0 :                 return false;
 7596 tgl@sss.pgh.pa.us          77                 :CBC          22 :             PQclear(res);
                                 78                 :             22 :             *own_transaction = true;
                                 79                 :             22 :             break;
 7596 tgl@sss.pgh.pa.us          80                 :UBC           0 :         case PQTRANS_INTRANS:
                                 81                 :                :             /* use the existing xact */
                                 82                 :              0 :             break;
                                 83                 :              0 :         case PQTRANS_INERROR:
 1840 peter@eisentraut.org       84                 :              0 :             pg_log_error("%s: current transaction is aborted", operation);
 7596 tgl@sss.pgh.pa.us          85                 :              0 :             return false;
                                 86                 :              0 :         default:
 1840 peter@eisentraut.org       87                 :              0 :             pg_log_error("%s: unknown transaction status", operation);
 7596 tgl@sss.pgh.pa.us          88                 :              0 :             return false;
                                 89                 :                :     }
                                 90                 :                : 
 7596 tgl@sss.pgh.pa.us          91                 :CBC          22 :     return true;
                                 92                 :                : }
                                 93                 :                : 
                                 94                 :                : /*
                                 95                 :                :  * Clean up after a successful LO operation
                                 96                 :                :  */
                                 97                 :                : static bool
                                 98                 :             22 : finish_lo_xact(const char *operation, bool own_transaction)
                                 99                 :                : {
                                100                 :                :     PGresult   *res;
                                101                 :                : 
 6438                           102   [ +  -  +  - ]:             22 :     if (own_transaction && pset.autocommit)
                                103                 :                :     {
                                104                 :                :         /* close out our own xact */
 3461 fujii@postgresql.org      105         [ -  + ]:             22 :         if (!(res = PSQLexec("COMMIT")))
                                106                 :                :         {
 3461 fujii@postgresql.org      107                 :UBC           0 :             res = PSQLexec("ROLLBACK");
 7596 tgl@sss.pgh.pa.us         108                 :              0 :             PQclear(res);
                                109                 :              0 :             return false;
                                110                 :                :         }
 7596 tgl@sss.pgh.pa.us         111                 :CBC          22 :         PQclear(res);
                                112                 :                :     }
                                113                 :                : 
                                114                 :             22 :     return true;
                                115                 :                : }
                                116                 :                : 
                                117                 :                : /*
                                118                 :                :  * Clean up after a failed LO operation
                                119                 :                :  */
                                120                 :                : static bool
 7596 tgl@sss.pgh.pa.us         121                 :UBC           0 : fail_lo_xact(const char *operation, bool own_transaction)
                                122                 :                : {
                                123                 :                :     PGresult   *res;
                                124                 :                : 
 6438                           125   [ #  #  #  # ]:              0 :     if (own_transaction && pset.autocommit)
                                126                 :                :     {
                                127                 :                :         /* close out our own xact */
 3461 fujii@postgresql.org      128                 :              0 :         res = PSQLexec("ROLLBACK");
 7596 tgl@sss.pgh.pa.us         129                 :              0 :         PQclear(res);
                                130                 :                :     }
                                131                 :                : 
                                132                 :              0 :     return false;               /* always */
                                133                 :                : }
                                134                 :                : 
                                135                 :                : 
                                136                 :                : /*
                                137                 :                :  * do_lo_export()
                                138                 :                :  *
                                139                 :                :  * Write a large object to a file
                                140                 :                :  */
                                141                 :                : bool
 8857 peter_e@gmx.net           142                 :CBC           3 : do_lo_export(const char *loid_arg, const char *filename_arg)
                                143                 :                : {
                                144                 :                :     int         status;
                                145                 :                :     bool        own_transaction;
                                146                 :                : 
 7596 tgl@sss.pgh.pa.us         147         [ -  + ]:              3 :     if (!start_lo_xact("\\lo_export", &own_transaction))
 8928 bruce@momjian.us          148                 :UBC           0 :         return false;
                                149                 :                : 
 1595 michael@paquier.xyz       150                 :CBC           3 :     SetCancelConn(NULL);
 8228 tgl@sss.pgh.pa.us         151                 :              3 :     status = lo_export(pset.db, atooid(loid_arg), filename_arg);
 6514                           152                 :              3 :     ResetCancelConn();
                                153                 :                : 
                                154                 :                :     /* of course this status is documented nowhere :( */
 8928 bruce@momjian.us          155         [ -  + ]:              3 :     if (status != 1)
                                156                 :                :     {
 1840 peter@eisentraut.org      157                 :UBC           0 :         pg_log_info("%s", PQerrorMessage(pset.db));
 7596 tgl@sss.pgh.pa.us         158                 :              0 :         return fail_lo_xact("\\lo_export", own_transaction);
                                159                 :                :     }
                                160                 :                : 
 7596 tgl@sss.pgh.pa.us         161         [ -  + ]:CBC           3 :     if (!finish_lo_xact("\\lo_export", own_transaction))
 7596 tgl@sss.pgh.pa.us         162                 :UBC           0 :         return false;
                                163                 :                : 
 6294 neilc@samurai.com         164                 :CBC           3 :     print_lo_result("lo_export");
                                165                 :                : 
 8928 bruce@momjian.us          166                 :              3 :     return true;
                                167                 :                : }
                                168                 :                : 
                                169                 :                : 
                                170                 :                : /*
                                171                 :                :  * do_lo_import()
                                172                 :                :  *
                                173                 :                :  * Copy large object from file to database
                                174                 :                :  */
                                175                 :                : bool
 8857 peter_e@gmx.net           176                 :              7 : do_lo_import(const char *filename_arg, const char *comment_arg)
                                177                 :                : {
                                178                 :                :     PGresult   *res;
                                179                 :                :     Oid         loid;
                                180                 :                :     char        oidbuf[32];
                                181                 :                :     bool        own_transaction;
                                182                 :                : 
 7596 tgl@sss.pgh.pa.us         183         [ -  + ]:              7 :     if (!start_lo_xact("\\lo_import", &own_transaction))
 8928 bruce@momjian.us          184                 :UBC           0 :         return false;
                                185                 :                : 
 1595 michael@paquier.xyz       186                 :CBC           7 :     SetCancelConn(NULL);
 8833 peter_e@gmx.net           187                 :              7 :     loid = lo_import(pset.db, filename_arg);
 6514 tgl@sss.pgh.pa.us         188                 :              7 :     ResetCancelConn();
                                189                 :                : 
 8928 bruce@momjian.us          190         [ -  + ]:              7 :     if (loid == InvalidOid)
                                191                 :                :     {
 1840 peter@eisentraut.org      192                 :UBC           0 :         pg_log_info("%s", PQerrorMessage(pset.db));
 7596 tgl@sss.pgh.pa.us         193                 :              0 :         return fail_lo_xact("\\lo_import", own_transaction);
                                194                 :                :     }
                                195                 :                : 
                                196                 :                :     /* insert description if given */
 7450 tgl@sss.pgh.pa.us         197         [ -  + ]:CBC           7 :     if (comment_arg)
                                198                 :                :     {
                                199                 :                :         char       *cmdbuf;
                                200                 :                :         char       *bufptr;
 7864 bruce@momjian.us          201                 :UBC           0 :         size_t      slen = strlen(comment_arg);
                                202                 :                : 
 1807 michael@paquier.xyz       203                 :              0 :         cmdbuf = pg_malloc_extended(slen * 2 + 256, MCXT_ALLOC_NO_OOM);
 3827 tgl@sss.pgh.pa.us         204         [ #  # ]:              0 :         if (!cmdbuf)
 7596                           205                 :              0 :             return fail_lo_xact("\\lo_import", own_transaction);
 3827                           206                 :              0 :         sprintf(cmdbuf, "COMMENT ON LARGE OBJECT %u IS '", loid);
                                207                 :              0 :         bufptr = cmdbuf + strlen(cmdbuf);
 6531                           208                 :              0 :         bufptr += PQescapeStringConn(pset.db, bufptr, comment_arg, slen, NULL);
 7450                           209                 :              0 :         strcpy(bufptr, "'");
                                210                 :                : 
 3461 fujii@postgresql.org      211         [ #  # ]:              0 :         if (!(res = PSQLexec(cmdbuf)))
                                212                 :                :         {
 8283 tgl@sss.pgh.pa.us         213                 :              0 :             free(cmdbuf);
 7596                           214                 :              0 :             return fail_lo_xact("\\lo_import", own_transaction);
                                215                 :                :         }
                                216                 :                : 
 8283                           217                 :              0 :         PQclear(res);
                                218                 :              0 :         free(cmdbuf);
                                219                 :                :     }
                                220                 :                : 
 7596 tgl@sss.pgh.pa.us         221         [ -  + ]:CBC           7 :     if (!finish_lo_xact("\\lo_import", own_transaction))
 7596 tgl@sss.pgh.pa.us         222                 :UBC           0 :         return false;
                                223                 :                : 
 6294 neilc@samurai.com         224                 :CBC           7 :     print_lo_result("lo_import %u", loid);
                                225                 :                : 
 8283 tgl@sss.pgh.pa.us         226                 :              7 :     sprintf(oidbuf, "%u", loid);
                                227                 :              7 :     SetVariable(pset.vars, "LASTOID", oidbuf);
                                228                 :                : 
 8928 bruce@momjian.us          229                 :              7 :     return true;
                                230                 :                : }
                                231                 :                : 
                                232                 :                : 
                                233                 :                : /*
                                234                 :                :  * do_lo_unlink()
                                235                 :                :  *
                                236                 :                :  * removes a large object out of the database
                                237                 :                :  */
                                238                 :                : bool
 8857 peter_e@gmx.net           239                 :             12 : do_lo_unlink(const char *loid_arg)
                                240                 :                : {
                                241                 :                :     int         status;
 8228 tgl@sss.pgh.pa.us         242                 :             12 :     Oid         loid = atooid(loid_arg);
                                243                 :                :     bool        own_transaction;
                                244                 :                : 
 7596                           245         [ -  + ]:             12 :     if (!start_lo_xact("\\lo_unlink", &own_transaction))
 8928 bruce@momjian.us          246                 :UBC           0 :         return false;
                                247                 :                : 
 1595 michael@paquier.xyz       248                 :CBC          12 :     SetCancelConn(NULL);
 8857 peter_e@gmx.net           249                 :             12 :     status = lo_unlink(pset.db, loid);
 6514 tgl@sss.pgh.pa.us         250                 :             12 :     ResetCancelConn();
                                251                 :                : 
 8928 bruce@momjian.us          252         [ -  + ]:             12 :     if (status == -1)
                                253                 :                :     {
 1840 peter@eisentraut.org      254                 :UBC           0 :         pg_log_info("%s", PQerrorMessage(pset.db));
 7596 tgl@sss.pgh.pa.us         255                 :              0 :         return fail_lo_xact("\\lo_unlink", own_transaction);
                                256                 :                :     }
                                257                 :                : 
 7596 tgl@sss.pgh.pa.us         258         [ -  + ]:CBC          12 :     if (!finish_lo_xact("\\lo_unlink", own_transaction))
 7596 tgl@sss.pgh.pa.us         259                 :UBC           0 :         return false;
                                260                 :                : 
 6294 neilc@samurai.com         261                 :CBC          12 :     print_lo_result("lo_unlink %u", loid);
                                262                 :                : 
 8928 bruce@momjian.us          263                 :             12 :     return true;
                                264                 :                : }
        

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