diff --git a/contrib/cube/README.cube b/contrib/cube/README.cube
index 93ba63dd78de7f5bb262568f3f09960b35776477..42b84fb0611f65bd385e7da77c1db0fe7d6dc6ec 100644
--- a/contrib/cube/README.cube
+++ b/contrib/cube/README.cube
@@ -264,6 +264,27 @@ cube(text) returns cube
   cube takes text input and returns a cube. This is useful for making cubes
   from computed strings.
 
+cube(float8) returns cube
+  This makes a one dimensional cube with both coordinates the same.
+  If the type of the argument is a numeric type other than float8 an
+  explicit cast to float8 may be needed.
+  cube(1) == '(1)'
+
+cube(float8, float8) returns cube
+  This makes a one dimensional cube.
+  cube(1,2) == '(1),(2)'
+
+cube(cube, float8) returns cube
+  This builds a new cube by adding a dimension on to an existing cube with
+  the same values for both parts of the new coordinate. This is useful for
+  building cubes piece by piece from calculated values.
+  cube('(1)',2) == '(1,2),(1,2)'
+
+cube(cube, float8, float8) returns cube
+  This builds a new cube by adding a dimension on to an existing cube.
+  This is useful for building cubes piece by piece from calculated values.
+  cube('(1,2)',3,4) == '(1,3),(2,4)'
+
 cube_dim(cube) returns int
   cube_dim returns the number of dimensions stored in the the data structure
   for a cube. This is useful for constraints on the dimensions of a cube.
diff --git a/contrib/cube/cube.c b/contrib/cube/cube.c
index d24d0f559324c667f3900cc331bfe1884cfad933..b46eb35d3cd183a698fed7c8e8f49098889f322b 100644
--- a/contrib/cube/cube.c
+++ b/contrib/cube/cube.c
@@ -30,6 +30,13 @@ extern int	cube_yyparse();
 NDBOX	   *cube_in(char *str);
 NDBOX	   *cube(text *str);
 char	   *cube_out(NDBOX * cube);
+NDBOX      *cube_f8(double *);
+NDBOX      *cube_f8_f8(double *, double *);
+NDBOX      *cube_c_f8(NDBOX *, double *);
+NDBOX      *cube_c_f8_f8(NDBOX *, double *, double *);
+int4			cube_dim(NDBOX * a);
+double	   *cube_ll_coord(NDBOX * a, int4 n);
+double	   *cube_ur_coord(NDBOX * a, int4 n);
 
 
 /*
@@ -73,9 +80,6 @@ bool		cube_right(NDBOX * a, NDBOX * b);
 bool		cube_lt(NDBOX * a, NDBOX * b);
 bool		cube_gt(NDBOX * a, NDBOX * b);
 double	   *cube_distance(NDBOX * a, NDBOX * b);
-int4			cube_dim(NDBOX * a);
-double	   *cube_ll_coord(NDBOX * a, int4 n);
-double	   *cube_ur_coord(NDBOX * a, int4 n);
 bool		cube_is_point(NDBOX * a);
 NDBOX	   *cube_enlarge(NDBOX * a, double *r, int4 n);
 
@@ -1226,3 +1230,78 @@ cube_enlarge(NDBOX * a, double *r, int4 n)
 	}
 	return result;
 }
+
+/* Create a one dimensional box with identical upper and lower coordinates */
+NDBOX *
+cube_f8(double *x1)
+{
+	NDBOX	   *result;
+        int        size;
+	size = offsetof(NDBOX, x[0]) + sizeof(double) * 2;
+	result = (NDBOX *) palloc(size);
+	memset(result, 0, size);
+	result->size = size;
+	result->dim = 1;
+        result->x[0] = *x1;
+        result->x[1] = *x1;
+	return result;
+}
+
+/* Create a one dimensional box */
+NDBOX *
+cube_f8_f8(double *x1, double *x2)
+{
+	NDBOX	   *result;
+        int        size;
+	size = offsetof(NDBOX, x[0]) + sizeof(double) * 2;
+	result = (NDBOX *) palloc(size);
+	memset(result, 0, size);
+	result->size = size;
+	result->dim = 1;
+        result->x[0] = *x1;
+        result->x[1] = *x2;
+	return result;
+}
+
+/* Add a dimension to an existing cube with the same values for the new
+   coordinate */
+NDBOX *
+cube_c_f8(NDBOX *c, double *x1)
+{
+	NDBOX	   *result;
+        int        size;
+        int        i;
+	size = offsetof(NDBOX, x[0]) + sizeof(double) * (c->dim + 1) * 2;
+	result = (NDBOX *) palloc(size);
+	memset(result, 0, size);
+	result->size = size;
+	result->dim = c->dim + 1;
+        for (i = 0; i < c->dim; i++) {
+            result->x[i] = c->x[i];
+            result->x[result->dim + i] = c->x[c->dim + i];
+        }
+        result->x[result->dim - 1] = *x1;
+        result->x[2 * result->dim - 1] = *x1;
+	return result;
+}
+
+/* Add a dimension to an existing cube */
+NDBOX *
+cube_c_f8_f8(NDBOX *c, double *x1, double *x2)
+{
+	NDBOX	   *result;
+        int        size;
+        int        i;
+	size = offsetof(NDBOX, x[0]) + sizeof(double) * (c->dim + 1) * 2;
+	result = (NDBOX *) palloc(size);
+	memset(result, 0, size);
+	result->size = size;
+	result->dim = c->dim + 1;
+        for (i = 0; i < c->dim; i++) {
+            result->x[i] = c->x[i];
+            result->x[result->dim + i] = c->x[c->dim + i];
+        }
+        result->x[result->dim - 1] = *x1;
+        result->x[2 * result->dim - 1] = *x2;
+	return result;
+}
diff --git a/contrib/cube/cube.sql.in b/contrib/cube/cube.sql.in
index 60ac7d8aee022644f1dee22c0b4770d317ad404a..e79eb5263c845e1918d6228024f2c2257c45afb0 100644
--- a/contrib/cube/cube.sql.in
+++ b/contrib/cube/cube.sql.in
@@ -165,6 +165,22 @@ RETURNS float8
 AS 'MODULE_PATHNAME'
 LANGUAGE 'C' IMMUTABLE STRICT;
 
