LCOV - differential code coverage report
Current view: top level - contrib/cube - cubeparse.y (source / functions) Coverage Total Hit UNC UIC UBC GBC GIC GNC CBC EUB ECB DUB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 84.6 % 104 88 10 4 2 2 33 28 25 9 38 3 25
Current Date: 2023-04-08 15:15:32 Functions: 100.0 % 3 3 1 2 3
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

           TLA  Line data    Source code
       1                 : %{
       2                 : /* contrib/cube/cubeparse.y */
       3                 : 
       4                 : /* NdBox = [(lowerleft),(upperright)] */
       5                 : /* [(xLL(1)...xLL(N)),(xUR(1)...xUR(n))] */
       6                 : 
       7                 : #include "postgres.h"
       8                 : 
       9                 : #include "cubedata.h"
      10                 : #include "nodes/miscnodes.h"
      11                 : #include "utils/float.h"
      12                 : #include "varatt.h"
      13                 : 
      14                 : /* All grammar constructs return strings */
      15                 : #define YYSTYPE char *
      16                 : 
      17                 : /*
      18                 :  * Bison doesn't allocate anything that needs to live across parser calls,
      19                 :  * so we can easily have it use palloc instead of malloc.  This prevents
      20                 :  * memory leaks if we error out during parsing.
      21                 :  */
      22                 : #define YYMALLOC palloc
      23                 : #define YYFREE   pfree
      24                 : 
      25                 : static int item_count(const char *s, char delim);
      26                 : static bool write_box(int dim, char *str1, char *str2,
      27                 :                       NDBOX **result, struct Node *escontext);
      28                 : static bool write_point_as_box(int dim, char *str,
      29                 :                                NDBOX **result, struct Node *escontext);
      30                 : 
      31                 : %}
      32                 : 
      33                 : /* BISON Declarations */
      34                 : %parse-param {NDBOX **result}
      35                 : %parse-param {Size scanbuflen}
      36                 : %parse-param {struct Node *escontext}
      37                 : %expect 0
      38                 : %name-prefix="cube_yy"
      39                 : 
      40                 : %token CUBEFLOAT O_PAREN C_PAREN O_BRACKET C_BRACKET COMMA
      41                 : %start box
      42                 : 
      43                 : /* Grammar follows */
      44                 : %%
      45                 : 
      46                 : box: O_BRACKET paren_list COMMA paren_list C_BRACKET
      47                 :     {
      48                 :         int         dim;
      49                 : 
      50 CBC          16 :         dim = item_count($2, ',');
      51              16 :         if (item_count($4, ',') != dim)
      52                 :         {
      53 GNC           2 :             errsave(escontext,
      54                 :                     (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
      55                 :                      errmsg("invalid input syntax for cube"),
      56                 :                      errdetail("Different point dimensions in (%s) and (%s).",
      57                 :                                $2, $4)));
      58 UBC           0 :             YYABORT;
      59                 :         }
      60 CBC          14 :         if (dim > CUBE_MAX_DIM)
      61                 :         {
      62 UNC           0 :             errsave(escontext,
      63                 :                     (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
      64                 :                      errmsg("invalid input syntax for cube"),
      65                 :                      errdetail("A cube cannot have more than %d dimensions.",
      66                 :                                CUBE_MAX_DIM)));
      67 UBC           0 :             YYABORT;
      68                 :         }
      69                 : 
      70 GNC          14 :         if (!write_box(dim, $2, $4, result, escontext))
      71 UNC           0 :             YYABORT;
      72 EUB             :     }
      73                 : 
      74                 :     | paren_list COMMA paren_list
      75                 :     {
      76                 :         int         dim;
      77                 : 
      78 GIC        3246 :         dim = item_count($1, ',');
      79 CBC        3246 :         if (item_count($3, ',') != dim)
      80 ECB             :         {
      81 GNC           2 :             errsave(escontext,
      82 ECB             :                     (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
      83                 :                      errmsg("invalid input syntax for cube"),
      84                 :                      errdetail("Different point dimensions in (%s) and (%s).",
      85                 :                                $1, $3)));
      86 UIC           0 :             YYABORT;
      87 EUB             :         }
      88 GIC        3244 :         if (dim > CUBE_MAX_DIM)
      89 ECB             :         {
      90 GNC           1 :             errsave(escontext,
      91 ECB             :                     (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
      92                 :                      errmsg("invalid input syntax for cube"),
      93                 :                      errdetail("A cube cannot have more than %d dimensions.",
      94                 :                                CUBE_MAX_DIM)));
      95 UIC           0 :             YYABORT;
      96 EUB             :         }
      97                 : 
      98 GNC        3243 :         if (!write_box(dim, $1, $3, result, escontext))
      99 UNC           0 :             YYABORT;
     100 ECB             :     }
     101 EUB             : 
     102                 :     | paren_list
     103                 :     {
     104                 :         int         dim;
     105                 : 
     106 GIC          69 :         dim = item_count($1, ',');
     107              69 :         if (dim > CUBE_MAX_DIM)
     108 ECB             :         {
     109 GNC           1 :             errsave(escontext,
     110                 :                     (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
     111 ECB             :                      errmsg("invalid input syntax for cube"),
     112                 :                      errdetail("A cube cannot have more than %d dimensions.",
     113                 :                                CUBE_MAX_DIM)));
     114 UIC           0 :             YYABORT;
     115                 :         }
     116 EUB             : 
     117 GNC          68 :         if (!write_point_as_box(dim, $1, result, escontext))
     118 UNC           0 :             YYABORT;
     119                 :     }
     120 ECB             : 
     121 EUB             :     | list
     122                 :     {
     123                 :         int         dim;
     124                 : 
     125 GIC          89 :         dim = item_count($1, ',');
     126              89 :         if (dim > CUBE_MAX_DIM)
     127                 :         {
     128 UNC           0 :             errsave(escontext,
     129 ECB             :                     (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
     130                 :                      errmsg("invalid input syntax for cube"),
     131 EUB             :                      errdetail("A cube cannot have more than %d dimensions.",
     132                 :                                CUBE_MAX_DIM)));
     133 UIC           0 :             YYABORT;
     134                 :         }
     135                 : 
     136 GNC          89 :         if (!write_point_as_box(dim, $1, result, escontext))
     137               2 :             YYABORT;
     138                 :     }
     139                 :     ;
     140 ECB             : 
     141                 : paren_list: O_PAREN list C_PAREN
     142                 :     {
     143 GIC        6596 :         $$ = $2;
     144                 :     }
     145                 :     | O_PAREN C_PAREN
     146                 :     {
     147 CBC           4 :         $$ = pstrdup("");
     148                 :     }
     149                 :     ;
     150                 : 
     151 ECB             : list: CUBEFLOAT
     152                 :     {
     153                 :         /* alloc enough space to be sure whole list will fit */
     154 GIC        6691 :         $$ = palloc(scanbuflen + 1);
     155            6691 :         strcpy($$, $1);
     156                 :     }
     157                 :     | list COMMA CUBEFLOAT
     158 ECB             :     {
     159 CBC        7368 :         $$ = $1;
     160 GIC        7368 :         strcat($$, ",");
     161            7368 :         strcat($$, $3);
     162                 :     }
     163 ECB             :     ;
     164                 : 
     165                 : %%
     166                 : 
     167                 : /* This assumes the string has been normalized by productions above */
     168                 : static int
     169 GIC        6682 : item_count(const char *s, char delim)
     170                 : {
     171            6682 :     int         nitems = 0;
     172                 : 
     173 CBC        6682 :     if (s[0] != '\0')
     174                 :     {
     175            6679 :         nitems++;
     176 GIC       14045 :         while ((s = strchr(s, delim)) != NULL)
     177 ECB             :         {
     178 GIC        7366 :             nitems++;
     179 CBC        7366 :             s++;
     180 ECB             :         }
     181                 :     }
     182 CBC        6682 :     return nitems;
     183 ECB             : }
     184                 : 
     185                 : static bool
     186 GNC        3257 : write_box(int dim, char *str1, char *str2,
     187                 :           NDBOX **result, struct Node *escontext)
     188                 : {
     189                 :     NDBOX      *bp;
     190                 :     char       *s;
     191 ECB             :     char       *endptr;
     192                 :     int         i;
     193 GIC        3257 :     int         size = CUBE_SIZE(dim);
     194            3257 :     bool        point = true;
     195                 : 
     196            3257 :     bp = palloc0(size);
     197            3257 :     SET_VARSIZE(bp, size);
     198 CBC        3257 :     SET_DIM(bp, dim);
     199 ECB             : 
     200 GIC        3257 :     s = str1;
     201 CBC        3257 :     i = 0;
     202            3257 :     if (dim > 0)
     203                 :     {
     204 GNC        3256 :         bp->x[i++] = float8in_internal(s, &endptr, "cube", str1, escontext);
     205            3256 :         if (SOFT_ERROR_OCCURRED(escontext))
     206 UNC           0 :             return false;
     207                 :     }
     208 GIC        6576 :     while ((s = strchr(s, ',')) != NULL)
     209 ECB             :     {
     210 CBC        3319 :         s++;
     211 GNC        3319 :         bp->x[i++] = float8in_internal(s, &endptr, "cube", str1, escontext);
     212            3319 :         if (SOFT_ERROR_OCCURRED(escontext))
     213 UNC           0 :             return false;
     214                 :     }
     215 CBC        3257 :     Assert(i == dim);
     216 ECB             : 
     217 GBC        3257 :     s = str2;
     218 GIC        3257 :     if (dim > 0)
     219 ECB             :     {
     220 GNC        3256 :         bp->x[i] = float8in_internal(s, &endptr, "cube", str2, escontext);
     221            3256 :         if (SOFT_ERROR_OCCURRED(escontext))
     222 UNC           0 :             return false;
     223 ECB             :         /* code this way to do right thing with NaN */
     224 CBC        3256 :         point &= (bp->x[i] == bp->x[0]);
     225            3256 :         i++;
     226 EUB             :     }
     227 GIC        6576 :     while ((s = strchr(s, ',')) != NULL)
     228 ECB             :     {
     229 GIC        3319 :         s++;
     230 GNC        3319 :         bp->x[i] = float8in_internal(s, &endptr, "cube", str2, escontext);
     231            3319 :         if (SOFT_ERROR_OCCURRED(escontext))
     232 UNC           0 :             return false;
     233 CBC        3319 :         point &= (bp->x[i] == bp->x[i - dim]);
     234 GIC        3319 :         i++;
     235 ECB             :     }
     236 CBC        3257 :     Assert(i == dim * 2);
     237 EUB             : 
     238 GIC        3257 :     if (point)
     239 ECB             :     {
     240                 :         /*
     241                 :          * The value turned out to be a point, ie. all the upper-right
     242                 :          * coordinates were equal to the lower-left coordinates. Resize the
     243                 :          * cube we constructed.  Note: we don't bother to repalloc() it
     244                 :          * smaller, as it's unlikely that the tiny amount of memory freed
     245                 :          * that way would be useful, and the output is always short-lived.
     246                 :          */
     247 GBC          25 :         size = POINT_SIZE(dim);
     248 CBC          25 :         SET_VARSIZE(bp, size);
     249              25 :         SET_POINT_BIT(bp);
     250                 :     }
     251 ECB             : 
     252 GNC        3257 :     *result = bp;
     253            3257 :     return true;
     254 ECB             : }
     255                 : 
     256                 : static bool
     257 GNC         157 : write_point_as_box(int dim, char *str,
     258                 :                    NDBOX **result, struct Node *escontext)
     259                 : {
     260                 :     NDBOX       *bp;
     261                 :     int         i,
     262                 :                 size;
     263                 :     char       *s;
     264 ECB             :     char       *endptr;
     265                 : 
     266 CBC         157 :     size = POINT_SIZE(dim);
     267 GIC         157 :     bp = palloc0(size);
     268             157 :     SET_VARSIZE(bp, size);
     269 CBC         157 :     SET_DIM(bp, dim);
     270             157 :     SET_POINT_BIT(bp);
     271                 : 
     272 GIC         157 :     s = str;
     273             157 :     i = 0;
     274 CBC         157 :     if (dim > 0)
     275                 :     {
     276 GNC         156 :         bp->x[i++] = float8in_internal(s, &endptr, "cube", str, escontext);
     277             155 :         if (SOFT_ERROR_OCCURRED(escontext))
     278               2 :             return false;
     279                 :     }
     280 GIC         276 :     while ((s = strchr(s, ',')) != NULL)
     281                 :     {
     282             122 :         s++;
     283 GNC         122 :         bp->x[i++] = float8in_internal(s, &endptr, "cube", str, escontext);
     284             122 :         if (SOFT_ERROR_OCCURRED(escontext))
     285 UNC           0 :             return false;
     286                 :     }
     287 GIC         154 :     Assert(i == dim);
     288                 : 
     289 GNC         154 :     *result = bp;
     290             154 :     return true;
     291 ECB             : }
        

Generated by: LCOV version v1.16-55-g56c0a2a