LCOV - differential code coverage report
Current view: top level - src/interfaces/ecpg/preproc - descriptor.c (source / functions) Coverage Total Hit UIC GIC
Current: c70b6db34ffeab48beef1fb4ce61bcad3772b8dd vs 06473f5a344df8c9594ead90a609b86f6724cff8 Lines: 66.1 % 180 119 61 119
Current Date: 2025-09-06 07:49:51 +0900 Functions: 92.3 % 13 12 1 12
Baseline: lcov-20250906-005545-baseline Branches: 48.8 % 84 41 43 41
Baseline Date: 2025-09-05 08:21:35 +0100 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(30,360] days: 100.0 % 16 16 16
(360..) days: 62.8 % 164 103 61 103
Function coverage date bins:
(30,360] days: 100.0 % 8 8 8
(360..) days: 80.0 % 5 4 1 4
Branch coverage date bins:
(360..) days: 48.8 % 84 41 43 41

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*
                                  2                 :                :  * functions needed for descriptor handling
                                  3                 :                :  *
                                  4                 :                :  * src/interfaces/ecpg/preproc/descriptor.c
                                  5                 :                :  *
                                  6                 :                :  * since descriptor might be either a string constant or a string var
                                  7                 :                :  * we need to check for a constant if we expect a constant
                                  8                 :                :  */
                                  9                 :                : 
                                 10                 :                : #include "postgres_fe.h"
                                 11                 :                : 
                                 12                 :                : #include "preproc_extern.h"
                                 13                 :                : 
                                 14                 :                : /*
                                 15                 :                :  * assignment handling function (descriptor)
                                 16                 :                :  */
                                 17                 :                : 
                                 18                 :                : static struct assignment *assignments;
                                 19                 :                : 
                                 20                 :                : void
  327 tgl@sss.pgh.pa.us          21                 :GIC          78 : push_assignment(const char *var, enum ECPGdtype value)
                                 22                 :                : {
 9278 bruce@momjian.us           23                 :             78 :     struct assignment *new = (struct assignment *) mm_alloc(sizeof(struct assignment));
                                 24                 :                : 
 9332 meskes@postgresql.or       25                 :             78 :     new->next = assignments;
  327 tgl@sss.pgh.pa.us          26                 :             78 :     new->variable = mm_strdup(var);
 9328 meskes@postgresql.or       27                 :             78 :     new->value = value;
 9332                            28                 :             78 :     assignments = new;
 9333                            29                 :             78 : }
                                 30                 :                : 
                                 31                 :                : static void
                                 32                 :             54 : drop_assignments(void)
                                 33                 :                : {
 9332                            34         [ +  + ]:            132 :     while (assignments)
                                 35                 :                :     {
                                 36                 :             78 :         struct assignment *old_head = assignments;
                                 37                 :                : 
                                 38                 :             78 :         assignments = old_head->next;
 9333                            39                 :             78 :         free(old_head->variable);
                                 40                 :             78 :         free(old_head);
                                 41                 :                :     }
                                 42                 :             54 : }
                                 43                 :                : 
                                 44                 :                : static void
 6469                            45                 :             12 : ECPGnumeric_lvalue(char *name)
                                 46                 :                : {
 9278 bruce@momjian.us           47                 :             12 :     const struct variable *v = find_variable(name);
                                 48                 :                : 
 8658 meskes@postgresql.or       49         [ +  - ]:             12 :     switch (v->type->type)
                                 50                 :                :     {
 9333                            51                 :             12 :         case ECPGt_short:
                                 52                 :                :         case ECPGt_int:
                                 53                 :                :         case ECPGt_long:
                                 54                 :                :         case ECPGt_long_long:
                                 55                 :                :         case ECPGt_unsigned_short:
                                 56                 :                :         case ECPGt_unsigned_int:
                                 57                 :                :         case ECPGt_unsigned_long:
                                 58                 :                :         case ECPGt_unsigned_long_long:
                                 59                 :                :         case ECPGt_const:
 3191 tgl@sss.pgh.pa.us          60                 :             12 :             fputs(name, base_yyout);
 9333 meskes@postgresql.or       61                 :             12 :             break;
 9333 meskes@postgresql.or       62                 :UIC           0 :         default:
 6070 peter_e@gmx.net            63                 :              0 :             mmerror(PARSE_ERROR, ET_ERROR, "variable \"%s\" must have a numeric type", name);
 9333 meskes@postgresql.or       64                 :              0 :             break;
                                 65                 :                :     }
 9333 meskes@postgresql.or       66                 :GIC          12 : }
                                 67                 :                : 
                                 68                 :                : /*
                                 69                 :                :  * descriptor name lookup
                                 70                 :                :  */
                                 71                 :                : 
                                 72                 :                : static struct descriptor *descriptors;
                                 73                 :                : 
                                 74                 :                : void
  327 tgl@sss.pgh.pa.us          75                 :             18 : add_descriptor(const char *name, const char *connection)
                                 76                 :                : {
                                 77                 :                :     struct descriptor *new;
                                 78                 :                : 
 8717 bruce@momjian.us           79         [ +  + ]:             18 :     if (name[0] != '"')
                                 80                 :              1 :         return;
                                 81                 :                : 
 8784 meskes@postgresql.or       82                 :             17 :     new = (struct descriptor *) mm_alloc(sizeof(struct descriptor));
                                 83                 :                : 
 9328                            84                 :             17 :     new->next = descriptors;
  327 tgl@sss.pgh.pa.us          85                 :             17 :     new->name = mm_strdup(name);
 9278 bruce@momjian.us           86         [ +  + ]:             17 :     if (connection)
  327 tgl@sss.pgh.pa.us          87                 :              2 :         new->connection = mm_strdup(connection);
                                 88                 :                :     else
                                 89                 :             15 :         new->connection = NULL;
 9328 meskes@postgresql.or       90                 :             17 :     descriptors = new;
                                 91                 :                : }
                                 92                 :                : 
                                 93                 :                : void
  327 tgl@sss.pgh.pa.us          94                 :             16 : drop_descriptor(const char *name, const char *connection)
                                 95                 :                : {
                                 96                 :                :     struct descriptor *i;
 9278 bruce@momjian.us           97                 :             16 :     struct descriptor **lastptr = &descriptors;
                                 98                 :                : 
 8717                            99         [ +  + ]:             16 :     if (name[0] != '"')
                                100                 :              1 :         return;
                                101                 :                : 
 9278                           102         [ +  - ]:             19 :     for (i = descriptors; i; lastptr = &i->next, i = i->next)
                                103                 :                :     {
 5002 peter_e@gmx.net           104         [ +  + ]:             19 :         if (strcmp(name, i->name) == 0)
                                105                 :                :         {
 9278 bruce@momjian.us          106   [ +  +  -  + ]:             15 :             if ((!connection && !i->connection)
                                107   [ +  -  +  - ]:              2 :                 || (connection && i->connection
 5002 peter_e@gmx.net           108         [ +  - ]:              2 :                     && strcmp(connection, i->connection) == 0))
                                109                 :                :             {
 9278 bruce@momjian.us          110                 :             15 :                 *lastptr = i->next;
 1178 peter@eisentraut.org      111                 :             15 :                 free(i->connection);
 9332 meskes@postgresql.or      112                 :             15 :                 free(i->name);
                                113                 :             15 :                 free(i);
                                114                 :             15 :                 return;
                                115                 :                :             }
                                116                 :                :         }
                                117                 :                :     }
 1485 meskes@postgresql.or      118         [ #  # ]:UIC           0 :     if (connection)
                                119                 :              0 :         mmerror(PARSE_ERROR, ET_WARNING, "descriptor %s bound to connection %s does not exist", name, connection);
                                120                 :                :     else
                                121                 :              0 :         mmerror(PARSE_ERROR, ET_WARNING, "descriptor %s bound to the default connection does not exist", name);
                                122                 :                : }
                                123                 :                : 
                                124                 :                : struct descriptor *
  327 tgl@sss.pgh.pa.us         125                 :GIC          54 : lookup_descriptor(const char *name, const char *connection)
                                126                 :                : {
                                127                 :                :     struct descriptor *i;
                                128                 :                : 
 8717 bruce@momjian.us          129         [ +  + ]:             54 :     if (name[0] != '"')
                                130                 :              1 :         return NULL;
                                131                 :                : 
 9328 meskes@postgresql.or      132         [ +  - ]:             67 :     for (i = descriptors; i; i = i->next)
                                133                 :                :     {
 5002 peter_e@gmx.net           134         [ +  + ]:             67 :         if (strcmp(name, i->name) == 0)
                                135                 :                :         {
 9278 bruce@momjian.us          136   [ +  +  -  + ]:             53 :             if ((!connection && !i->connection)
                                137   [ +  -  +  - ]:              3 :                 || (connection && i->connection
 5002 peter_e@gmx.net           138         [ +  - ]:              3 :                     && strcmp(connection, i->connection) == 0))
 9332 meskes@postgresql.or      139                 :             53 :                 return i;
 1485 meskes@postgresql.or      140   [ #  #  #  # ]:UIC           0 :             if (connection && !i->connection)
                                141                 :                :             {
                                142                 :                :                 /* overwrite descriptor's connection */
                                143                 :              0 :                 i->connection = mm_strdup(connection);
                                144                 :              0 :                 return i;
                                145                 :                :             }
                                146                 :                :         }
                                147                 :                :     }
                                148         [ #  # ]:              0 :     if (connection)
                                149                 :              0 :         mmerror(PARSE_ERROR, ET_WARNING, "descriptor %s bound to connection %s does not exist", name, connection);
                                150                 :                :     else
                                151                 :              0 :         mmerror(PARSE_ERROR, ET_WARNING, "descriptor %s bound to the default connection does not exist", name);
 9332                           152                 :              0 :     return NULL;
                                153                 :                : }
                                154                 :                : 
                                155                 :                : void
  327 tgl@sss.pgh.pa.us         156                 :GIC          11 : output_get_descr_header(const char *desc_name)
                                157                 :                : {
                                158                 :                :     struct assignment *results;
                                159                 :                : 
 3191                           160                 :             11 :     fprintf(base_yyout, "{ ECPGget_desc_header(__LINE__, %s, &(", desc_name);
 9332 meskes@postgresql.or      161         [ +  + ]:             22 :     for (results = assignments; results != NULL; results = results->next)
                                162                 :                :     {
 9328                           163         [ +  - ]:             11 :         if (results->value == ECPGd_count)
 6469                           164                 :             11 :             ECPGnumeric_lvalue(results->variable);
                                165                 :                :         else
 6070 peter_e@gmx.net           166                 :UIC           0 :             mmerror(PARSE_ERROR, ET_WARNING, "descriptor header item \"%d\" does not exist", results->value);
                                167                 :                :     }
                                168                 :                : 
 9332 meskes@postgresql.or      169                 :GIC          11 :     drop_assignments();
 3191 tgl@sss.pgh.pa.us         170                 :             11 :     fprintf(base_yyout, "));\n");
 9332 meskes@postgresql.or      171                 :             11 :     whenever_action(3);
 9333                           172                 :             11 : }
                                173                 :                : 
                                174                 :                : void
  327 tgl@sss.pgh.pa.us         175                 :             31 : output_get_descr(const char *desc_name, const char *index)
                                176                 :                : {
                                177                 :                :     struct assignment *results;
                                178                 :                : 
 3191                           179                 :             31 :     fprintf(base_yyout, "{ ECPGget_desc(__LINE__, %s, %s,", desc_name, index);
 9328 meskes@postgresql.or      180         [ +  + ]:             82 :     for (results = assignments; results != NULL; results = results->next)
                                181                 :                :     {
                                182                 :             51 :         const struct variable *v = find_variable(results->variable);
 3376 rhaas@postgresql.org      183                 :             51 :         char       *str_zero = mm_strdup("0");
                                184                 :                : 
 9328 meskes@postgresql.or      185      [ -  -  + ]:             51 :         switch (results->value)
                                186                 :                :         {
 9328 meskes@postgresql.or      187                 :UIC           0 :             case ECPGd_nullable:
 8585 bruce@momjian.us          188                 :              0 :                 mmerror(PARSE_ERROR, ET_WARNING, "nullable is always 1");
 9328 meskes@postgresql.or      189                 :              0 :                 break;
                                190                 :              0 :             case ECPGd_key_member:
 8585 bruce@momjian.us          191                 :              0 :                 mmerror(PARSE_ERROR, ET_WARNING, "key_member is always 0");
 9328 meskes@postgresql.or      192                 :              0 :                 break;
 9328 meskes@postgresql.or      193                 :GIC          51 :             default:
 9278 bruce@momjian.us          194                 :             51 :                 break;
                                195                 :                :         }
 3191 tgl@sss.pgh.pa.us         196                 :             51 :         fprintf(base_yyout, "%s,", get_dtype(results->value));
                                197                 :             51 :         ECPGdump_a_type(base_yyout, v->name, v->type, v->brace_level,
                                198                 :                :                         NULL, NULL, -1, NULL, NULL, str_zero, NULL, NULL);
 3739 meskes@postgresql.or      199                 :             51 :         free(str_zero);
                                200                 :                :     }
 9333                           201                 :             31 :     drop_assignments();
 3191 tgl@sss.pgh.pa.us         202                 :             31 :     fputs("ECPGd_EODT);\n", base_yyout);
                                203                 :                : 
 9278 bruce@momjian.us          204                 :             31 :     whenever_action(2 | 1);
 9333 meskes@postgresql.or      205                 :             31 : }
                                206                 :                : 
                                207                 :                : void
  327 tgl@sss.pgh.pa.us         208                 :              1 : output_set_descr_header(const char *desc_name)
                                209                 :                : {
                                210                 :                :     struct assignment *results;
                                211                 :                : 
 3191                           212                 :              1 :     fprintf(base_yyout, "{ ECPGset_desc_header(__LINE__, %s, (int)(", desc_name);
 7738 meskes@postgresql.or      213         [ +  + ]:              2 :     for (results = assignments; results != NULL; results = results->next)
                                214                 :                :     {
                                215         [ +  - ]:              1 :         if (results->value == ECPGd_count)
 6469                           216                 :              1 :             ECPGnumeric_lvalue(results->variable);
                                217                 :                :         else
 6070 peter_e@gmx.net           218                 :UIC           0 :             mmerror(PARSE_ERROR, ET_WARNING, "descriptor header item \"%d\" does not exist", results->value);
                                219                 :                :     }
                                220                 :                : 
 7738 meskes@postgresql.or      221                 :GIC           1 :     drop_assignments();
 3191 tgl@sss.pgh.pa.us         222                 :              1 :     fprintf(base_yyout, "));\n");
 7738 meskes@postgresql.or      223                 :              1 :     whenever_action(3);
                                224                 :              1 : }
                                225                 :                : 
                                226                 :                : static const char *
 7738 meskes@postgresql.or      227                 :UIC           0 : descriptor_item_name(enum ECPGdtype itemcode)
                                228                 :                : {
                                229   [ #  #  #  #  :              0 :     switch (itemcode)
                                     #  #  #  #  #  
                                     #  #  #  #  #  
                                           #  #  # ]
                                230                 :                :     {
                                231                 :              0 :         case ECPGd_cardinality:
                                232                 :              0 :             return "CARDINALITY";
                                233                 :              0 :         case ECPGd_count:
                                234                 :              0 :             return "COUNT";
                                235                 :              0 :         case ECPGd_data:
                                236                 :              0 :             return "DATA";
                                237                 :              0 :         case ECPGd_di_code:
                                238                 :              0 :             return "DATETIME_INTERVAL_CODE";
                                239                 :              0 :         case ECPGd_di_precision:
                                240                 :              0 :             return "DATETIME_INTERVAL_PRECISION";
                                241                 :              0 :         case ECPGd_indicator:
                                242                 :              0 :             return "INDICATOR";
                                243                 :              0 :         case ECPGd_key_member:
                                244                 :              0 :             return "KEY_MEMBER";
                                245                 :              0 :         case ECPGd_length:
                                246                 :              0 :             return "LENGTH";
                                247                 :              0 :         case ECPGd_name:
                                248                 :              0 :             return "NAME";
                                249                 :              0 :         case ECPGd_nullable:
                                250                 :              0 :             return "NULLABLE";
                                251                 :              0 :         case ECPGd_octet:
                                252                 :              0 :             return "OCTET_LENGTH";
                                253                 :              0 :         case ECPGd_precision:
                                254                 :              0 :             return "PRECISION";
                                255                 :              0 :         case ECPGd_ret_length:
                                256                 :              0 :             return "RETURNED_LENGTH";
                                257                 :              0 :         case ECPGd_ret_octet:
                                258                 :              0 :             return "RETURNED_OCTET_LENGTH";
                                259                 :              0 :         case ECPGd_scale:
                                260                 :              0 :             return "SCALE";
                                261                 :              0 :         case ECPGd_type:
                                262                 :              0 :             return "TYPE";
                                263                 :              0 :         default:
                                264                 :              0 :             return NULL;
                                265                 :                :     }
                                266                 :                : }
                                267                 :                : 
                                268                 :                : void
  327 tgl@sss.pgh.pa.us         269                 :GIC          11 : output_set_descr(const char *desc_name, const char *index)
                                270                 :                : {
                                271                 :                :     struct assignment *results;
                                272                 :                : 
 3191                           273                 :             11 :     fprintf(base_yyout, "{ ECPGset_desc(__LINE__, %s, %s,", desc_name, index);
 7738 meskes@postgresql.or      274         [ +  + ]:             26 :     for (results = assignments; results != NULL; results = results->next)
                                275                 :                :     {
                                276                 :             15 :         const struct variable *v = find_variable(results->variable);
                                277                 :                : 
                                278   [ -  -  +  - ]:             15 :         switch (results->value)
                                279                 :                :         {
 7738 meskes@postgresql.or      280                 :UIC           0 :             case ECPGd_cardinality:
                                281                 :                :             case ECPGd_di_code:
                                282                 :                :             case ECPGd_di_precision:
                                283                 :                :             case ECPGd_precision:
                                284                 :                :             case ECPGd_scale:
 4316 peter_e@gmx.net           285                 :              0 :                 mmfatal(PARSE_ERROR, "descriptor item \"%s\" is not implemented",
                                286                 :                :                         descriptor_item_name(results->value));
                                287                 :                :                 break;
                                288                 :                : 
 7738 meskes@postgresql.or      289                 :              0 :             case ECPGd_key_member:
                                290                 :                :             case ECPGd_name:
                                291                 :                :             case ECPGd_nullable:
                                292                 :                :             case ECPGd_octet:
                                293                 :                :             case ECPGd_ret_length:
                                294                 :                :             case ECPGd_ret_octet:
 4316 peter_e@gmx.net           295                 :              0 :                 mmfatal(PARSE_ERROR, "descriptor item \"%s\" cannot be set",
                                296                 :                :                         descriptor_item_name(results->value));
                                297                 :                :                 break;
                                298                 :                : 
 7738 meskes@postgresql.or      299                 :GIC          15 :             case ECPGd_data:
                                300                 :                :             case ECPGd_indicator:
                                301                 :                :             case ECPGd_length:
                                302                 :                :             case ECPGd_type:
                                303                 :                :                 {
 3376 rhaas@postgresql.org      304                 :             15 :                     char       *str_zero = mm_strdup("0");
                                305                 :                : 
 3191 tgl@sss.pgh.pa.us         306                 :             15 :                     fprintf(base_yyout, "%s,", get_dtype(results->value));
                                307                 :             15 :                     ECPGdump_a_type(base_yyout, v->name, v->type, v->brace_level,
                                308                 :                :                                     NULL, NULL, -1, NULL, NULL, str_zero, NULL, NULL);
 3739 meskes@postgresql.or      309                 :             15 :                     free(str_zero);
                                310                 :                :                 }
 7738                           311                 :             15 :                 break;
                                312                 :                : 
                                313                 :             15 :             default:
                                314                 :                :                 ;
                                315                 :                :         }
                                316                 :                :     }
                                317                 :             11 :     drop_assignments();
 3191 tgl@sss.pgh.pa.us         318                 :             11 :     fputs("ECPGd_EODT);\n", base_yyout);
                                319                 :                : 
 7738 meskes@postgresql.or      320                 :             11 :     whenever_action(2 | 1);
                                321                 :             11 : }
                                322                 :                : 
                                323                 :                : /* I consider dynamic allocation overkill since at most two descriptor
                                324                 :                :    variables are possible per statement. (input and output descriptor)
                                325                 :                :    And descriptors are no normal variables, so they don't belong into
                                326                 :                :    the variable list.
                                327                 :                : */
                                328                 :                : 
                                329                 :                : #define MAX_DESCRIPTOR_NAMELEN 128
                                330                 :                : struct variable *
 8717 bruce@momjian.us          331                 :             22 : descriptor_variable(const char *name, int input)
                                332                 :                : {
                                333                 :                :     static char descriptor_names[2][MAX_DESCRIPTOR_NAMELEN];
                                334                 :                :     static struct ECPGtype descriptor_type = {ECPGt_descriptor, NULL, NULL, NULL, {NULL}, 0};
                                335                 :                :     static struct variable varspace[2] = {
                                336                 :                :         {descriptor_names[0], &descriptor_type, 0, NULL},
                                337                 :                :         {descriptor_names[1], &descriptor_type, 0, NULL}
                                338                 :                :     };
                                339                 :                : 
 6786 peter_e@gmx.net           340                 :             22 :     strlcpy(descriptor_names[input], name, sizeof(descriptor_names[input]));
 4936                           341                 :             22 :     return &varspace[input];
                                342                 :                : }
                                343                 :                : 
                                344                 :                : struct variable *
 5723 meskes@postgresql.or      345                 :             25 : sqlda_variable(const char *name)
                                346                 :                : {
                                347                 :                :     /*
                                348                 :                :      * Presently, sqlda variables are only needed for the duration of the
                                349                 :                :      * current statement.  Rather than add infrastructure to manage them,
                                350                 :                :      * let's just loc_alloc them.
                                351                 :                :      */
  283 tgl@sss.pgh.pa.us         352                 :             25 :     struct variable *p = (struct variable *) loc_alloc(sizeof(struct variable));
                                353                 :                : 
                                354                 :             25 :     p->name = loc_strdup(name);
                                355                 :             25 :     p->type = (struct ECPGtype *) loc_alloc(sizeof(struct ECPGtype));
 5723 meskes@postgresql.or      356                 :             25 :     p->type->type = ECPGt_sqlda;
  283 tgl@sss.pgh.pa.us         357                 :             25 :     p->type->type_name = NULL;
 5723 meskes@postgresql.or      358                 :             25 :     p->type->size = NULL;
                                359                 :             25 :     p->type->struct_sizeof = NULL;
                                360                 :             25 :     p->type->u.element = NULL;
 5660                           361                 :             25 :     p->type->counter = 0;
 5723                           362                 :             25 :     p->brace_level = 0;
                                363                 :             25 :     p->next = NULL;
                                364                 :                : 
                                365                 :             25 :     return p;
                                366                 :                : }
        

Generated by: LCOV version 2.4-beta