mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-09-28 21:01:48 +02:00
Make contrib/cube work with flex 2.5.31. Fix it up to have a real
btree operator class, too, since in PG 7.4 you can't GROUP without one.
This commit is contained in:
parent
b38c04335a
commit
03e47392e0
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
@ -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);
|
@ -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_eq(NDBOX * a, NDBOX * b)
|
||||
{
|
||||
return (cube_cmp(a, b) == 0);
|
||||
}
|
||||
|
||||
bool
|
||||
cube_ne(NDBOX * a, NDBOX * b)
|
||||
{
|
||||
return (cube_cmp(a, b) != 0);
|
||||
}
|
||||
|
||||
bool
|
||||
cube_lt(NDBOX * a, NDBOX * b)
|
||||
{
|
||||
return (cube_cmp(a, b) < 0);
|
||||
}
|
||||
|
||||
bool
|
||||
cube_gt(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_le(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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
return (TRUE);
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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,6 +98,27 @@ LANGUAGE 'C' IMMUTABLE STRICT;
|
||||
|
||||
COMMENT ON FUNCTION cube_gt(cube, cube) IS 'greater than';
|
||||
|
||||
CREATE OR REPLACE FUNCTION cube_le(cube, cube)
|
||||
RETURNS bool
|
||||
AS 'MODULE_PATHNAME'
|
||||
LANGUAGE 'C' IMMUTABLE STRICT;
|
||||
|
||||
COMMENT ON FUNCTION cube_le(cube, cube) IS 'lower than or equal to';
|
||||
|
||||
CREATE OR REPLACE FUNCTION cube_ge(cube, cube)
|
||||
RETURNS bool
|
||||
AS 'MODULE_PATHNAME'
|
||||
LANGUAGE 'C' IMMUTABLE STRICT;
|
||||
|
||||
COMMENT ON FUNCTION cube_ge(cube, cube) IS 'greater than or equal to';
|
||||
|
||||
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'
|
||||
@ -105,20 +140,6 @@ LANGUAGE 'C' IMMUTABLE STRICT;
|
||||
|
||||
COMMENT ON FUNCTION cube_overlap(cube, cube) IS 'overlaps';
|
||||
|
||||
CREATE OR REPLACE FUNCTION cube_same(cube, cube)
|
||||
RETURNS bool
|
||||
AS 'MODULE_PATHNAME'
|
||||
LANGUAGE 'C' IMMUTABLE STRICT;
|
||||
|
||||
COMMENT ON FUNCTION cube_same(cube, cube) IS 'same as';
|
||||
|
||||
CREATE OR REPLACE FUNCTION cube_different(cube, cube)
|
||||
RETURNS bool
|
||||
AS 'MODULE_PATHNAME'
|
||||
LANGUAGE 'C' IMMUTABLE STRICT;
|
||||
|
||||
COMMENT ON FUNCTION cube_different(cube, cube) IS 'different';
|
||||
|
||||
-- support routines for indexing
|
||||
|
||||
CREATE OR REPLACE FUNCTION cube_union(cube, cube)
|
||||
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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 cube_flush_scanner_buffer(void) {
|
||||
YY_FLUSH_BUFFER;
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Called after parsing is done to clean up after cube_scanner_init()
|
||||
*/
|
||||
void
|
||||
cube_scanner_finish(void)
|
||||
{
|
||||
yy_delete_buffer(scanbufhandle);
|
||||
pfree(scanbuf);
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user