diff --git a/contrib/cube/Makefile b/contrib/cube/Makefile
index 6c5570505cb4166609c385252702d1717508b6ff..80e56aa7f880d23f3e02894cd61051adf33a454a 100644
--- a/contrib/cube/Makefile
+++ b/contrib/cube/Makefile
@@ -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
diff --git a/contrib/cube/README.cube b/contrib/cube/README.cube
index 42b84fb0611f65bd385e7da77c1db0fe7d6dc6ec..c4ad7b33b5ac739fdf1597bcb3fbe9c930335ec8 100644
--- a/contrib/cube/README.cube
+++ b/contrib/cube/README.cube
@@ -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
index 3a1b728812817bbb7733d6ee22d77f8dcceede4f..0000000000000000000000000000000000000000
--- a/contrib/cube/buffer.c
+++ /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
index eef9124dac5eff3cbbc4236b13970b4a6862cf46..0000000000000000000000000000000000000000
--- a/contrib/cube/buffer.h
+++ /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);
diff --git a/contrib/cube/cube.c b/contrib/cube/cube.c
index 396253261d95f57d4c4205f14720dc5b7a0a7cfa..15fce4f1f7d6c56554dd0c674cda11f0a7a55e8b 100644
--- a/contrib/cube/cube.c
+++ b/contrib/cube/cube.c
@@ -19,8 +19,10 @@
 #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);
 }
 
 
diff --git a/contrib/cube/cube.sql.in b/contrib/cube/cube.sql.in
index 6afcce5aeba6676e9c012fe04e72c30988fe8545..b9b812f5814460b62cbe976d13a12c5dbb6bdb1d 100644
--- a/contrib/cube/cube.sql.in
+++ b/contrib/cube/cube.sql.in
@@ -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
diff --git a/contrib/cube/cubeparse.y b/contrib/cube/cubeparse.y
index 917d84079e3c24e95dd830d475172bdacca7fd06..e996a488c62300b3d743a3cfebd7caa524142994 100644
--- a/contrib/cube/cubeparse.y
+++ b/contrib/cube/cubeparse.y
@@ -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  */
@@ -17,7 +16,10 @@
 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)
 {
diff --git a/contrib/cube/cubescan.l b/contrib/cube/cubescan.l
index 1b44397f460e35e7e8a6ea7cfd0cb90717ab377d..c5e1a20f6b19543baa9ed5578f176f298aa555c9 100644
--- a/contrib/cube/cubescan.l
+++ b/contrib/cube/cubescan.l
@@ -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);
 }
diff --git a/contrib/cube/expected/cube.out b/contrib/cube/expected/cube.out
index 086d76fd0bfc4de39b4ad1a264baeb42c18d8801..367031e9835fefd09c2e4db355084861ebd51475 100644
--- a/contrib/cube/expected/cube.out
+++ b/contrib/cube/expected/cube.out
@@ -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;