+CREATE OR REPLACE FUNCTION cube(float8) RETURNS cube
+AS 'MODULE_PATHNAME', 'cube_f8'
+LANGUAGE 'C' IMMUTABLE STRICT;
+
+CREATE OR REPLACE FUNCTION cube(float8, float8) RETURNS cube
+AS 'MODULE_PATHNAME', 'cube_f8_f8'
+LANGUAGE 'C' IMMUTABLE STRICT;
+
+CREATE OR REPLACE FUNCTION cube(cube, float8) RETURNS cube
+AS 'MODULE_PATHNAME', 'cube_c_f8'
+LANGUAGE 'C' IMMUTABLE STRICT;
+
+CREATE OR REPLACE FUNCTION cube(cube, float8, float8) RETURNS cube
+AS 'MODULE_PATHNAME', 'cube_c_f8_f8'
+LANGUAGE 'C' IMMUTABLE STRICT;
+
 -- Test if cube is also a point
 
 CREATE OR REPLACE FUNCTION cube_is_point(cube)
diff --git a/contrib/cube/expected/cube.out b/contrib/cube/expected/cube.out
index beced4e64a812c322cef306773c90bb85e6b30a5..3a1e670d66bf21b198ba7ffd7c95ef0335f504a5 100644
--- a/contrib/cube/expected/cube.out
+++ b/contrib/cube/expected/cube.out
@@ -258,46 +258,46 @@ SELECT '[(0,0,0,0),(1,0,0,0)]'::cube AS cube;
 SELECT ''::cube AS cube;
 ERROR:  cube_in: can't parse an empty string
 SELECT 'ABC'::cube AS cube;
-ERROR:  parse error at or before position 1, character ('A', \101), input: 'ABC'
+ERROR:  syntax error at or before position 1, character ('A', \101), input: 'ABC'
 
 SELECT '()'::cube AS cube;
-ERROR:  parse error at or before position 2, character (')', \051), input: '()'
+ERROR:  syntax error at or before position 2, character (')', \051), input: '()'
 
 SELECT '[]'::cube AS cube;
-ERROR:  parse error at or before position 2, character (']', \135), input: '[]'
+ERROR:  syntax error at or before position 2, character (']', \135), input: '[]'
 
 SELECT '[()]'::cube AS cube;
-ERROR:  parse error at or before position 3, character (')', \051), input: '[()]'
+ERROR:  syntax error at or before position 3, character (')', \051), input: '[()]'
 
 SELECT '[(1)]'::cube AS cube;
-ERROR:  parse error at or before position 5, character (']', \135), input: '[(1)]'
+ERROR:  syntax error at or before position 5, character (']', \135), input: '[(1)]'
 
 SELECT '[(1),]'::cube AS cube;
-ERROR:  parse error at or before position 6, character (']', \135), input: '[(1),]'
+ERROR:  syntax error at or before position 6, character (']', \135), input: '[(1),]'
 
 SELECT '[(1),2]'::cube AS cube;
