LCOV - differential code coverage report
Current view: top level - src/interfaces/ecpg/ecpglib - descriptor.c (source / functions) Coverage Total Hit UNC UBC GNC CBC DUB DCB
Current: 380a8b2ea024c33a35e7abc8628e7c4f52f9f9f9 vs db5ed03217b9c238703df8b4b286115d6e940488 Lines: 58.3 % 530 309 221 6 303 5
Current Date: 2026-05-29 21:51:00 -0400 Functions: 90.0 % 20 18 2 4 14 3
Baseline: lcov-20260530-034037-baseline Branches: 48.9 % 235 115 1 119 1 114 1 1
Baseline Date: 2026-05-29 14:39:03 -0700 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(7,30] days: 100.0 % 9 9 3 6
(30,360] days: 100.0 % 3 3 3
(360..) days: 57.3 % 518 297 221 297
Function coverage date bins:
(7,30] days: 100.0 % 3 3 3
(360..) days: 88.2 % 17 15 2 1 14
Branch coverage date bins:
(7,30] days: 100.0 % 2 2 2
(30,360] days: 50.0 % 2 1 1 1
(360..) days: 48.5 % 231 112 119 112

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*
                                  2                 :                :  * dynamic SQL support routines
                                  3                 :                :  *
                                  4                 :                :  * src/interfaces/ecpg/ecpglib/descriptor.c
                                  5                 :                :  */
                                  6                 :                : 
                                  7                 :                : #define POSTGRES_ECPG_INTERNAL
                                  8                 :                : #include "postgres_fe.h"
                                  9                 :                : 
                                 10                 :                : #include "catalog/pg_type_d.h"
                                 11                 :                : #include "ecpg-pthread-win32.h"
                                 12                 :                : #include "ecpgerrno.h"
                                 13                 :                : #include "ecpglib.h"
                                 14                 :                : #include "ecpglib_extern.h"
                                 15                 :                : #include "ecpgtype.h"
                                 16                 :                : #include "sql3types.h"
                                 17                 :                : #include "sqlca.h"
                                 18                 :                : #include "sqlda.h"
                                 19                 :                : 
                                 20                 :                : static void descriptor_free(struct descriptor *desc);
                                 21                 :                : 
                                 22                 :                : /* We manage descriptors separately for each thread. */
                                 23                 :                : static pthread_key_t descriptor_key;
                                 24                 :                : static pthread_once_t descriptor_once = PTHREAD_ONCE_INIT;
                                 25                 :                : 
                                 26                 :                : static void descriptor_deallocate_all(struct descriptor *list);
                                 27                 :                : 
                                 28                 :                : static void
 6815 meskes@postgresql.or       29                 :UBC           0 : descriptor_destructor(void *arg)
                                 30                 :                : {
                                 31                 :              0 :     descriptor_deallocate_all(arg);
                                 32                 :              0 : }
                                 33                 :                : 
                                 34                 :                : static void
 6815 meskes@postgresql.or       35                 :CBC          10 : descriptor_key_init(void)
                                 36                 :                : {
                                 37                 :             10 :     pthread_key_create(&descriptor_key, descriptor_destructor);
                                 38                 :             10 : }
                                 39                 :                : 
                                 40                 :                : static struct descriptor *
                                 41                 :        1600154 : get_descriptors(void)
                                 42                 :                : {
                                 43                 :        1600154 :     pthread_once(&descriptor_once, descriptor_key_init);
                                 44                 :        1600154 :     return (struct descriptor *) pthread_getspecific(descriptor_key);
                                 45                 :                : }
                                 46                 :                : 
                                 47                 :                : static void
 3265 tgl@sss.pgh.pa.us          48                 :        1600029 : set_descriptors(struct descriptor *value)
                                 49                 :                : {
 6815 meskes@postgresql.or       50                 :        1600029 :     pthread_setspecific(descriptor_key, value);
                                 51                 :        1600029 : }
                                 52                 :                : 
                                 53                 :                : /* old internal convenience function that might go away later */
                                 54                 :                : static PGresult *
 6814                            55                 :             74 : ecpg_result_by_descriptor(int line, const char *name)
                                 56                 :                : {
                                 57                 :             74 :     struct descriptor *desc = ecpg_find_desc(line, name);
                                 58                 :                : 
 6815                            59         [ -  + ]:             74 :     if (desc == NULL)
 6815 meskes@postgresql.or       60                 :UBC           0 :         return NULL;
 6815 meskes@postgresql.or       61                 :CBC          74 :     return desc->result;
                                 62                 :                : }
                                 63                 :                : 
                                 64                 :                : static unsigned int
 6814                            65                 :              8 : ecpg_dynamic_type_DDT(Oid type)
                                 66                 :                : {
 8476                            67   [ +  -  -  -  :              8 :     switch (type)
                                              -  - ]
                                 68                 :                :     {
                                 69                 :              8 :         case DATEOID:
                                 70                 :              8 :             return SQL3_DDT_DATE;
 8476 meskes@postgresql.or       71                 :UBC           0 :         case TIMEOID:
                                 72                 :              0 :             return SQL3_DDT_TIME;
                                 73                 :              0 :         case TIMESTAMPOID:
                                 74                 :              0 :             return SQL3_DDT_TIMESTAMP;
                                 75                 :              0 :         case TIMESTAMPTZOID:
                                 76                 :              0 :             return SQL3_DDT_TIMESTAMP_WITH_TIME_ZONE;
                                 77                 :              0 :         case TIMETZOID:
                                 78                 :              0 :             return SQL3_DDT_TIME_WITH_TIME_ZONE;
                                 79                 :              0 :         default:
                                 80                 :              0 :             return SQL3_DDT_ILLEGAL;
                                 81                 :                :     }
                                 82                 :                : }
                                 83                 :                : 
                                 84                 :                : bool
 7486 meskes@postgresql.or       85                 :CBC          12 : ECPGget_desc_header(int lineno, const char *desc_name, int *count)
                                 86                 :                : {
                                 87                 :                :     PGresult   *ECPGresult;
 8385 bruce@momjian.us           88                 :             12 :     struct sqlca_t *sqlca = ECPGget_sqlca();
                                 89                 :                : 
 4002 meskes@postgresql.or       90         [ -  + ]:             12 :     if (sqlca == NULL)
                                 91                 :                :     {
 4002 meskes@postgresql.or       92                 :UBC           0 :         ecpg_raise(lineno, ECPG_OUT_OF_MEMORY,
                                 93                 :                :                    ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
                                 94                 :              0 :         return false;
                                 95                 :                :     }
                                 96                 :                : 
 6814 meskes@postgresql.or       97                 :CBC          12 :     ecpg_init_sqlca(sqlca);
                                 98                 :             12 :     ECPGresult = ecpg_result_by_descriptor(lineno, desc_name);
 8476                            99         [ -  + ]:             12 :     if (!ECPGresult)
 8476 meskes@postgresql.or      100                 :UBC           0 :         return false;
                                101                 :                : 
 8476 meskes@postgresql.or      102                 :CBC          12 :     *count = PQnfields(ECPGresult);
 8385 bruce@momjian.us          103                 :             12 :     sqlca->sqlerrd[2] = 1;
 6588 peter_e@gmx.net           104                 :             12 :     ecpg_log("ECPGget_desc_header: found %d attributes\n", *count);
 8476 meskes@postgresql.or      105                 :             12 :     return true;
                                106                 :                : }
                                107                 :                : 
                                108                 :                : static bool
                                109                 :            103 : get_int_item(int lineno, void *var, enum ECPGttype vartype, int value)
                                110                 :                : {
                                111                 :            103 :     switch (vartype)
                                      [ -  +  -  -  
                                     -  -  -  -  -  
                                              -  - ]
                                112                 :                :     {
 8476 meskes@postgresql.or      113                 :UBC           0 :         case ECPGt_short:
                                114                 :              0 :             *(short *) var = (short) value;
                                115                 :              0 :             break;
 8476 meskes@postgresql.or      116                 :CBC         103 :         case ECPGt_int:
  179 peter@eisentraut.org      117                 :GNC         103 :             *(int *) var = value;
 8476 meskes@postgresql.or      118                 :CBC         103 :             break;
 8476 meskes@postgresql.or      119                 :UBC           0 :         case ECPGt_long:
                                120                 :              0 :             *(long *) var = (long) value;
                                121                 :              0 :             break;
                                122                 :              0 :         case ECPGt_unsigned_short:
                                123                 :              0 :             *(unsigned short *) var = (unsigned short) value;
                                124                 :              0 :             break;
                                125                 :              0 :         case ECPGt_unsigned_int:
                                126                 :              0 :             *(unsigned int *) var = (unsigned int) value;
                                127                 :              0 :             break;
                                128                 :              0 :         case ECPGt_unsigned_long:
                                129                 :              0 :             *(unsigned long *) var = (unsigned long) value;
                                130                 :              0 :             break;
                                131                 :              0 :         case ECPGt_long_long:
                                132                 :              0 :             *(long long int *) var = (long long int) value;
                                133                 :              0 :             break;
                                134                 :              0 :         case ECPGt_unsigned_long_long:
                                135                 :              0 :             *(unsigned long long int *) var = (unsigned long long int) value;
                                136                 :              0 :             break;
                                137                 :              0 :         case ECPGt_float:
                                138                 :              0 :             *(float *) var = (float) value;
                                139                 :              0 :             break;
                                140                 :              0 :         case ECPGt_double:
                                141                 :              0 :             *(double *) var = (double) value;
                                142                 :              0 :             break;
                                143                 :              0 :         default:
 6814                           144                 :              0 :             ecpg_raise(lineno, ECPG_VAR_NOT_NUMERIC, ECPG_SQLSTATE_RESTRICTED_DATA_TYPE_ATTRIBUTE_VIOLATION, NULL);
 3208 peter_e@gmx.net           145                 :              0 :             return false;
                                146                 :                :     }
                                147                 :                : 
 3208 peter_e@gmx.net           148                 :CBC         103 :     return true;
                                149                 :                : }
                                150                 :                : 
                                151                 :                : static bool
 8004 meskes@postgresql.or      152                 :              4 : set_int_item(int lineno, int *target, const void *var, enum ECPGttype vartype)
                                153                 :                : {
                                154                 :              4 :     switch (vartype)
                                      [ -  +  -  -  
                                     -  -  -  -  -  
                                              -  - ]
                                155                 :                :     {
 8004 meskes@postgresql.or      156                 :UBC           0 :         case ECPGt_short:
 5375 peter_e@gmx.net           157                 :              0 :             *target = *(const short *) var;
 8004 meskes@postgresql.or      158                 :              0 :             break;
 8004 meskes@postgresql.or      159                 :CBC           4 :         case ECPGt_int:
 5375 peter_e@gmx.net           160                 :              4 :             *target = *(const int *) var;
 8004 meskes@postgresql.or      161                 :              4 :             break;
 8004 meskes@postgresql.or      162                 :UBC           0 :         case ECPGt_long:
 5375 peter_e@gmx.net           163                 :              0 :             *target = *(const long *) var;
 8004 meskes@postgresql.or      164                 :              0 :             break;
                                165                 :              0 :         case ECPGt_unsigned_short:
 5375 peter_e@gmx.net           166                 :              0 :             *target = *(const unsigned short *) var;
 8004 meskes@postgresql.or      167                 :              0 :             break;
                                168                 :              0 :         case ECPGt_unsigned_int:
 5375 peter_e@gmx.net           169                 :              0 :             *target = *(const unsigned int *) var;
 8004 meskes@postgresql.or      170                 :              0 :             break;
                                171                 :              0 :         case ECPGt_unsigned_long:
 5375 peter_e@gmx.net           172                 :              0 :             *target = *(const unsigned long *) var;
 8004 meskes@postgresql.or      173                 :              0 :             break;
                                174                 :              0 :         case ECPGt_long_long:
 5375 peter_e@gmx.net           175                 :              0 :             *target = *(const long long int *) var;
 8004 meskes@postgresql.or      176                 :              0 :             break;
                                177                 :              0 :         case ECPGt_unsigned_long_long:
 5375 peter_e@gmx.net           178                 :              0 :             *target = *(const unsigned long long int *) var;
 8004 meskes@postgresql.or      179                 :              0 :             break;
                                180                 :              0 :         case ECPGt_float:
 5375 peter_e@gmx.net           181                 :              0 :             *target = *(const float *) var;
 8004 meskes@postgresql.or      182                 :              0 :             break;
                                183                 :              0 :         case ECPGt_double:
 5375 peter_e@gmx.net           184                 :              0 :             *target = *(const double *) var;
 8004 meskes@postgresql.or      185                 :              0 :             break;
                                186                 :              0 :         default:
 6814                           187                 :              0 :             ecpg_raise(lineno, ECPG_VAR_NOT_NUMERIC, ECPG_SQLSTATE_RESTRICTED_DATA_TYPE_ATTRIBUTE_VIOLATION, NULL);
 3208 peter_e@gmx.net           188                 :              0 :             return false;
                                189                 :                :     }
                                190                 :                : 
 8004 meskes@postgresql.or      191                 :CBC           4 :     return true;
                                192                 :                : }
                                193                 :                : 
                                194                 :                : static bool
 8476                           195                 :             30 : get_char_item(int lineno, void *var, enum ECPGttype vartype, char *value, int varcharsize)
                                196                 :                : {
                                197      [ +  -  - ]:             30 :     switch (vartype)
                                198                 :                :     {
                                199                 :             30 :         case ECPGt_char:
                                200                 :                :         case ECPGt_unsigned_char:
                                201                 :                :         case ECPGt_string:
  464 peter@eisentraut.org      202                 :             30 :             strncpy(var, value, varcharsize);
 8476 meskes@postgresql.or      203                 :             30 :             break;
 8476 meskes@postgresql.or      204                 :UBC           0 :         case ECPGt_varchar:
                                205                 :                :             {
                                206                 :              0 :                 struct ECPGgeneric_varchar *variable =
                                207                 :                :                     (struct ECPGgeneric_varchar *) var;
                                208                 :                : 
                                209         [ #  # ]:              0 :                 if (varcharsize == 0)
 2905 tgl@sss.pgh.pa.us         210                 :              0 :                     memcpy(variable->arr, value, strlen(value));
                                211                 :                :                 else
 8476 meskes@postgresql.or      212                 :              0 :                     strncpy(variable->arr, value, varcharsize);
                                213                 :                : 
                                214                 :              0 :                 variable->len = strlen(value);
                                215   [ #  #  #  # ]:              0 :                 if (varcharsize > 0 && variable->len > varcharsize)
                                216                 :              0 :                     variable->len = varcharsize;
                                217                 :                :             }
                                218                 :              0 :             break;
                                219                 :              0 :         default:
 6814                           220                 :              0 :             ecpg_raise(lineno, ECPG_VAR_NOT_CHAR, ECPG_SQLSTATE_RESTRICTED_DATA_TYPE_ATTRIBUTE_VIOLATION, NULL);
 3208 peter_e@gmx.net           221                 :              0 :             return false;
                                222                 :                :     }
                                223                 :                : 
 3208 peter_e@gmx.net           224                 :CBC          30 :     return true;
                                225                 :                : }
                                226                 :                : 
                                227                 :                : #define RETURN_IF_NO_DATA   if (ntuples < 1) \
                                228                 :                :                 { \
                                229                 :                :                     va_end(args); \
                                230                 :                :                     ecpg_raise(lineno, ECPG_NOT_FOUND, ECPG_SQLSTATE_NO_DATA, NULL); \
                                231                 :                :                     return false; \
                                232                 :                :                 }
                                233                 :                : 
                                234                 :                : bool
   17 tgl@sss.pgh.pa.us         235                 :GNC          62 : ECPGget_desc(int lineno, const char *desc_name, int index, ...)
                                236                 :                : {
                                237                 :                :     va_list     args;
                                238                 :                :     PGresult   *ECPGresult;
                                239                 :                :     enum ECPGdtype type;
                                240                 :                :     int         ntuples,
                                241                 :                :                 act_tuple;
                                242                 :                :     struct variable data_var;
 8385 bruce@momjian.us          243                 :CBC          62 :     struct sqlca_t *sqlca = ECPGget_sqlca();
  311 michael@paquier.xyz       244                 :GNC          62 :     bool        alloc_failed = (sqlca == NULL);
                                245                 :                : 
                                246         [ -  + ]:             62 :     if (alloc_failed)
                                247                 :                :     {
 4002 meskes@postgresql.or      248                 :UBC           0 :         ecpg_raise(lineno, ECPG_OUT_OF_MEMORY,
                                249                 :                :                    ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
                                250                 :              0 :         return false;
                                251                 :                :     }
                                252                 :                : 
 8476 meskes@postgresql.or      253                 :CBC          62 :     va_start(args, index);
 6814                           254                 :             62 :     ecpg_init_sqlca(sqlca);
                                255                 :             62 :     ECPGresult = ecpg_result_by_descriptor(lineno, desc_name);
 8476                           256         [ -  + ]:             62 :     if (!ECPGresult)
                                257                 :                :     {
 5190 peter_e@gmx.net           258                 :UBC           0 :         va_end(args);
 3208                           259                 :              0 :         return false;
                                260                 :                :     }
                                261                 :                : 
 8476 meskes@postgresql.or      262                 :CBC          62 :     ntuples = PQntuples(ECPGresult);
                                263                 :                : 
                                264   [ +  -  -  + ]:             62 :     if (index < 1 || index > PQnfields(ECPGresult))
                                265                 :                :     {
 6814 meskes@postgresql.or      266                 :UBC           0 :         ecpg_raise(lineno, ECPG_INVALID_DESCRIPTOR_INDEX, ECPG_SQLSTATE_INVALID_DESCRIPTOR_INDEX, NULL);
 5190 peter_e@gmx.net           267                 :              0 :         va_end(args);
 3208                           268                 :              0 :         return false;
                                269                 :                :     }
                                270                 :                : 
 6814 meskes@postgresql.or      271                 :CBC          62 :     ecpg_log("ECPGget_desc: reading items for tuple %d\n", index);
 8476                           272                 :             62 :     --index;
                                273                 :                : 
                                274                 :             62 :     type = va_arg(args, enum ECPGdtype);
                                275                 :                : 
                                276                 :             62 :     memset(&data_var, 0, sizeof data_var);
                                277                 :             62 :     data_var.type = ECPGt_EORT;
                                278                 :             62 :     data_var.ind_type = ECPGt_NO_INDICATOR;
                                279                 :                : 
                                280         [ +  + ]:            236 :     while (type != ECPGd_EODT)
                                281                 :                :     {
                                282                 :                :         char        type_str[20];
                                283                 :                :         long        varcharsize;
                                284                 :                :         long        offset;
                                285                 :                :         long        arrsize;
                                286                 :                :         enum ECPGttype vartype;
                                287                 :                :         void       *var;
                                288                 :                : 
                                289                 :            174 :         vartype = va_arg(args, enum ECPGttype);
                                290                 :            174 :         var = va_arg(args, void *);
                                291                 :            174 :         varcharsize = va_arg(args, long);
                                292                 :            174 :         arrsize = va_arg(args, long);
                                293                 :            174 :         offset = va_arg(args, long);
                                294                 :                : 
                                295                 :            174 :         switch (type)
                                      [ +  +  +  -  
                                     -  +  +  +  +  
                                        +  +  -  +  
                                                 - ]
                                296                 :                :         {
                                297                 :             26 :             case (ECPGd_indicator):
 5979                           298         [ -  + ]:             26 :                 RETURN_IF_NO_DATA;
 8476                           299                 :             26 :                 data_var.ind_type = vartype;
                                300                 :             26 :                 data_var.ind_pointer = var;
                                301                 :             26 :                 data_var.ind_varcharsize = varcharsize;
                                302                 :             26 :                 data_var.ind_arrsize = arrsize;
                                303                 :             26 :                 data_var.ind_offset = offset;
 7239                           304   [ +  +  -  + ]:             26 :                 if (data_var.ind_arrsize == 0 || data_var.ind_varcharsize == 0)
 8476                           305                 :             10 :                     data_var.ind_value = *((void **) (data_var.ind_pointer));
                                306                 :                :                 else
                                307                 :             16 :                     data_var.ind_value = data_var.ind_pointer;
                                308                 :             26 :                 break;
                                309                 :                : 
                                310                 :             29 :             case ECPGd_data:
 5979                           311         [ -  + ]:             29 :                 RETURN_IF_NO_DATA;
 8476                           312                 :             29 :                 data_var.type = vartype;
                                313                 :             29 :                 data_var.pointer = var;
                                314                 :             29 :                 data_var.varcharsize = varcharsize;
                                315                 :             29 :                 data_var.arrsize = arrsize;
                                316                 :             29 :                 data_var.offset = offset;
                                317   [ +  +  -  + ]:             29 :                 if (data_var.arrsize == 0 || data_var.varcharsize == 0)
                                318                 :             10 :                     data_var.value = *((void **) (data_var.pointer));
                                319                 :                :                 else
                                320                 :             19 :                     data_var.value = data_var.pointer;
                                321                 :             29 :                 break;
                                322                 :                : 
                                323                 :             30 :             case ECPGd_name:
                                324         [ -  + ]:             30 :                 if (!get_char_item(lineno, var, vartype, PQfname(ECPGresult, index), varcharsize))
                                325                 :                :                 {
 5190 peter_e@gmx.net           326                 :UBC           0 :                     va_end(args);
 3208                           327                 :              0 :                     return false;
                                328                 :                :                 }
                                329                 :                : 
 6814 meskes@postgresql.or      330                 :CBC          30 :                 ecpg_log("ECPGget_desc: NAME = %s\n", PQfname(ECPGresult, index));
 8476                           331                 :             30 :                 break;
                                332                 :                : 
 8476 meskes@postgresql.or      333                 :UBC           0 :             case ECPGd_nullable:
                                334         [ #  # ]:              0 :                 if (!get_int_item(lineno, var, vartype, 1))
                                335                 :                :                 {
 5190 peter_e@gmx.net           336                 :              0 :                     va_end(args);
 3208                           337                 :              0 :                     return false;
                                338                 :                :                 }
                                339                 :                : 
 8476 meskes@postgresql.or      340                 :              0 :                 break;
                                341                 :                : 
                                342                 :              0 :             case ECPGd_key_member:
                                343         [ #  # ]:              0 :                 if (!get_int_item(lineno, var, vartype, 0))
                                344                 :                :                 {
 5190 peter_e@gmx.net           345                 :              0 :                     va_end(args);
 3208                           346                 :              0 :                     return false;
                                347                 :                :                 }
                                348                 :                : 
 8476 meskes@postgresql.or      349                 :              0 :                 break;
                                350                 :                : 
 8476 meskes@postgresql.or      351                 :CBC          14 :             case ECPGd_scale:
                                352         [ -  + ]:             14 :                 if (!get_int_item(lineno, var, vartype, (PQfmod(ECPGresult, index) - VARHDRSZ) & 0xffff))
                                353                 :                :                 {
 5190 peter_e@gmx.net           354                 :UBC           0 :                     va_end(args);
 3208                           355                 :              0 :                     return false;
                                356                 :                :                 }
                                357                 :                : 
 6814 meskes@postgresql.or      358                 :CBC          14 :                 ecpg_log("ECPGget_desc: SCALE = %d\n", (PQfmod(ECPGresult, index) - VARHDRSZ) & 0xffff);
 8476                           359                 :             14 :                 break;
                                360                 :                : 
                                361                 :             14 :             case ECPGd_precision:
                                362         [ -  + ]:             14 :                 if (!get_int_item(lineno, var, vartype, PQfmod(ECPGresult, index) >> 16))
                                363                 :                :                 {
 5190 peter_e@gmx.net           364                 :UBC           0 :                     va_end(args);
 3208                           365                 :              0 :                     return false;
                                366                 :                :                 }
                                367                 :                : 
 6814 meskes@postgresql.or      368                 :CBC          14 :                 ecpg_log("ECPGget_desc: PRECISION = %d\n", PQfmod(ECPGresult, index) >> 16);
 8476                           369                 :             14 :                 break;
                                370                 :                : 
                                371                 :             14 :             case ECPGd_octet:
                                372         [ -  + ]:             14 :                 if (!get_int_item(lineno, var, vartype, PQfsize(ECPGresult, index)))
                                373                 :                :                 {
 5190 peter_e@gmx.net           374                 :UBC           0 :                     va_end(args);
 3208                           375                 :              0 :                     return false;
                                376                 :                :                 }
                                377                 :                : 
 6814 meskes@postgresql.or      378                 :CBC          14 :                 ecpg_log("ECPGget_desc: OCTET_LENGTH = %d\n", PQfsize(ECPGresult, index));
 8476                           379                 :             14 :                 break;
                                380                 :                : 
                                381                 :             15 :             case ECPGd_length:
                                382         [ -  + ]:             15 :                 if (!get_int_item(lineno, var, vartype, PQfmod(ECPGresult, index) - VARHDRSZ))
                                383                 :                :                 {
 5190 peter_e@gmx.net           384                 :UBC           0 :                     va_end(args);
 3208                           385                 :              0 :                     return false;
                                386                 :                :                 }
                                387                 :                : 
 6814 meskes@postgresql.or      388                 :CBC          15 :                 ecpg_log("ECPGget_desc: LENGTH = %d\n", PQfmod(ECPGresult, index) - VARHDRSZ);
 8476                           389                 :             15 :                 break;
                                390                 :                : 
                                391                 :             14 :             case ECPGd_type:
 6814                           392         [ -  + ]:             14 :                 if (!get_int_item(lineno, var, vartype, ecpg_dynamic_type(PQftype(ECPGresult, index))))
                                393                 :                :                 {
 5190 peter_e@gmx.net           394                 :UBC           0 :                     va_end(args);
 3208                           395                 :              0 :                     return false;
                                396                 :                :                 }
                                397                 :                : 
 6814 meskes@postgresql.or      398                 :CBC          14 :                 ecpg_log("ECPGget_desc: TYPE = %d\n", ecpg_dynamic_type(PQftype(ECPGresult, index)));
 8476                           399                 :             14 :                 break;
                                400                 :                : 
                                401                 :              4 :             case ECPGd_di_code:
 6814                           402         [ -  + ]:              4 :                 if (!get_int_item(lineno, var, vartype, ecpg_dynamic_type_DDT(PQftype(ECPGresult, index))))
                                403                 :                :                 {
 5190 peter_e@gmx.net           404                 :UBC           0 :                     va_end(args);
 3208                           405                 :              0 :                     return false;
                                406                 :                :                 }
                                407                 :                : 
 6814 meskes@postgresql.or      408                 :CBC           4 :                 ecpg_log("ECPGget_desc: TYPE = %d\n", ecpg_dynamic_type_DDT(PQftype(ECPGresult, index)));
 8476                           409                 :              4 :                 break;
                                410                 :                : 
 8476 meskes@postgresql.or      411                 :UBC           0 :             case ECPGd_cardinality:
                                412         [ #  # ]:              0 :                 if (!get_int_item(lineno, var, vartype, PQntuples(ECPGresult)))
                                413                 :                :                 {
 5190 peter_e@gmx.net           414                 :              0 :                     va_end(args);
 3208                           415                 :              0 :                     return false;
                                416                 :                :                 }
                                417                 :                : 
 6814 meskes@postgresql.or      418                 :              0 :                 ecpg_log("ECPGget_desc: CARDINALITY = %d\n", PQntuples(ECPGresult));
 8476                           419                 :              0 :                 break;
                                420                 :                : 
 8476 meskes@postgresql.or      421                 :CBC          14 :             case ECPGd_ret_length:
                                422                 :                :             case ECPGd_ret_octet:
                                423                 :                : 
 5979                           424         [ -  + ]:             14 :                 RETURN_IF_NO_DATA;
                                425                 :                : 
                                426                 :                :                 /*
                                427                 :                :                  * this is like ECPGstore_result
                                428                 :                :                  */
 8476                           429   [ +  -  -  + ]:             14 :                 if (arrsize > 0 && ntuples > arrsize)
                                430                 :                :                 {
 5376 peter_e@gmx.net           431                 :UBC           0 :                     ecpg_log("ECPGget_desc on line %d: incorrect number of matches; %d don't fit into array of %ld\n",
                                432                 :                :                              lineno, ntuples, arrsize);
 6814 meskes@postgresql.or      433                 :              0 :                     ecpg_raise(lineno, ECPG_TOO_MANY_MATCHES, ECPG_SQLSTATE_CARDINALITY_VIOLATION, NULL);
 5190 peter_e@gmx.net           434                 :              0 :                     va_end(args);
 8476 meskes@postgresql.or      435                 :              0 :                     return false;
                                436                 :                :                 }
                                437                 :                :                 /* allocate storage if needed */
 7279 meskes@postgresql.or      438   [ -  +  -  - ]:CBC          14 :                 if (arrsize == 0 && *(void **) var == NULL)
                                439                 :                :                 {
  548 peter@eisentraut.org      440                 :UBC           0 :                     void       *mem = ecpg_auto_alloc(offset * ntuples, lineno);
                                441                 :                : 
 7283 meskes@postgresql.or      442         [ #  # ]:              0 :                     if (!mem)
                                443                 :                :                     {
 5190 peter_e@gmx.net           444                 :              0 :                         va_end(args);
 7283 meskes@postgresql.or      445                 :              0 :                         return false;
                                446                 :                :                     }
 8476                           447                 :              0 :                     *(void **) var = mem;
                                448                 :              0 :                     var = mem;
                                449                 :                :                 }
                                450                 :                : 
 8476 meskes@postgresql.or      451         [ +  + ]:CBC          28 :                 for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
                                452                 :                :                 {
                                453         [ -  + ]:             14 :                     if (!get_int_item(lineno, var, vartype, PQgetlength(ECPGresult, act_tuple, index)))
                                454                 :                :                     {
 5190 peter_e@gmx.net           455                 :UBC           0 :                         va_end(args);
 3208                           456                 :              0 :                         return false;
                                457                 :                :                     }
 8476 meskes@postgresql.or      458                 :CBC          14 :                     var = (char *) var + offset;
 6814                           459                 :             14 :                     ecpg_log("ECPGget_desc: RETURNED[%d] = %d\n", act_tuple, PQgetlength(ECPGresult, act_tuple, index));
                                460                 :                :                 }
 8476                           461                 :             14 :                 break;
                                462                 :                : 
 8476 meskes@postgresql.or      463                 :UBC           0 :             default:
                                464                 :              0 :                 snprintf(type_str, sizeof(type_str), "%d", type);
 6814                           465                 :              0 :                 ecpg_raise(lineno, ECPG_UNKNOWN_DESCRIPTOR_ITEM, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, type_str);
 5190 peter_e@gmx.net           466                 :              0 :                 va_end(args);
 3208                           467                 :              0 :                 return false;
                                468                 :                :         }
                                469                 :                : 
 8476 meskes@postgresql.or      470                 :CBC         174 :         type = va_arg(args, enum ECPGdtype);
                                471                 :                :     }
                                472                 :                : 
                                473         [ +  + ]:             62 :     if (data_var.type != ECPGt_EORT)
                                474                 :                :     {
                                475                 :                :         struct statement stmt;
                                476                 :                : 
 2686 tgl@sss.pgh.pa.us         477                 :             29 :         memset(&stmt, 0, sizeof stmt);
                                478                 :             29 :         stmt.lineno = lineno;
                                479                 :                : 
                                480                 :                :         /* desperate try to guess something sensible */
   29 andrew@dunslane.net       481                 :             29 :         stmt.connection = ecpg_get_connection(NULL);
                                482         [ +  + ]:             29 :         if (stmt.connection == NULL)
                                483                 :                :         {
                                484                 :              1 :             ecpg_raise(lineno, ECPG_NO_CONN, ECPG_SQLSTATE_CONNECTION_DOES_NOT_EXIST,
                                485                 :              1 :                        ecpg_gettext("NULL"));
                                486                 :              1 :             va_end(args);
                                487                 :              1 :             return false;
                                488                 :                :         }
                                489                 :                : 
                                490                 :                :         /* Make sure we do NOT honor the locale for numeric input */
                                491                 :                :         /* since the database gives the standard decimal point */
                                492                 :                :         /* (see comments in execute.c) */
                                493                 :                : #ifdef HAVE_USELOCALE
                                494                 :                : 
                                495                 :                :         /*
                                496                 :                :          * To get here, the above PQnfields() test must have found nonzero
                                497                 :                :          * fields.  One needs a connection to create such a descriptor.  (EXEC
                                498                 :                :          * SQL SET DESCRIPTOR can populate the descriptor's "items", but it
                                499                 :                :          * can't change the descriptor's PQnfields().)  Any successful
                                500                 :                :          * connection initializes ecpg_clocale.
                                501                 :                :          */
  428 peter@eisentraut.org      502         [ -  + ]:             28 :         Assert(ecpg_clocale);
                                503                 :             28 :         stmt.oldlocale = uselocale(ecpg_clocale);
                                504                 :                : #else
                                505                 :                : #ifdef WIN32
                                506                 :                :         stmt.oldthreadlocale = _configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
                                507                 :                : #endif
                                508                 :                :         stmt.oldlocale = ecpg_strdup(setlocale(LC_NUMERIC, NULL),
                                509                 :                :                                      lineno, &alloc_failed);
                                510                 :                :         if (alloc_failed)
                                511                 :                :         {
                                512                 :                :             va_end(args);
                                513                 :                :             return false;
                                514                 :                :         }
                                515                 :                : 
                                516                 :                :         setlocale(LC_NUMERIC, "C");
                                517                 :                : #endif
                                518                 :                : 
 6814 meskes@postgresql.or      519                 :             28 :         ecpg_store_result(ECPGresult, index, &stmt, &data_var);
                                520                 :                : 
                                521                 :                : #ifdef HAVE_USELOCALE
  428 peter@eisentraut.org      522         [ +  - ]:             28 :         if (stmt.oldlocale != (locale_t) 0)
                                523                 :             28 :             uselocale(stmt.oldlocale);
                                524                 :                : #else
                                525                 :                :         if (stmt.oldlocale)
                                526                 :                :         {
                                527                 :                :             setlocale(LC_NUMERIC, stmt.oldlocale);
                                528                 :                :             ecpg_free(stmt.oldlocale);
                                529                 :                :         }
                                530                 :                : #ifdef WIN32
                                531                 :                :         if (stmt.oldthreadlocale != -1)
                                532                 :                :             _configthreadlocale(stmt.oldthreadlocale);
                                533                 :                : #endif
                                534                 :                : #endif
                                535                 :                :     }
 7269 meskes@postgresql.or      536   [ +  +  +  - ]:             33 :     else if (data_var.ind_type != ECPGt_NO_INDICATOR && data_var.ind_pointer != NULL)
                                537                 :                : 
                                538                 :                :         /*
                                539                 :                :          * ind_type != NO_INDICATOR should always have ind_pointer != NULL but
                                540                 :                :          * since this might be changed manually in the .c file let's play it
                                541                 :                :          * safe
                                542                 :                :          */
                                543                 :                :     {
                                544                 :                :         /*
                                545                 :                :          * this is like ECPGstore_result but since we don't have a data
                                546                 :                :          * variable at hand, we can't call it
                                547                 :                :          */
 8476                           548   [ +  -  -  + ]:             14 :         if (data_var.ind_arrsize > 0 && ntuples > data_var.ind_arrsize)
                                549                 :                :         {
 5376 peter_e@gmx.net           550                 :UBC           0 :             ecpg_log("ECPGget_desc on line %d: incorrect number of matches (indicator); %d don't fit into array of %ld\n",
                                551                 :                :                      lineno, ntuples, data_var.ind_arrsize);
 6814 meskes@postgresql.or      552                 :              0 :             ecpg_raise(lineno, ECPG_TOO_MANY_MATCHES, ECPG_SQLSTATE_CARDINALITY_VIOLATION, NULL);
 5190 peter_e@gmx.net           553                 :              0 :             va_end(args);
 8476 meskes@postgresql.or      554                 :              0 :             return false;
                                555                 :                :         }
                                556                 :                : 
                                557                 :                :         /* allocate storage if needed */
 7269 meskes@postgresql.or      558   [ -  +  -  - ]:CBC          14 :         if (data_var.ind_arrsize == 0 && data_var.ind_value == NULL)
                                559                 :                :         {
  548 peter@eisentraut.org      560                 :UBC           0 :             void       *mem = ecpg_auto_alloc(data_var.ind_offset * ntuples, lineno);
                                561                 :                : 
 7283 meskes@postgresql.or      562         [ #  # ]:              0 :             if (!mem)
                                563                 :                :             {
 5190 peter_e@gmx.net           564                 :              0 :                 va_end(args);
 7283 meskes@postgresql.or      565                 :              0 :                 return false;
                                566                 :                :             }
 8476                           567                 :              0 :             *(void **) data_var.ind_pointer = mem;
                                568                 :              0 :             data_var.ind_value = mem;
                                569                 :                :         }
                                570                 :                : 
 8476 meskes@postgresql.or      571         [ +  + ]:CBC          28 :         for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
                                572                 :                :         {
                                573         [ -  + ]:             14 :             if (!get_int_item(lineno, data_var.ind_value, data_var.ind_type, -PQgetisnull(ECPGresult, act_tuple, index)))
                                574                 :                :             {
 5190 peter_e@gmx.net           575                 :UBC           0 :                 va_end(args);
 3208                           576                 :              0 :                 return false;
                                577                 :                :             }
 8476 meskes@postgresql.or      578                 :CBC          14 :             data_var.ind_value = (char *) data_var.ind_value + data_var.ind_offset;
 6814                           579                 :             14 :             ecpg_log("ECPGget_desc: INDICATOR[%d] = %d\n", act_tuple, -PQgetisnull(ECPGresult, act_tuple, index));
                                580                 :                :         }
                                581                 :                :     }
 8385 bruce@momjian.us          582                 :             61 :     sqlca->sqlerrd[2] = ntuples;
 5190 peter_e@gmx.net           583                 :             61 :     va_end(args);
 3208                           584                 :             61 :     return true;
                                585                 :                : }
                                586                 :                : 
                                587                 :                : #undef RETURN_IF_NO_DATA
                                588                 :                : 
                                589                 :                : bool
 7486 meskes@postgresql.or      590                 :              1 : ECPGset_desc_header(int lineno, const char *desc_name, int count)
                                591                 :                : {
 6814                           592                 :              1 :     struct descriptor *desc = ecpg_find_desc(lineno, desc_name);
                                593                 :                : 
 7999                           594         [ -  + ]:              1 :     if (desc == NULL)
 7999 meskes@postgresql.or      595                 :UBC           0 :         return false;
 7999 meskes@postgresql.or      596                 :CBC           1 :     desc->count = count;
                                597                 :              1 :     return true;
                                598                 :                : }
                                599                 :                : 
                                600                 :                : static void
 2658                           601                 :             13 : set_desc_attr(struct descriptor_item *desc_item, struct variable *var,
                                602                 :                :               char *tobeinserted)
                                603                 :                : {
                                604         [ +  + ]:             13 :     if (var->type != ECPGt_bytea)
                                605                 :             11 :         desc_item->is_binary = false;
                                606                 :                : 
                                607                 :                :     else
                                608                 :                :     {
 2133 michael@paquier.xyz       609                 :              2 :         struct ECPGgeneric_bytea *variable =
                                610                 :                :             (struct ECPGgeneric_bytea *) (var->value);
                                611                 :                : 
 2658 meskes@postgresql.or      612                 :              2 :         desc_item->is_binary = true;
                                613                 :              2 :         desc_item->data_len = variable->len;
                                614                 :                :     }
                                615                 :                : 
 2565 tgl@sss.pgh.pa.us         616                 :             13 :     ecpg_free(desc_item->data); /* free() takes care of a potential NULL value */
  464 peter@eisentraut.org      617                 :             13 :     desc_item->data = tobeinserted;
 2658 meskes@postgresql.or      618                 :             13 : }
                                619                 :                : 
                                620                 :                : 
                                621                 :                : bool
   17 tgl@sss.pgh.pa.us         622                 :GNC          13 : ECPGset_desc(int lineno, const char *desc_name, int index, ...)
                                623                 :                : {
                                624                 :                :     va_list     args;
                                625                 :                :     struct descriptor *desc;
                                626                 :                :     struct descriptor_item *desc_item;
                                627                 :                :     struct variable *var;
                                628                 :                : 
 6814 meskes@postgresql.or      629                 :CBC          13 :     desc = ecpg_find_desc(lineno, desc_name);
 8004                           630         [ -  + ]:             13 :     if (desc == NULL)
 8004 meskes@postgresql.or      631                 :UBC           0 :         return false;
                                632                 :                : 
 8004 meskes@postgresql.or      633         [ +  + ]:CBC          20 :     for (desc_item = desc->items; desc_item; desc_item = desc_item->next)
                                634                 :                :     {
                                635         [ +  + ]:             14 :         if (desc_item->num == index)
                                636                 :              7 :             break;
                                637                 :                :     }
                                638                 :                : 
                                639         [ +  + ]:             13 :     if (desc_item == NULL)
                                640                 :                :     {
 6814                           641                 :              6 :         desc_item = (struct descriptor_item *) ecpg_alloc(sizeof(*desc_item), lineno);
 7283                           642         [ -  + ]:              6 :         if (!desc_item)
 7283 meskes@postgresql.or      643                 :UBC           0 :             return false;
 8004 meskes@postgresql.or      644                 :CBC           6 :         desc_item->num = index;
 6864                           645         [ +  - ]:              6 :         if (desc->count < index)
                                646                 :              6 :             desc->count = index;
 8004                           647                 :              6 :         desc_item->next = desc->items;
                                648                 :              6 :         desc->items = desc_item;
                                649                 :                :     }
                                650                 :                : 
 6814                           651         [ -  + ]:             13 :     if (!(var = (struct variable *) ecpg_alloc(sizeof(struct variable), lineno)))
 7944 bruce@momjian.us          652                 :UBC           0 :         return false;
                                653                 :                : 
 8004 meskes@postgresql.or      654                 :CBC          13 :     va_start(args, index);
                                655                 :                : 
                                656                 :                :     for (;;)
                                657                 :             17 :     {
                                658                 :                :         enum ECPGdtype itemtype;
 6197 bruce@momjian.us          659                 :             30 :         char       *tobeinserted = NULL;
                                660                 :                : 
 8004 meskes@postgresql.or      661                 :             30 :         itemtype = va_arg(args, enum ECPGdtype);
                                662                 :                : 
                                663         [ +  + ]:             30 :         if (itemtype == ECPGd_EODT)
                                664                 :             13 :             break;
                                665                 :                : 
 6973                           666                 :             17 :         var->type = va_arg(args, enum ECPGttype);
                                667                 :             17 :         var->pointer = va_arg(args, char *);
                                668                 :                : 
                                669                 :             17 :         var->varcharsize = va_arg(args, long);
                                670                 :             17 :         var->arrsize = va_arg(args, long);
                                671                 :             17 :         var->offset = va_arg(args, long);
                                672                 :                : 
                                673   [ +  -  -  + ]:             17 :         if (var->arrsize == 0 || var->varcharsize == 0)
 6973 meskes@postgresql.or      674                 :UBC           0 :             var->value = *((char **) (var->pointer));
                                675                 :                :         else
 6973 meskes@postgresql.or      676                 :CBC          17 :             var->value = var->pointer;
                                677                 :                : 
                                678                 :                :         /*
                                679                 :                :          * negative values are used to indicate an array without given bounds
                                680                 :                :          */
                                681                 :                :         /* reset to zero for us */
                                682         [ -  + ]:             17 :         if (var->arrsize < 0)
 6973 meskes@postgresql.or      683                 :UBC           0 :             var->arrsize = 0;
 6973 meskes@postgresql.or      684         [ -  + ]:CBC          17 :         if (var->varcharsize < 0)
 6973 meskes@postgresql.or      685                 :UBC           0 :             var->varcharsize = 0;
                                686                 :                : 
 6973 meskes@postgresql.or      687                 :CBC          17 :         var->next = NULL;
                                688                 :                : 
 8004                           689   [ +  +  -  -  :             17 :         switch (itemtype)
                                           -  -  - ]
                                690                 :                :         {
                                691                 :             13 :             case ECPGd_data:
                                692                 :                :                 {
 6814                           693         [ -  + ]:             13 :                     if (!ecpg_store_input(lineno, true, var, &tobeinserted, false))
                                694                 :                :                     {
 6814 meskes@postgresql.or      695                 :UBC           0 :                         ecpg_free(var);
 5190 peter_e@gmx.net           696                 :              0 :                         va_end(args);
 7944 bruce@momjian.us          697                 :              0 :                         return false;
                                698                 :                :                     }
                                699                 :                : 
 2658 meskes@postgresql.or      700                 :CBC          13 :                     set_desc_attr(desc_item, var, tobeinserted);
 7944 bruce@momjian.us          701                 :             13 :                     tobeinserted = NULL;
                                702                 :             13 :                     break;
                                703                 :                :                 }
                                704                 :                : 
 8004 meskes@postgresql.or      705                 :              4 :             case ECPGd_indicator:
 8000                           706                 :              4 :                 set_int_item(lineno, &desc_item->indicator, var->pointer, var->type);
 8004                           707                 :              4 :                 break;
                                708                 :                : 
 8004 meskes@postgresql.or      709                 :UBC           0 :             case ECPGd_length:
 8000                           710                 :              0 :                 set_int_item(lineno, &desc_item->length, var->pointer, var->type);
 8004                           711                 :              0 :                 break;
                                712                 :                : 
                                713                 :              0 :             case ECPGd_precision:
 8000                           714                 :              0 :                 set_int_item(lineno, &desc_item->precision, var->pointer, var->type);
 8004                           715                 :              0 :                 break;
                                716                 :                : 
                                717                 :              0 :             case ECPGd_scale:
 8000                           718                 :              0 :                 set_int_item(lineno, &desc_item->scale, var->pointer, var->type);
 8004                           719                 :              0 :                 break;
                                720                 :                : 
                                721                 :              0 :             case ECPGd_type:
 8000                           722                 :              0 :                 set_int_item(lineno, &desc_item->type, var->pointer, var->type);
 8004                           723                 :              0 :                 break;
                                724                 :                : 
                                725                 :              0 :             default:
                                726                 :                :                 {
                                727                 :                :                     char        type_str[20];
                                728                 :                : 
 7944 bruce@momjian.us          729                 :              0 :                     snprintf(type_str, sizeof(type_str), "%d", itemtype);
 6814 meskes@postgresql.or      730                 :              0 :                     ecpg_raise(lineno, ECPG_UNKNOWN_DESCRIPTOR_ITEM, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, type_str);
                                731                 :              0 :                     ecpg_free(var);
 5190 peter_e@gmx.net           732                 :              0 :                     va_end(args);
 7944 bruce@momjian.us          733                 :              0 :                     return false;
                                734                 :                :                 }
                                735                 :                :         }
                                736                 :                :     }
 6814 meskes@postgresql.or      737                 :CBC          13 :     ecpg_free(var);
 5190 peter_e@gmx.net           738                 :             13 :     va_end(args);
                                739                 :                : 
 8004 meskes@postgresql.or      740                 :             13 :     return true;
                                741                 :                : }
                                742                 :                : 
                                743                 :                : /* Free the descriptor and items in it. */
                                744                 :                : static void
 3265 tgl@sss.pgh.pa.us         745                 :         800015 : descriptor_free(struct descriptor *desc)
                                746                 :                : {
                                747                 :                :     struct descriptor_item *desc_item;
                                748                 :                : 
 6815 meskes@postgresql.or      749         [ +  + ]:         800017 :     for (desc_item = desc->items; desc_item;)
                                750                 :                :     {
                                751                 :                :         struct descriptor_item *di;
                                752                 :                : 
 6814                           753                 :              2 :         ecpg_free(desc_item->data);
 6815                           754                 :              2 :         di = desc_item;
                                755                 :              2 :         desc_item = desc_item->next;
 6814                           756                 :              2 :         ecpg_free(di);
                                757                 :                :     }
                                758                 :                : 
                                759                 :         800015 :     ecpg_free(desc->name);
 6815                           760                 :         800015 :     PQclear(desc->result);
 6814                           761                 :         800015 :     ecpg_free(desc);
 6815                           762                 :         800015 : }
                                763                 :                : 
                                764                 :                : bool
 8476                           765                 :         800015 : ECPGdeallocate_desc(int line, const char *name)
                                766                 :                : {
                                767                 :                :     struct descriptor *desc;
                                768                 :                :     struct descriptor *prev;
 8385 bruce@momjian.us          769                 :         800015 :     struct sqlca_t *sqlca = ECPGget_sqlca();
                                770                 :                : 
 4002 meskes@postgresql.or      771         [ -  + ]:         800015 :     if (sqlca == NULL)
                                772                 :                :     {
 4002 meskes@postgresql.or      773                 :UBC           0 :         ecpg_raise(line, ECPG_OUT_OF_MEMORY,
                                774                 :                :                    ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
                                775                 :              0 :         return false;
                                776                 :                :     }
                                777                 :                : 
 6814 meskes@postgresql.or      778                 :CBC      800015 :     ecpg_init_sqlca(sqlca);
 6815                           779         [ +  - ]:         800020 :     for (desc = get_descriptors(), prev = NULL; desc; prev = desc, desc = desc->next)
                                780                 :                :     {
 5268 peter_e@gmx.net           781         [ +  + ]:         800020 :         if (strcmp(name, desc->name) == 0)
                                782                 :                :         {
 6815 meskes@postgresql.or      783         [ +  + ]:         800015 :             if (prev)
                                784                 :              5 :                 prev->next = desc->next;
                                785                 :                :             else
                                786                 :         800010 :                 set_descriptors(desc->next);
                                787                 :         800015 :             descriptor_free(desc);
 8476                           788                 :         800015 :             return true;
                                789                 :                :         }
                                790                 :                :     }
 6814 meskes@postgresql.or      791                 :UBC           0 :     ecpg_raise(line, ECPG_UNKNOWN_DESCRIPTOR, ECPG_SQLSTATE_INVALID_SQL_DESCRIPTOR_NAME, name);
 8476                           792                 :              0 :     return false;
                                793                 :                : }
                                794                 :                : 
                                795                 :                : /* Deallocate all descriptors in the list */
                                796                 :                : static void
 3265 tgl@sss.pgh.pa.us         797                 :              0 : descriptor_deallocate_all(struct descriptor *list)
                                798                 :                : {
 6815 meskes@postgresql.or      799         [ #  # ]:              0 :     while (list)
                                800                 :                :     {
                                801                 :              0 :         struct descriptor *next = list->next;
                                802                 :                : 
                                803                 :              0 :         descriptor_free(list);
                                804                 :              0 :         list = next;
                                805                 :                :     }
                                806                 :              0 : }
                                807                 :                : 
                                808                 :                : bool
 8476 meskes@postgresql.or      809                 :CBC      800019 : ECPGallocate_desc(int line, const char *name)
                                810                 :                : {
                                811                 :                :     struct descriptor *new;
 8385 bruce@momjian.us          812                 :         800019 :     struct sqlca_t *sqlca = ECPGget_sqlca();
                                813                 :                : 
 4002 meskes@postgresql.or      814         [ -  + ]:         800019 :     if (sqlca == NULL)
                                815                 :                :     {
 4002 meskes@postgresql.or      816                 :UBC           0 :         ecpg_raise(line, ECPG_OUT_OF_MEMORY,
                                817                 :                :                    ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
                                818                 :              0 :         return false;
                                819                 :                :     }
                                820                 :                : 
 6814 meskes@postgresql.or      821                 :CBC      800019 :     ecpg_init_sqlca(sqlca);
                                822                 :         800019 :     new = (struct descriptor *) ecpg_alloc(sizeof(struct descriptor), line);
 8476                           823         [ -  + ]:         800019 :     if (!new)
 8476 meskes@postgresql.or      824                 :UBC           0 :         return false;
 6815 meskes@postgresql.or      825                 :CBC      800019 :     new->next = get_descriptors();
 6814                           826                 :         800019 :     new->name = ecpg_alloc(strlen(name) + 1, line);
 8476                           827         [ -  + ]:         800019 :     if (!new->name)
                                828                 :                :     {
 6814 meskes@postgresql.or      829                 :UBC           0 :         ecpg_free(new);
 8476                           830                 :              0 :         return false;
                                831                 :                :     }
 7999 meskes@postgresql.or      832                 :CBC      800019 :     new->count = -1;
 8004                           833                 :         800019 :     new->items = NULL;
 8476                           834                 :         800019 :     new->result = PQmakeEmptyPGresult(NULL, 0);
                                835         [ -  + ]:         800019 :     if (!new->result)
                                836                 :                :     {
 6814 meskes@postgresql.or      837                 :UBC           0 :         ecpg_free(new->name);
                                838                 :              0 :         ecpg_free(new);
                                839                 :              0 :         ecpg_raise(line, ECPG_OUT_OF_MEMORY, ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
 8476                           840                 :              0 :         return false;
                                841                 :                :     }
 8476 meskes@postgresql.or      842                 :CBC      800019 :     strcpy(new->name, name);
 6815                           843                 :         800019 :     set_descriptors(new);
 8476                           844                 :         800019 :     return true;
                                845                 :                : }
                                846                 :                : 
                                847                 :                : /* Find descriptor with name in the connection. */
                                848                 :                : struct descriptor *
 6814                           849                 :            120 : ecpg_find_desc(int line, const char *name)
                                850                 :                : {
                                851                 :                :     struct descriptor *desc;
                                852                 :                : 
 6815                           853         [ +  - ]:            169 :     for (desc = get_descriptors(); desc; desc = desc->next)
                                854                 :                :     {
                                855         [ +  + ]:            169 :         if (strcmp(name, desc->name) == 0)
                                856                 :            120 :             return desc;
                                857                 :                :     }
                                858                 :                : 
 6814 meskes@postgresql.or      859                 :UBC           0 :     ecpg_raise(line, ECPG_UNKNOWN_DESCRIPTOR, ECPG_SQLSTATE_INVALID_SQL_DESCRIPTOR_NAME, name);
 6771 bruce@momjian.us          860                 :              0 :     return NULL;                /* not found */
                                861                 :                : }
                                862                 :                : 
                                863                 :                : bool
   17 tgl@sss.pgh.pa.us         864                 :GNC          21 : ECPGdescribe(int line, int compat, bool input, const char *connection_name, const char *stmt_name, ...)
                                865                 :                : {
 5979 meskes@postgresql.or      866                 :CBC          21 :     bool        ret = false;
                                867                 :                :     struct connection *con;
                                868                 :                :     struct prepared_statement *prep;
                                869                 :                :     PGresult   *res;
                                870                 :                :     va_list     args;
                                871                 :                : 
                                872                 :                :     /* DESCRIBE INPUT is not yet supported */
                                873         [ -  + ]:             21 :     if (input)
                                874                 :                :     {
 5979 meskes@postgresql.or      875                 :UBC           0 :         ecpg_raise(line, ECPG_UNSUPPORTED, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, "DESCRIBE INPUT");
                                876                 :              0 :         return ret;
                                877                 :                :     }
                                878                 :                : 
 2444 tgl@sss.pgh.pa.us         879                 :CBC          21 :     con = ecpg_get_connection(connection_name);
 5979 meskes@postgresql.or      880         [ -  + ]:             21 :     if (!con)
                                881                 :                :     {
 5979 meskes@postgresql.or      882         [ #  # ]:UBC           0 :         ecpg_raise(line, ECPG_NO_CONN, ECPG_SQLSTATE_CONNECTION_DOES_NOT_EXIST,
 2444 tgl@sss.pgh.pa.us         883                 :              0 :                    connection_name ? connection_name : ecpg_gettext("NULL"));
 5979 meskes@postgresql.or      884                 :              0 :         return ret;
                                885                 :                :     }
 5979 meskes@postgresql.or      886                 :CBC          21 :     prep = ecpg_find_prepared_statement(stmt_name, con, NULL);
                                887         [ -  + ]:             21 :     if (!prep)
                                888                 :                :     {
 5979 meskes@postgresql.or      889                 :UBC           0 :         ecpg_raise(line, ECPG_INVALID_STMT, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, stmt_name);
                                890                 :              0 :         return ret;
                                891                 :                :     }
                                892                 :                : 
 5979 meskes@postgresql.or      893                 :CBC          21 :     va_start(args, stmt_name);
                                894                 :                : 
                                895                 :                :     for (;;)
                                896                 :             21 :     {
                                897                 :                :         enum ECPGttype type;
                                898                 :                :         void       *ptr;
                                899                 :                : 
                                900                 :                :         /* variable type */
                                901                 :             42 :         type = va_arg(args, enum ECPGttype);
                                902                 :                : 
                                903         [ +  + ]:             42 :         if (type == ECPGt_EORT)
                                904                 :             21 :             break;
                                905                 :                : 
                                906                 :                :         /* rest of variable parameters */
                                907                 :             21 :         ptr = va_arg(args, void *);
 3265 tgl@sss.pgh.pa.us         908                 :             21 :         (void) va_arg(args, long);  /* skip args */
 5527                           909                 :             21 :         (void) va_arg(args, long);
                                910                 :             21 :         (void) va_arg(args, long);
                                911                 :                : 
                                912                 :                :         /* variable indicator */
                                913                 :             21 :         (void) va_arg(args, enum ECPGttype);
                                914                 :             21 :         (void) va_arg(args, void *);    /* skip args */
                                915                 :             21 :         (void) va_arg(args, long);
                                916                 :             21 :         (void) va_arg(args, long);
                                917                 :             21 :         (void) va_arg(args, long);
                                918                 :                : 
 5979 meskes@postgresql.or      919      [ +  +  - ]:             21 :         switch (type)
                                920                 :                :         {
                                921                 :              9 :             case ECPGt_descriptor:
                                922                 :                :                 {
 5937 bruce@momjian.us          923                 :              9 :                     char       *name = ptr;
                                924                 :              9 :                     struct descriptor *desc = ecpg_find_desc(line, name);
                                925                 :                : 
                                926         [ -  + ]:              9 :                     if (desc == NULL)
 5937 bruce@momjian.us          927                 :UBC           0 :                         break;
                                928                 :                : 
 5979 meskes@postgresql.or      929                 :CBC           9 :                     res = PQdescribePrepared(con->connection, stmt_name);
                                930         [ -  + ]:              9 :                     if (!ecpg_check_PQresult(res, line, con->connection, compat))
 5979 meskes@postgresql.or      931                 :UBC           0 :                         break;
                                932                 :                : 
 1427 peter@eisentraut.org      933                 :CBC           9 :                     PQclear(desc->result);
                                934                 :                : 
 5937 bruce@momjian.us          935                 :              9 :                     desc->result = res;
                                936                 :              9 :                     ret = true;
                                937                 :              9 :                     break;
                                938                 :                :                 }
                                939                 :             12 :             case ECPGt_sqlda:
                                940                 :                :                 {
                                941   [ +  +  -  + ]:             12 :                     if (INFORMIX_MODE(compat))
 5979 meskes@postgresql.or      942                 :              6 :                     {
 5937 bruce@momjian.us          943                 :              6 :                         struct sqlda_compat **_sqlda = ptr;
                                944                 :                :                         struct sqlda_compat *sqlda;
                                945                 :                : 
                                946                 :              6 :                         res = PQdescribePrepared(con->connection, stmt_name);
                                947         [ -  + ]:              6 :                         if (!ecpg_check_PQresult(res, line, con->connection, compat))
 5937 bruce@momjian.us          948                 :UBC           0 :                             break;
                                949                 :                : 
 5937 bruce@momjian.us          950                 :CBC           6 :                         sqlda = ecpg_build_compat_sqlda(line, res, -1, compat);
                                951         [ +  - ]:              6 :                         if (sqlda)
                                952                 :                :                         {
                                953                 :              6 :                             struct sqlda_compat *sqlda_old = *_sqlda;
                                954                 :                :                             struct sqlda_compat *sqlda_old1;
                                955                 :                : 
                                956         [ -  + ]:              6 :                             while (sqlda_old)
                                957                 :                :                             {
 5937 bruce@momjian.us          958                 :UBC           0 :                                 sqlda_old1 = sqlda_old->desc_next;
                                959                 :              0 :                                 free(sqlda_old);
                                960                 :              0 :                                 sqlda_old = sqlda_old1;
                                961                 :                :                             }
                                962                 :                : 
 5937 bruce@momjian.us          963                 :CBC           6 :                             *_sqlda = sqlda;
                                964                 :              6 :                             ret = true;
                                965                 :                :                         }
                                966                 :                : 
                                967                 :              6 :                         PQclear(res);
                                968                 :                :                     }
                                969                 :                :                     else
                                970                 :                :                     {
                                971                 :              6 :                         struct sqlda_struct **_sqlda = ptr;
                                972                 :                :                         struct sqlda_struct *sqlda;
                                973                 :                : 
                                974                 :              6 :                         res = PQdescribePrepared(con->connection, stmt_name);
                                975         [ -  + ]:              6 :                         if (!ecpg_check_PQresult(res, line, con->connection, compat))
 5937 bruce@momjian.us          976                 :UBC           0 :                             break;
                                977                 :                : 
 5937 bruce@momjian.us          978                 :CBC           6 :                         sqlda = ecpg_build_native_sqlda(line, res, -1, compat);
                                979         [ +  - ]:              6 :                         if (sqlda)
                                980                 :                :                         {
                                981                 :              6 :                             struct sqlda_struct *sqlda_old = *_sqlda;
                                982                 :                :                             struct sqlda_struct *sqlda_old1;
                                983                 :                : 
                                984         [ -  + ]:              6 :                             while (sqlda_old)
                                985                 :                :                             {
 5937 bruce@momjian.us          986                 :UBC           0 :                                 sqlda_old1 = sqlda_old->desc_next;
                                987                 :              0 :                                 free(sqlda_old);
                                988                 :              0 :                                 sqlda_old = sqlda_old1;
                                989                 :                :                             }
                                990                 :                : 
 5937 bruce@momjian.us          991                 :CBC           6 :                             *_sqlda = sqlda;
                                992                 :              6 :                             ret = true;
                                993                 :                :                         }
                                994                 :                : 
                                995                 :              6 :                         PQclear(res);
                                996                 :                :                     }
                                997                 :             12 :                     break;
                                998                 :                :                 }
 5979 meskes@postgresql.or      999                 :             21 :             default:
                               1000                 :                :                 /* nothing else may come */
                               1001                 :                :                 ;
                               1002                 :                :         }
                               1003                 :                :     }
                               1004                 :                : 
                               1005                 :             21 :     va_end(args);
                               1006                 :                : 
                               1007                 :             21 :     return ret;
                               1008                 :                : }
        

Generated by: LCOV version 2.5.0-beta