LCOV - code coverage report
Current view: top level - contrib/cube - cubeparse.y (source / functions) Coverage Total Hit
Test: Code coverage Lines: 0.0 % 83 0
Test Date: 2026-01-26 10:56:24 Functions: 0.0 % 3 0
Legend: Lines:     hit not hit

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

Generated by: LCOV version 2.3.2-1