]> granicus.if.org Git - postgresql/commitdiff
Make contrib/cube work with flex 2.5.31. Fix it up to have a real
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 14 Sep 2003 01:52:25 +0000 (01:52 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 14 Sep 2003 01:52:25 +0000 (01:52 +0000)
btree operator class, too, since in PG 7.4 you can't GROUP without one.

contrib/cube/Makefile
contrib/cube/README.cube
contrib/cube/buffer.c [deleted file]
contrib/cube/buffer.h [deleted file]
contrib/cube/cube.c
contrib/cube/cube.sql.in
contrib/cube/cubeparse.y
contrib/cube/cubescan.l
contrib/cube/expected/cube.out

index 6c5570505cb4166609c385252702d1717508b6ff..80e56aa7f880d23f3e02894cd61051adf33a454a 100644 (file)
@@ -1,11 +1,11 @@
-# $Header: /cvsroot/pgsql/contrib/cube/Makefile,v 1.9 2003/05/14 03:27:21 tgl Exp $
+# $Header: /cvsroot/pgsql/contrib/cube/Makefile,v 1.10 2003/09/14 01:52:25 tgl Exp $
 
 subdir = contrib/cube
 top_builddir = ../..
 include $(top_builddir)/src/Makefile.global
 
 MODULE_big = cube
-OBJS= cube.o cubeparse.o buffer.o
+OBJS= cube.o cubeparse.o
 
 DATA_built = cube.sql
 DOCS = README.cube
@@ -28,7 +28,7 @@ endif
 
 cubescan.c: cubescan.l
 ifdef FLEX
-       $(FLEX) $(FLEXFLAGS) -Pcube_yy -o'$@' $<
+       $(FLEX) $(FLEXFLAGS) -o'$@' $<
 else
        @$(missing) flex $< $@
 endif
index 42b84fb0611f65bd385e7da77c1db0fe7d6dc6ec..c4ad7b33b5ac739fdf1597bcb3fbe9c930335ec8 100644 (file)
@@ -9,11 +9,6 @@ Makefile               building instructions for the shared library
 
 README.cube            the file you are now reading
 
-buffer.c               globals and buffer access utilities shared between 
-                       the parser (cubeparse.y) and the scanner (cubescan.l)
-
-buffer.h               function prototypes for buffer.c
-
 cube.c                 the implementation of this data type in c
 
 cube.sql.in            SQL code needed to register this type with postgres
diff --git a/contrib/cube/buffer.c b/contrib/cube/buffer.c
deleted file mode 100644 (file)
index 3a1b728..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/* This module defines the parse buffer and routines for setting/reading it */
-
-#include "postgres.h"
-
-static char *PARSE_BUFFER;
-static char *PARSE_BUFFER_PTR;
-static unsigned int PARSE_BUFFER_SIZE;
-static unsigned int SCANNER_POS;
-
-void           set_parse_buffer(char *s);
-void           reset_parse_buffer(void);
-int                    read_parse_buffer(void);
-char      *parse_buffer(void);
-char      *parse_buffer_ptr(void);
-unsigned int parse_buffer_curr_char(void);
-unsigned int parse_buffer_size(void);
-unsigned int parse_buffer_pos(void);
-
-extern void cube_flush_scanner_buffer(void);   /* defined in cubescan.l */
-
-void
-set_parse_buffer(char *s)
-{
-       PARSE_BUFFER = s;
-       PARSE_BUFFER_SIZE = strlen(s);
-       if (PARSE_BUFFER_SIZE == 0)
-               ereport(ERROR,
-                               (errcode(ERRCODE_ZERO_LENGTH_CHARACTER_STRING),
-                                errmsg("can't parse an empty string")));
-
-       PARSE_BUFFER_PTR = PARSE_BUFFER;
-       SCANNER_POS = 0;
-}
-
-void
-reset_parse_buffer(void)
-{
-       PARSE_BUFFER_PTR = PARSE_BUFFER;
-       SCANNER_POS = 0;
-       cube_flush_scanner_buffer();
-}
-
-int
-read_parse_buffer(void)
-{
-       int                     c;
-
-       /*
-        * c = *PARSE_BUFFER_PTR++; SCANNER_POS++;
-        */
-       c = PARSE_BUFFER[SCANNER_POS];
-       if (SCANNER_POS < PARSE_BUFFER_SIZE)
-               SCANNER_POS++;
-       return c;
-}
-
-char *
-parse_buffer(void)
-{
-       return PARSE_BUFFER;
-}
-
-unsigned int
-parse_buffer_curr_char(void)
-{
-       return PARSE_BUFFER[SCANNER_POS];
-}
-
-char *
-parse_buffer_ptr(void)
-{
-       return PARSE_BUFFER_PTR;
-}
-
-unsigned int
-parse_buffer_pos(void)
-{
-       return SCANNER_POS;
-}
-
-unsigned int
-parse_buffer_size(void)
-{
-       return PARSE_BUFFER_SIZE;
-}
diff --git a/contrib/cube/buffer.h b/contrib/cube/buffer.h
deleted file mode 100644 (file)
index eef9124..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-extern void set_parse_buffer(char *s);
-extern void reset_parse_buffer(void);
-extern int     read_parse_buffer(void);
-extern char *parse_buffer(void);
-extern char *parse_buffer_ptr(void);
-extern unsigned int parse_buffer_curr_char(void);
-extern unsigned int parse_buffer_pos(void);
-extern unsigned int parse_buffer_size(void);
index 396253261d95f57d4c4205f14720dc5b7a0a7cfa..15fce4f1f7d6c56554dd0c674cda11f0a7a55e8b 100644 (file)
 #define min(a,b)               ((a) <= (b) ? (a) : (b))
 #define abs(a)                 ((a) <  (0) ? (-a) : (a))
 
-extern void set_parse_buffer(char *str);
 extern int     cube_yyparse();
+extern void cube_yyerror(const char *message);
+extern void cube_scanner_init(const char *str);
+extern void cube_scanner_finish(void);
 
 /*
 ** Input/Output routines
@@ -51,11 +53,20 @@ NDBOX          *g_cube_union(bytea *entryvec, int *sizep);
 NDBOX     *g_cube_binary_union(NDBOX * r1, NDBOX * r2, int *sizep);
 bool      *g_cube_same(NDBOX * b1, NDBOX * b2, bool *result);
 
+/*
+** B-tree support functions
+*/
+bool           cube_eq(NDBOX * a, NDBOX * b);
+bool           cube_ne(NDBOX * a, NDBOX * b);
+bool           cube_lt(NDBOX * a, NDBOX * b);
+bool           cube_gt(NDBOX * a, NDBOX * b);
+bool           cube_le(NDBOX * a, NDBOX * b);
+bool           cube_ge(NDBOX * a, NDBOX * b);
+int32          cube_cmp(NDBOX * a, NDBOX * b);
+
 /*
 ** R-tree support functions
 */
-bool           cube_same(NDBOX * a, NDBOX * b);
-bool           cube_different(NDBOX * a, NDBOX * b);
 bool           cube_contains(NDBOX * a, NDBOX * b);
 bool           cube_contained(NDBOX * a, NDBOX * b);
 bool           cube_overlap(NDBOX * a, NDBOX * b);
@@ -99,10 +110,12 @@ cube_in(char *str)
 {
        void       *result;
 
-       set_parse_buffer(str);
+       cube_scanner_init(str);
 
        if (cube_yyparse(&result) != 0)
-               return NULL;
+               cube_yyerror("bogus input");
+
+       cube_scanner_finish();
 
        return ((NDBOX *) result);
 }
@@ -438,7 +451,7 @@ g_cube_picksplit(bytea *entryvec,
 bool *
 g_cube_same(NDBOX * b1, NDBOX * b2, bool *result)
 {
-       if (cube_same(b1, b2))
+       if (cube_eq(b1, b2))
                *result = TRUE;
        else
                *result = FALSE;
@@ -480,7 +493,7 @@ g_cube_leaf_consistent(NDBOX * key,
                        retval = (bool) cube_right(key, query);
                        break;
                case RTSameStrategyNumber:
-                       retval = (bool) cube_same(key, query);
+                       retval = (bool) cube_eq(key, query);
                        break;
                case RTContainsStrategyNumber:
                        retval = (bool) cube_contains(key, query);
@@ -754,15 +767,12 @@ cube_right(NDBOX * a, NDBOX * b)
 
 /* make up a metric in which one box will be 'lower' than the other
    -- this can be useful for sorting and to determine uniqueness */
-bool
-cube_lt(NDBOX * a, NDBOX * b)
+int32
+cube_cmp(NDBOX * a, NDBOX * b)
 {
        int                     i;
        int                     dim;
 
-       if ((a == NULL) || (b == NULL))
-               return (FALSE);
-
        dim = min(a->dim, b->dim);
 
        /* compare the common dimensions */
@@ -770,19 +780,19 @@ cube_lt(NDBOX * a, NDBOX * b)
        {
                if (min(a->x[i], a->x[a->dim + i]) >
                        min(b->x[i], b->x[b->dim + i]))
-                       return (FALSE);
+                       return 1;
                if (min(a->x[i], a->x[a->dim + i]) <
                        min(b->x[i], b->x[b->dim + i]))
-                       return (TRUE);
+                       return -1;
        }
        for (i = 0; i < dim; i++)
        {
                if (max(a->x[i], a->x[a->dim + i]) >
                        max(b->x[i], b->x[b->dim + i]))
-                       return (FALSE);
+                       return 1;
                if (max(a->x[i], a->x[a->dim + i]) <
                        max(b->x[i], b->x[b->dim + i]))
-                       return (TRUE);
+                       return -1;
        }
 
        /* compare extra dimensions to zero */
@@ -791,186 +801,87 @@ cube_lt(NDBOX * a, NDBOX * b)
                for (i = dim; i < a->dim; i++)
                {
                        if (min(a->x[i], a->x[a->dim + i]) > 0)
-                               return (FALSE);
+                               return 1;
                        if (min(a->x[i], a->x[a->dim + i]) < 0)
-                               return (TRUE);
+                               return -1;
                }
                for (i = dim; i < a->dim; i++)
                {
                        if (max(a->x[i], a->x[a->dim + i]) > 0)
-                               return (FALSE);
+                               return 1;
                        if (max(a->x[i], a->x[a->dim + i]) < 0)
-                               return (TRUE);
+                               return -1;
                }
 
                /*
                 * if all common dimensions are equal, the cube with more
                 * dimensions wins
                 */
-               return (FALSE);
+               return 1;
        }
        if (a->dim < b->dim)
        {
                for (i = dim; i < b->dim; i++)
                {
                        if (min(b->x[i], b->x[b->dim + i]) > 0)
-                               return (TRUE);
+                               return -1;
                        if (min(b->x[i], b->x[b->dim + i]) < 0)
-                               return (FALSE);
+                               return 1;
                }
                for (i = dim; i < b->dim; i++)
                {
                        if (max(b->x[i], b->x[b->dim + i]) > 0)
-                               return (TRUE);
+                               return -1;
                        if (max(b->x[i], b->x[b->dim + i]) < 0)
-                               return (FALSE);
+                               return 1;
                }
 
                /*
                 * if all common dimensions are equal, the cube with more
                 * dimensions wins
                 */
-               return (TRUE);
+               return -1;
        }
 
-       return (FALSE);
+       /* They're really equal */
+       return 0;
 }
 
 
 bool
-cube_gt(NDBOX * a, NDBOX * b)
+cube_eq(NDBOX * a, NDBOX * b)
 {
-       int                     i;
-       int                     dim;
-
-       if ((a == NULL) || (b == NULL))
-               return (FALSE);
-
-       dim = min(a->dim, b->dim);
-
-       /* compare the common dimensions */
-       for (i = 0; i < dim; i++)
-       {
-               if (min(a->x[i], a->x[a->dim + i]) <
-                       min(b->x[i], b->x[b->dim + i]))
-                       return (FALSE);
-               if (min(a->x[i], a->x[a->dim + i]) >
-                       min(b->x[i], b->x[b->dim + i]))
-                       return (TRUE);
-       }
-       for (i = 0; i < dim; i++)
-       {
-               if (max(a->x[i], a->x[a->dim + i]) <
-                       max(b->x[i], b->x[b->dim + i]))
-                       return (FALSE);
-               if (max(a->x[i], a->x[a->dim + i]) >
-                       max(b->x[i], b->x[b->dim + i]))
-                       return (TRUE);
-       }
-
-
-       /* compare extra dimensions to zero */
-       if (a->dim > b->dim)
-       {
-               for (i = dim; i < a->dim; i++)
-               {
-                       if (min(a->x[i], a->x[a->dim + i]) < 0)
-                               return (FALSE);
-                       if (min(a->x[i], a->x[a->dim + i]) > 0)
-                               return (TRUE);
-               }
-               for (i = dim; i < a->dim; i++)
-               {
-                       if (max(a->x[i], a->x[a->dim + i]) < 0)
-                               return (FALSE);
-                       if (max(a->x[i], a->x[a->dim + i]) > 0)
-                               return (TRUE);
-               }
-
-               /*
-                * if all common dimensions are equal, the cube with more
-                * dimensions wins
-                */
-               return (TRUE);
-       }
-       if (a->dim < b->dim)
-       {
-               for (i = dim; i < b->dim; i++)
-               {
-                       if (min(b->x[i], b->x[b->dim + i]) < 0)
-                               return (TRUE);
-                       if (min(b->x[i], b->x[b->dim + i]) > 0)
-                               return (FALSE);
-               }
-               for (i = dim; i < b->dim; i++)
-               {
-                       if (max(b->x[i], b->x[b->dim + i]) < 0)
-                               return (TRUE);
-                       if (max(b->x[i], b->x[b->dim + i]) > 0)
-                               return (FALSE);
-               }
-
-               /*
-                * if all common dimensions are equal, the cube with more
-                * dimensions wins
-                */
-               return (FALSE);
-       }
-
-       return (FALSE);
+       return (cube_cmp(a, b) == 0);
 }
 
-
-/* Equal */
 bool
-cube_same(NDBOX * a, NDBOX * b)
+cube_ne(NDBOX * a, NDBOX * b)
 {
-       int                     i;
-
-       if ((a == NULL) || (b == NULL))
-               return (FALSE);
-
-       /* swap the box pointers if necessary */
-       if (a->dim < b->dim)
-       {
-               NDBOX      *tmp = b;
-
-               b = a;
-               a = tmp;
-       }
+       return (cube_cmp(a, b) != 0);
+}
 
-       for (i = 0; i < b->dim; i++)
-       {
-               if (min(a->x[i], a->x[a->dim + i]) !=
-                       min(b->x[i], b->x[b->dim + i]))
-                       return (FALSE);
-               if (max(a->x[i], a->x[a->dim + i]) !=
-                       max(b->x[i], b->x[b->dim + i]))
-                       return (FALSE);
-       }
+bool
+cube_lt(NDBOX * a, NDBOX * b)
+{
+       return (cube_cmp(a, b) < 0);
+}
 
-       /*
-        * all dimensions of (b) are compared to those of (a); instead of
-        * those in (a) absent in (b), compare (a) to zero Since both LL and
-        * UR coordinates are compared to zero, we can just check them all
-        * without worrying about which is which.
-        */
-       for (i = b->dim; i < a->dim; i++)
-       {
-               if (a->x[i] != 0)
-                       return (FALSE);
-               if (a->x[i + a->dim] != 0)
-                       return (FALSE);
-       }
+bool
+cube_gt(NDBOX * a, NDBOX * b)
+{
+       return (cube_cmp(a, b) > 0);
+}
 
-       return (TRUE);
+bool
+cube_le(NDBOX * a, NDBOX * b)
+{
+       return (cube_cmp(a, b) <= 0);
 }
 
-/* Different */
 bool
-cube_different(NDBOX * a, NDBOX * b)
+cube_ge(NDBOX * a, NDBOX * b)
 {
-       return (!cube_same(a, b));
+       return (cube_cmp(a, b) >= 0);
 }
 
 
index 6afcce5aeba6676e9c012fe04e72c30988fe8545..b9b812f5814460b62cbe976d13a12c5dbb6bdb1d 100644 (file)
@@ -70,6 +70,20 @@ COMMENT ON FUNCTION cube_right(cube, cube) IS 'is right of (NOT IMPLEMENTED)';
 
 -- Comparison methods
 
+CREATE OR REPLACE FUNCTION cube_eq(cube, cube)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE 'C' IMMUTABLE STRICT;
+
+COMMENT ON FUNCTION cube_eq(cube, cube) IS 'same as';
+
+CREATE OR REPLACE FUNCTION cube_ne(cube, cube)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE 'C' IMMUTABLE STRICT;
+
+COMMENT ON FUNCTION cube_ne(cube, cube) IS 'different';
+
 CREATE OR REPLACE FUNCTION cube_lt(cube, cube)
 RETURNS bool
 AS 'MODULE_PATHNAME'
@@ -84,40 +98,47 @@ LANGUAGE 'C' IMMUTABLE STRICT;
 
 COMMENT ON FUNCTION cube_gt(cube, cube) IS 'greater than';
 
-CREATE OR REPLACE FUNCTION cube_contains(cube, cube)
+CREATE OR REPLACE FUNCTION cube_le(cube, cube)
 RETURNS bool
 AS 'MODULE_PATHNAME'
 LANGUAGE 'C' IMMUTABLE STRICT;
 
-COMMENT ON FUNCTION cube_contains(cube, cube) IS 'contains';
+COMMENT ON FUNCTION cube_le(cube, cube) IS 'lower than or equal to';
 
-CREATE OR REPLACE FUNCTION cube_contained(cube, cube)
+CREATE OR REPLACE FUNCTION cube_ge(cube, cube)
 RETURNS bool
 AS 'MODULE_PATHNAME'
 LANGUAGE 'C' IMMUTABLE STRICT;
 
-COMMENT ON FUNCTION cube_contained(cube, cube) IS 'contained in';
+COMMENT ON FUNCTION cube_ge(cube, cube) IS 'greater than or equal to';
 
-CREATE OR REPLACE FUNCTION cube_overlap(cube, cube)
+CREATE OR REPLACE FUNCTION cube_cmp(cube, cube)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE 'C' IMMUTABLE STRICT;
+
+COMMENT ON FUNCTION cube_cmp(cube, cube) IS 'btree comparison function';
+
+CREATE OR REPLACE FUNCTION cube_contains(cube, cube)
 RETURNS bool
 AS 'MODULE_PATHNAME'
 LANGUAGE 'C' IMMUTABLE STRICT;
 
-COMMENT ON FUNCTION cube_overlap(cube, cube) IS 'overlaps';
+COMMENT ON FUNCTION cube_contains(cube, cube) IS 'contains';
 
-CREATE OR REPLACE FUNCTION cube_same(cube, cube)
+CREATE OR REPLACE FUNCTION cube_contained(cube, cube)
 RETURNS bool
 AS 'MODULE_PATHNAME'
 LANGUAGE 'C' IMMUTABLE STRICT;
 
-COMMENT ON FUNCTION cube_same(cube, cube) IS 'same as';
+COMMENT ON FUNCTION cube_contained(cube, cube) IS 'contained in';
 
-CREATE OR REPLACE FUNCTION cube_different(cube, cube)
+CREATE OR REPLACE FUNCTION cube_overlap(cube, cube)
 RETURNS bool
 AS 'MODULE_PATHNAME'
 LANGUAGE 'C' IMMUTABLE STRICT;
 
-COMMENT ON FUNCTION cube_different(cube, cube) IS 'different';
+COMMENT ON FUNCTION cube_overlap(cube, cube) IS 'overlaps';
 
 -- support routines for indexing
 
@@ -199,13 +220,25 @@ LANGUAGE 'C' IMMUTABLE STRICT;
 
 CREATE OPERATOR < (
        LEFTARG = cube, RIGHTARG = cube, PROCEDURE = cube_lt,
-       COMMUTATOR = '>',
+       COMMUTATOR = '>', NEGATOR = '>=',
        RESTRICT = scalarltsel, JOIN = scalarltjoinsel
 );
 
 CREATE OPERATOR > (
        LEFTARG = cube, RIGHTARG = cube, PROCEDURE = cube_gt,
-       COMMUTATOR = '<',
+       COMMUTATOR = '<', NEGATOR = '<=',
+       RESTRICT = scalargtsel, JOIN = scalargtjoinsel
+);
+
+CREATE OPERATOR <= (
+       LEFTARG = cube, RIGHTARG = cube, PROCEDURE = cube_le,
+       COMMUTATOR = '>=', NEGATOR = '>',
+       RESTRICT = scalarltsel, JOIN = scalarltjoinsel
+);
+
+CREATE OPERATOR >= (
+       LEFTARG = cube, RIGHTARG = cube, PROCEDURE = cube_ge,
+       COMMUTATOR = '<=', NEGATOR = '<',
        RESTRICT = scalargtsel, JOIN = scalargtjoinsel
 );
 
@@ -240,14 +273,14 @@ CREATE OPERATOR >> (
 );
 
 CREATE OPERATOR = (
-       LEFTARG = cube, RIGHTARG = cube, PROCEDURE = cube_same,
+       LEFTARG = cube, RIGHTARG = cube, PROCEDURE = cube_eq,
        COMMUTATOR = '=', NEGATOR = '<>',
        RESTRICT = eqsel, JOIN = eqjoinsel,
-       SORT1 = '<', SORT2 = '<'
+       MERGES
 );
 
 CREATE OPERATOR <> (
-       LEFTARG = cube, RIGHTARG = cube, PROCEDURE = cube_different,
+       LEFTARG = cube, RIGHTARG = cube, PROCEDURE = cube_ne,
        COMMUTATOR = '<>', NEGATOR = '=',
        RESTRICT = neqsel, JOIN = neqjoinsel
 );
@@ -302,7 +335,16 @@ AS 'MODULE_PATHNAME'
 LANGUAGE 'C';
 
 
--- Create the operator class for indexing
+-- Create the operator classes for indexing
+
+CREATE OPERATOR CLASS cube_ops
+    DEFAULT FOR TYPE cube USING btree AS
+        OPERATOR        1       < ,
+        OPERATOR        2       <= ,
+        OPERATOR        3       = ,
+        OPERATOR        4       >= ,
+        OPERATOR        5       > ,
+        FUNCTION        1       cube_cmp(cube, cube);
 
 CREATE OPERATOR CLASS gist_cube_ops
     DEFAULT FOR TYPE cube USING gist AS
index 917d84079e3c24e95dd830d475172bdacca7fd06..e996a488c62300b3d743a3cfebd7caa524142994 100644 (file)
@@ -9,7 +9,6 @@
 #include "postgres.h"
 
 #include "cubedata.h"
-#include "buffer.h"
 
 #undef yylex                 /* falure to redefine yylex will result in a call to  the */
 #define yylex cube_yylex     /* wrong scanner when running inside the postgres backend  */
 extern int yylex();           /* defined as cube_yylex in cubescan.c */
 extern int errno;
 
-int cube_yyerror( char *msg );
+static char *scanbuf;
+static int     scanbuflen;
+
+void cube_yyerror(const char *message);
 int cube_yyparse(void *result);
 
 static int delim_count(char *s, char delim);
@@ -37,25 +39,9 @@ box:
           O_BRACKET paren_list COMMA paren_list C_BRACKET {
 
            int dim;
-           int c = parse_buffer_curr_char();
-           int pos = parse_buffer_pos();
-
-           /* We can't let the parser recognize more than one valid expression:
-              the job is done and memory is allocated. */
-           if ( c != '\0' ) {
-             /* Not at EOF */
-             reset_parse_buffer();     
-          ereport(ERROR,
-                  (errcode(ERRCODE_SYNTAX_ERROR),
-                   errmsg("bad cube representation"),
-                   errdetail("garbage at or before char %d, ('%c', \\%03o)",
-                             pos, c, c)));
-             YYERROR;
-           }
            
            dim = delim_count($2, ',') + 1;
            if ( (delim_count($4, ',') + 1) != dim ) {
-             reset_parse_buffer();     
           ereport(ERROR,
                   (errcode(ERRCODE_SYNTAX_ERROR),
                    errmsg("bad cube representation"),
@@ -64,7 +50,6 @@ box:
              YYABORT;
            }
            if (dim > CUBE_MAX_DIM) {
-              reset_parse_buffer();
               ereport(ERROR,
                       (errcode(ERRCODE_SYNTAX_ERROR),
                        errmsg("bad cube representation"),
@@ -79,23 +64,10 @@ box:
       |
           paren_list COMMA paren_list {
            int dim;
-           int c = parse_buffer_curr_char();
-           int pos = parse_buffer_pos();
-
-           if ( c != '\0' ) {  /* Not at EOF */
-             reset_parse_buffer();     
-          ereport(ERROR,
-                  (errcode(ERRCODE_SYNTAX_ERROR),
-                   errmsg("bad cube representation"),
-                   errdetail("garbage at or before char %d, ('%c', \\%03o)",
-                             pos, c, c)));
-             YYABORT;
-           }
 
            dim = delim_count($1, ',') + 1;
            
            if ( (delim_count($3, ',') + 1) != dim ) {
-             reset_parse_buffer();     
           ereport(ERROR,
                   (errcode(ERRCODE_SYNTAX_ERROR),
                    errmsg("bad cube representation"),
@@ -104,7 +76,6 @@ box:
              YYABORT;
            }
            if (dim > CUBE_MAX_DIM) {
-              reset_parse_buffer();
               ereport(ERROR,
                       (errcode(ERRCODE_SYNTAX_ERROR),
                        errmsg("bad cube representation"),
@@ -119,33 +90,9 @@ box:
 
           paren_list {
             int dim;
-           int c = parse_buffer_curr_char();
-           int pos = parse_buffer_pos();
-
-           if ( c != '\0') {  /* Not at EOF */
-             reset_parse_buffer();     
-          ereport(ERROR,
-                  (errcode(ERRCODE_SYNTAX_ERROR),
-                   errmsg("bad cube representation"),
-                   errdetail("garbage at or before char %d, ('%c', \\%03o)",
-                             pos, c, c)));
-             YYABORT;
-           }
-
-           if ( yychar != YYEOF) {
-             /* There's still a lookahead token to be parsed */
-             reset_parse_buffer();     
-          ereport(ERROR,
-                  (errcode(ERRCODE_SYNTAX_ERROR),
-                   errmsg("bad cube representation"),
-                   errdetail("garbage at or before char %d, ('end of input', \\%03o)",
-                             pos, c)));
-             YYABORT;
-           }
 
             dim = delim_count($1, ',') + 1;
            if (dim > CUBE_MAX_DIM) {
-              reset_parse_buffer();
               ereport(ERROR,
                       (errcode(ERRCODE_SYNTAX_ERROR),
                        errmsg("bad cube representation"),
@@ -161,33 +108,9 @@ box:
 
           list {
             int dim;
-           int c = parse_buffer_curr_char();
-           int pos = parse_buffer_pos();
-
-           if ( c != '\0') {  /* Not at EOF */
-             reset_parse_buffer();
-          ereport(ERROR,
-                  (errcode(ERRCODE_SYNTAX_ERROR),
-                   errmsg("bad cube representation"),
-                   errdetail("garbage at or before char %d, ('%c', \\%03o)",
-                             pos, c, c)));
-             YYABORT;
-           }
-
-           if ( yychar != YYEOF) {
-             /* There's still a lookahead token to be parsed */
-             reset_parse_buffer();
-          ereport(ERROR,
-                  (errcode(ERRCODE_SYNTAX_ERROR),
-                   errmsg("bad cube representation"),
-                   errdetail("garbage at or before char %d, ('end of input', \\%03o)",
-                             pos, c)));
-             YYABORT;
-           }
 
             dim = delim_count($1, ',') + 1;
            if (dim > CUBE_MAX_DIM) {
-              reset_parse_buffer();
               ereport(ERROR,
                       (errcode(ERRCODE_SYNTAX_ERROR),
                        errmsg("bad cube representation"),
@@ -207,8 +130,9 @@ paren_list:
 
 list:
           FLOAT {
-             $$ = palloc(strlen(parse_buffer()) + 1);
-            strcpy($$, $1);
+                        /* alloc enough space to be sure whole list will fit */
+             $$ = palloc(scanbuflen + 1);
+                        strcpy($$, $1);
          }
       | 
          list COMMA FLOAT {
@@ -220,39 +144,6 @@ list:
 
 %%
 
-
-int cube_yyerror ( char *msg ) {
-  char *buf = (char *) palloc(256);
-  int position;
-
-  yyclearin;
-
-  if ( !strcmp(msg, "parse error, expecting `$'") ) {
-    msg = "expecting end of input";
-  }
-
-  position = parse_buffer_pos() > parse_buffer_size() ? parse_buffer_pos() - 1 : parse_buffer_pos();
-
-  snprintf(
-         buf, 
-         256,
-         "%s at or before position %d, character ('%c', \\%03o), input: '%s'", 
-         msg,
-         position,
-         parse_buffer()[position - 1],
-         parse_buffer()[position - 1],
-         parse_buffer()
-         );
-
-  reset_parse_buffer();     
-  ereport(ERROR,
-          (errcode(ERRCODE_SYNTAX_ERROR),
-           errmsg("bad cube representation"),
-           errdetail("%s", buf)));
-
-  return 0;
-}
-
 static int
 delim_count(char *s, char delim)
 {
index 1b44397f460e35e7e8a6ea7cfd0cb90717ab377d..c5e1a20f6b19543baa9ed5578f176f298aa555c9 100644 (file)
@@ -5,33 +5,30 @@
 
 #include "postgres.h"
 
-#include "buffer.h"
+/* No reason to constrain amount of data slurped */
+#define YY_READ_BUF_SIZE 16777216
 
 /* Avoid exit() on fatal scanner errors (a bit ugly -- see yy_fatal_error) */
 #define fprintf(file, fmt, msg)  ereport(ERROR, (errmsg_internal("%s", msg)))
 
+/* Handles to the buffer that the lexer uses internally */
+static YY_BUFFER_STATE scanbufhandle;
+/* this is now declared in cubeparse.y: */
+/* static char *scanbuf; */
+/* static int  scanbuflen; */
 
-/* flex screws a couple symbols when used with the -P option; fix those */
-#define YY_DECL int cube_yylex YY_PROTO(( void )); \
-int cube_yylex YY_PROTO(( void ))
-#define yylval cube_yylval
+/* flex 2.5.4 doesn't bother with a decl for this */
+int cube_yylex(void);
 
-
-/* redefined YY_INPUT reads byte-wise from the memory area defined in buffer.c */
-#undef YY_INPUT
-#define YY_INPUT(buf,result,max_size) \
-{ \
-        int c = read_parse_buffer(); \
-        result = (c == '\0') ?  YY_NULL : (buf[0] = c, 1); \
-}
-
-void cube_flush_scanner_buffer(void); 
+void cube_scanner_init(const char *str);
+void cube_scanner_finish(void);
 %}
 
 %option 8bit
 %option never-interactive
 %option nounput
 %option noyywrap
+%option prefix="cube_yy"
 
 
 n            [0-9]+
@@ -52,8 +49,61 @@ float        ({integer}|{real})([eE]{integer})?
 
 %%
 
-int cube_yylex();
+void
+yyerror(const char *message)
+{
+       if (*yytext == YY_END_OF_BUFFER_CHAR)
+       {
+               ereport(ERROR,
+                               (errcode(ERRCODE_SYNTAX_ERROR),
+                                errmsg("bad cube representation"),
+                                /* translator: %s is typically "syntax error" */
+                                errdetail("%s at end of input", message)));
+       }
+       else
+       {
+               ereport(ERROR,
+                               (errcode(ERRCODE_SYNTAX_ERROR),
+                                errmsg("bad cube representation"),
+                                /* translator: first %s is typically "syntax error" */
+                                errdetail("%s at or near \"%s\"", message, yytext)));
+       }
+}
+
+
+/*
+ * Called before any actual parsing is done
+ */
+void
+cube_scanner_init(const char *str)
+{
+       Size    slen = strlen(str);
+
+       /*
+        * Might be left over after ereport()
+        */
+       if (YY_CURRENT_BUFFER)
+               yy_delete_buffer(YY_CURRENT_BUFFER);
+
+       /*
+        * Make a scan buffer with special termination needed by flex.
+        */
+       scanbuflen = slen;
+       scanbuf = palloc(slen + 2);
+       memcpy(scanbuf, str, slen);
+       scanbuf[slen] = scanbuf[slen + 1] = YY_END_OF_BUFFER_CHAR;
+       scanbufhandle = yy_scan_buffer(scanbuf, slen + 2);
+
+       BEGIN(INITIAL);
+}
+
 
-void cube_flush_scanner_buffer(void) {
-  YY_FLUSH_BUFFER;
+/*
+ * Called after parsing is done to clean up after cube_scanner_init()
+ */
+void
+cube_scanner_finish(void)
+{
+       yy_delete_buffer(scanbufhandle);
+       pfree(scanbuf);
 }
index 086d76fd0bfc4de39b4ad1a264baeb42c18d8801..367031e9835fefd09c2e4db355084861ebd51475 100644 (file)
@@ -257,53 +257,54 @@ SELECT '[(0,0,0,0),(1,0,0,0)]'::cube AS cube;
 
 -- invalid input: parse errors
 SELECT ''::cube AS cube;
-ERROR:  can't parse an empty string
+ERROR:  bad cube representation
+DETAIL:  syntax error at end of input
 SELECT 'ABC'::cube AS cube;
 ERROR:  bad cube representation
-DETAIL:  syntax error at or before position 1, character ('A', \101), input: 'ABC'
+DETAIL:  syntax error at or near "A"
 SELECT '()'::cube AS cube;
 ERROR:  bad cube representation
-DETAIL:  syntax error at or before position 2, character (')', \051), input: '()'
+DETAIL:  syntax error at or near ")"
 SELECT '[]'::cube AS cube;
 ERROR:  bad cube representation
-DETAIL:  syntax error at or before position 2, character (']', \135), input: '[]'
+DETAIL:  syntax error at or near "]"
 SELECT '[()]'::cube AS cube;
 ERROR:  bad cube representation
-DETAIL:  syntax error at or before position 3, character (')', \051), input: '[()]'
+DETAIL:  syntax error at or near ")"
 SELECT '[(1)]'::cube AS cube;
 ERROR:  bad cube representation
-DETAIL:  syntax error at or before position 5, character (']', \135), input: '[(1)]'
+DETAIL:  syntax error at or near "]"
 SELECT '[(1),]'::cube AS cube;
 ERROR:  bad cube representation
-DETAIL:  syntax error at or before position 6, character (']', \135), input: '[(1),]'
+DETAIL:  syntax error at or near "]"
 SELECT '[(1),2]'::cube AS cube;
 ERROR:  bad cube representation
-DETAIL:  syntax error at or before position 7, character (']', \135), input: '[(1),2]'
+DETAIL:  syntax error at or near "2"
 SELECT '[(1),(2),(3)]'::cube AS cube;
 ERROR:  bad cube representation
-DETAIL:  syntax error at or before position 9, character (',', \054), input: '[(1),(2),(3)]'
+DETAIL:  syntax error at or near ","
 SELECT '1,'::cube AS cube;
 ERROR:  bad cube representation
-DETAIL:  syntax error at or before position 2, character (',', \054), input: '1,'
+DETAIL:  syntax error at end of input
 SELECT '1,2,'::cube AS cube;
 ERROR:  bad cube representation
-DETAIL:  syntax error at or before position 4, character (',', \054), input: '1,2,'
+DETAIL:  syntax error at end of input
 SELECT '1,,2'::cube AS cube;
 ERROR:  bad cube representation
-DETAIL:  syntax error at or before position 3, character (',', \054), input: '1,,2'
+DETAIL:  syntax error at or near ","
 SELECT '(1,)'::cube AS cube;
 ERROR:  bad cube representation
-DETAIL:  syntax error at or before position 4, character (')', \051), input: '(1,)'
+DETAIL:  syntax error at or near ")"
 SELECT '(1,2,)'::cube AS cube;
 ERROR:  bad cube representation
-DETAIL:  syntax error at or before position 6, character (')', \051), input: '(1,2,)'
+DETAIL:  syntax error at or near ")"
 SELECT '(1,,2)'::cube AS cube;
 ERROR:  bad cube representation
-DETAIL:  syntax error at or before position 4, character (',', \054), input: '(1,,2)'
+DETAIL:  syntax error at or near ","
 -- invalid input: semantic errors and trailing garbage
 SELECT '[(1),(2)],'::cube AS cube; -- 0
 ERROR:  bad cube representation
-DETAIL:  garbage at or before char 9, (',', \054)
+DETAIL:  syntax error at or near ","
 SELECT '[(1,2,3),(2,3)]'::cube AS cube; -- 1
 ERROR:  bad cube representation
 DETAIL:  different point dimensions in (1,2,3) and (2,3)
@@ -312,7 +313,7 @@ ERROR:  bad cube representation
 DETAIL:  different point dimensions in (1,2) and (1,2,3)
 SELECT '(1),(2),'::cube AS cube; -- 2
 ERROR:  bad cube representation
-DETAIL:  garbage at or before char 7, (',', \054)
+DETAIL:  syntax error at or near ","
 SELECT '(1,2,3),(2,3)'::cube AS cube; -- 3
 ERROR:  bad cube representation
 DETAIL:  different point dimensions in (1,2,3) and (2,3)
@@ -321,25 +322,25 @@ ERROR:  bad cube representation
 DETAIL:  different point dimensions in (1,2) and (1,2,3)
 SELECT '(1,2,3)ab'::cube AS cube; -- 4
 ERROR:  bad cube representation
-DETAIL:  garbage at or before char 8, ('b', \142)
+DETAIL:  syntax error at or near "a"
 SELECT '(1,2,3)a'::cube AS cube; -- 5
 ERROR:  bad cube representation
-DETAIL:  garbage at or before char 8, ('end of input', \000)
+DETAIL:  syntax error at or near "a"
 SELECT '(1,2)('::cube AS cube; -- 5
 ERROR:  bad cube representation
-DETAIL:  garbage at or before char 6, ('end of input', \000)
+DETAIL:  syntax error at or near "("
 SELECT '1,2ab'::cube AS cube; -- 6
 ERROR:  bad cube representation
-DETAIL:  garbage at or before char 4, ('b', \142)
+DETAIL:  syntax error at or near "a"
 SELECT '1 e7'::cube AS cube; -- 6
 ERROR:  bad cube representation
-DETAIL:  garbage at or before char 3, ('7', \067)
+DETAIL:  syntax error at or near "e"
 SELECT '1,2a'::cube AS cube; -- 7
 ERROR:  bad cube representation
-DETAIL:  garbage at or before char 4, ('end of input', \000)
+DETAIL:  syntax error at or near "a"
 SELECT '1..2'::cube AS cube; -- 7
 ERROR:  bad cube representation
-DETAIL:  garbage at or before char 4, ('end of input', \000)
+DETAIL:  syntax error at or near ".2"
 --
 -- Testing building cubes from float8 values
 --
@@ -435,7 +436,7 @@ SELECT '24, 33.20'::cube    != '24, 33.21'::cube AS bool;
 SELECT '(2,0),(3,1)'::cube  =  '(2,0,0,0,0),(3,1,0,0,0)'::cube AS bool;
  bool 
 ------
- t
+ f
 (1 row)
 
 SELECT '(2,0),(3,1)'::cube  =  '(2,0,0,0,0),(3,1,0,0,1)'::cube AS bool;