-ERROR:  parse error at or before position 7, character (']', \135), input: '[(1),2]'
+ERROR:  syntax error at or before position 7, character (']', \135), input: '[(1),2]'
 
 SELECT '[(1),(2),(3)]'::cube AS cube;
-ERROR:  parse error at or before position 9, character (',', \054), input: '[(1),(2),(3)]'
+ERROR:  syntax error at or before position 9, character (',', \054), input: '[(1),(2),(3)]'
 
 SELECT '1,'::cube AS cube;
-ERROR:  parse error at or before position 2, character (',', \054), input: '1,'
+ERROR:  syntax error at or before position 2, character (',', \054), input: '1,'
 
 SELECT '1,2,'::cube AS cube;
-ERROR:  parse error at or before position 4, character (',', \054), input: '1,2,'
+ERROR:  syntax error at or before position 4, character (',', \054), input: '1,2,'
 
 SELECT '1,,2'::cube AS cube;
-ERROR:  parse error at or before position 3, character (',', \054), input: '1,,2'
+ERROR:  syntax error at or before position 3, character (',', \054), input: '1,,2'
 
 SELECT '(1,)'::cube AS cube;
-ERROR:  parse error at or before position 4, character (')', \051), input: '(1,)'
+ERROR:  syntax error at or before position 4, character (')', \051), input: '(1,)'
 
 SELECT '(1,2,)'::cube AS cube;
-ERROR:  parse error at or before position 6, character (')', \051), input: '(1,2,)'
+ERROR:  syntax error at or before position 6, character (')', \051), input: '(1,2,)'
 
 SELECT '(1,,2)'::cube AS cube;
-ERROR:  parse error at or before position 4, character (',', \054), input: '(1,,2)'
+ERROR:  syntax error at or before position 4, character (',', \054), input: '(1,,2)'
 
 -- invalid input: semantic errors and trailing garbage
 SELECT '[(1),(2)],'::cube AS cube; -- 0
@@ -339,6 +339,60 @@ ERROR:  (7) bad cube representation; garbage at or before char 4, ('end of input
 SELECT '1..2'::cube AS cube; -- 7
 ERROR:  (7) bad cube representation; garbage at or before char 4, ('end of input', \000)
 
+--
+-- Testing building cubes from float8 values
+--
+SELECT cube(0::float8);
+ cube 
+------
+ (0)
+(1 row)
+
+SELECT cube(1::float8);
+ cube 
+------
+ (1)
+(1 row)
+
+SELECT cube(1,2);
+  cube   
+---------
+ (1),(2)
+(1 row)
+
+SELECT cube(cube(1,2),3);
+     cube      
+---------------
+ (1, 3),(2, 3)
+(1 row)
+
+SELECT cube(cube(1,2),3,4);
+     cube      
+---------------
+ (1, 3),(2, 4)
+(1 row)
+
+SELECT cube(cube(cube(1,2),3,4),5);
+        cube         
+---------------------
+ (1, 3, 5),(2, 4, 5)
+(1 row)
+
+SELECT cube(cube(cube(1,2),3,4),5,6);
+        cube         
+---------------------
+ (1, 3, 5),(2, 4, 6)
+(1 row)
+
+--
+-- Test that the text -> cube cast was installed.
+--
+SELECT '(0)'::text::cube;
+ cube 
+------
+ (0)
+(1 row)
+
 --
 -- Testing limit of CUBE_MAX_DIM dimensions check in cube_in.
 --
diff --git a/contrib/cube/sql/cube.sql b/contrib/cube/sql/cube.sql
index a0712c555799f3cd23d2ecb0e664dd6a918114a8..d386a5a2f32f4e43fe95feb3dec37b52de10177b 100644
--- a/contrib/cube/sql/cube.sql
+++ b/contrib/cube/sql/cube.sql
@@ -92,6 +92,24 @@ SELECT '1 e7'::cube AS cube; -- 6
 SELECT '1,2a'::cube AS cube; -- 7
 SELECT '1..2'::cube AS cube; -- 7
 
+--
+-- Testing building cubes from float8 values
+--
+
+SELECT cube(0::float8);
+SELECT cube(1::float8);
+SELECT cube(1,2);
+SELECT cube(cube(1,2),3);
+SELECT cube(cube(1,2),3,4);
+SELECT cube(cube(cube(1,2),3,4),5);
+SELECT cube(cube(cube(1,2),3,4),5,6);
+
+--
+-- Test that the text -> cube cast was installed.
+--
+
+SELECT '(0)'::text::cube;
+
 --
 -- Testing limit of CUBE_MAX_DIM dimensions check in cube_in.
 --