提交 03e47392 编写于 作者: T Tom Lane

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.
上级 b38c0433
# $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 subdir = contrib/cube
top_builddir = ../.. top_builddir = ../..
include $(top_builddir)/src/Makefile.global include $(top_builddir)/src/Makefile.global
MODULE_big = cube MODULE_big = cube
OBJS= cube.o cubeparse.o buffer.o OBJS= cube.o cubeparse.o
DATA_built = cube.sql DATA_built = cube.sql
DOCS = README.cube DOCS = README.cube
...@@ -28,7 +28,7 @@ endif ...@@ -28,7 +28,7 @@ endif
cubescan.c: cubescan.l cubescan.c: cubescan.l
ifdef FLEX ifdef FLEX
$(FLEX) $(FLEXFLAGS) -Pcube_yy -o'$@' $< $(FLEX) $(FLEXFLAGS) -o'$@' $<
else else
@$(missing) flex $< $@ @$(missing) flex $< $@
endif endif
......
...@@ -9,11 +9,6 @@ Makefile building instructions for the shared library ...@@ -9,11 +9,6 @@ Makefile building instructions for the shared library
README.cube the file you are now reading 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.c the implementation of this data type in c
cube.sql.in SQL code needed to register this type with postgres cube.sql.in SQL code needed to register this type with postgres
......
/* 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;
}
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 @@ ...@@ -19,8 +19,10 @@
#define min(a,b) ((a) <= (b) ? (a) : (b)) #define min(a,b) ((a) <= (b) ? (a) : (b))
#define abs(a) ((a) < (0) ? (-a) : (a)) #define abs(a) ((a) < (0) ? (-a) : (a))
extern void set_parse_buffer(char *str);
extern int cube_yyparse(); 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 ** Input/Output routines
...@@ -51,11 +53,20 @@ NDBOX *g_cube_union(bytea *entryvec, int *sizep); ...@@ -51,11 +53,20 @@ NDBOX *g_cube_union(bytea *entryvec, int *sizep);
NDBOX *g_cube_binary_union(NDBOX * r1, NDBOX * r2, int *sizep); NDBOX *g_cube_binary_union(NDBOX * r1, NDBOX * r2, int *sizep);
bool *g_cube_same(NDBOX * b1, NDBOX * b2, bool *result); 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 ** 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_contains(NDBOX * a, NDBOX * b);
bool cube_contained(NDBOX * a, NDBOX * b); bool cube_contained(NDBOX * a, NDBOX * b);
bool cube_overlap(NDBOX * a, NDBOX * b); bool cube_overlap(NDBOX * a, NDBOX * b);
...@@ -99,10 +110,12 @@ cube_in(char *str) ...@@ -99,10 +110,12 @@ cube_in(char *str)
{ {
void *result; void *result;
set_parse_buffer(str); cube_scanner_init(str);
if (cube_yyparse(&result) != 0) if (cube_yyparse(&result) != 0)
return NULL; cube_yyerror("bogus input");
cube_scanner_finish();
return ((NDBOX *) result); return ((NDBOX *) result);
} }
...@@ -438,7 +451,7 @@ g_cube_picksplit(bytea *entryvec, ...@@ -438,7 +451,7 @@ g_cube_picksplit(bytea *entryvec,
bool * bool *
g_cube_same(NDBOX * b1, NDBOX * b2, bool *result) g_cube_same(NDBOX * b1, NDBOX * b2, bool *result)
{ {
if (cube_same(b1, b2)) if (cube_eq(b1, b2))
*result = TRUE; *result = TRUE;
else else
*result = FALSE; *result = FALSE;
...@@ -480,7 +493,7 @@ g_cube_leaf_consistent(NDBOX * key, ...@@ -480,7 +493,7 @@ g_cube_leaf_consistent(NDBOX * key,
retval = (bool) cube_right(key, query); retval = (bool) cube_right(key, query);
break; break;
case RTSameStrategyNumber: case RTSameStrategyNumber:
retval = (bool) cube_same(key, query); retval = (bool) cube_eq(key, query);
break; break;
case RTContainsStrategyNumber: case RTContainsStrategyNumber:
retval = (bool) cube_contains(key, query); retval = (bool) cube_contains(key, query);
...@@ -754,15 +767,12 @@ cube_right(NDBOX * a, NDBOX * b) ...@@ -754,15 +767,12 @@ cube_right(NDBOX * a, NDBOX * b)
/* make up a metric in which one box will be 'lower' than the other /* make up a metric in which one box will be 'lower' than the other
-- this can be useful for sorting and to determine uniqueness */ -- this can be useful for sorting and to determine uniqueness */
bool int32
cube_lt(NDBOX * a, NDBOX * b) cube_cmp(NDBOX * a, NDBOX * b)
{ {
int i; int i;
int dim; int dim;
if ((a == NULL) || (b == NULL))
return (FALSE);
dim = min(a->dim, b->dim); dim = min(a->dim, b->dim);
/* compare the common dimensions */ /* compare the common dimensions */
...@@ -770,19 +780,19 @@ cube_lt(NDBOX * a, NDBOX * b) ...@@ -770,19 +780,19 @@ cube_lt(NDBOX * a, NDBOX * b)
{ {
if (min(a->x[i], a->x[a->dim + i]) > if (min(a->x[i], a->x[a->dim + i]) >
min(b->x[i], b->x[b->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]) < if (min(a->x[i], a->x[a->dim + i]) <
min(b->x[i], b->x[b->dim + i])) min(b->x[i], b->x[b->dim + i]))
return (TRUE); return -1;
} }
for (i = 0; i < dim; i++) for (i = 0; i < dim; i++)
{ {
if (max(a->x[i], a->x[a->dim + i]) > if (max(a->x[i], a->x[a->dim + i]) >
max(b->x[i], b->x[b->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]) < if (max(a->x[i], a->x[a->dim + i]) <
max(b->x[i], b->x[b->dim + i])) max(b->x[i], b->x[b->dim + i]))
return (TRUE); return -1;
} }
/* compare extra dimensions to zero */ /* compare extra dimensions to zero */
...@@ -791,186 +801,87 @@ cube_lt(NDBOX * a, NDBOX * b) ...@@ -791,186 +801,87 @@ cube_lt(NDBOX * a, NDBOX * b)
for (i = dim; i < a->dim; i++) for (i = dim; i < a->dim; i++)
{ {
if (min(a->x[i], a->x[a->dim + i]) > 0) 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) if (min(a->x[i], a->x[a->dim + i]) < 0)
return (TRUE); return -1;
} }
for (i = dim; i < a->dim; i++) for (i = dim; i < a->dim; i++)
{ {
if (max(a->x[i], a->x[a->dim + i]) > 0) 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) 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 * if all common dimensions are equal, the cube with more
* dimensions wins * dimensions wins
*/ */
return (FALSE); return 1;
} }
if (a->dim < b->dim) if (a->dim < b->dim)
{ {
for (i = dim; i < b->dim; i++) for (i = dim; i < b->dim; i++)
{ {
if (min(b->x[i], b->x[b->dim + i]) > 0) 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) if (min(b->x[i], b->x[b->dim + i]) < 0)
return (FALSE); return 1;
} }
for (i = dim; i < b->dim; i++) for (i = dim; i < b->dim; i++)
{ {
if (max(b->x[i], b->x[b->dim + i]) > 0) 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) 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 * if all common dimensions are equal, the cube with more
* dimensions wins * dimensions wins
*/ */
return (TRUE); return -1;
} }
return (FALSE); /* They're really equal */
return 0;
} }
bool bool
cube_gt(NDBOX * a, NDBOX * b) cube_eq(NDBOX * a, NDBOX * b)
{ {
int i; return (cube_cmp(a, b) == 0);
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);
} }
/* Equal */
bool bool
cube_same(NDBOX * a, NDBOX * b) cube_ne(NDBOX * a, NDBOX * b)
{ {
int i; return (cube_cmp(a, b) != 0);
}
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++) bool
{ 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 (cube_cmp(a, b) < 0);
return (FALSE); }
if (max(a->x[i], a->x[a->dim + i]) !=
max(b->x[i], b->x[b->dim + i]))
return (FALSE);
}
/* bool
* all dimensions of (b) are compared to those of (a); instead of cube_gt(NDBOX * a, NDBOX * b)
* 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 return (cube_cmp(a, b) > 0);
* 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); bool
cube_le(NDBOX * a, NDBOX * b)
{
return (cube_cmp(a, b) <= 0);
} }
/* Different */
bool 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)'; ...@@ -70,6 +70,20 @@ COMMENT ON FUNCTION cube_right(cube, cube) IS 'is right of (NOT IMPLEMENTED)';
-- Comparison methods -- 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) CREATE OR REPLACE FUNCTION cube_lt(cube, cube)
RETURNS bool RETURNS bool
AS 'MODULE_PATHNAME' AS 'MODULE_PATHNAME'
...@@ -84,40 +98,47 @@ LANGUAGE 'C' IMMUTABLE STRICT; ...@@ -84,40 +98,47 @@ LANGUAGE 'C' IMMUTABLE STRICT;
COMMENT ON FUNCTION cube_gt(cube, cube) IS 'greater than'; 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 RETURNS bool
AS 'MODULE_PATHNAME' AS 'MODULE_PATHNAME'
LANGUAGE 'C' IMMUTABLE STRICT; 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 RETURNS bool
AS 'MODULE_PATHNAME' AS 'MODULE_PATHNAME'
LANGUAGE 'C' IMMUTABLE STRICT; 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 RETURNS bool
AS 'MODULE_PATHNAME' AS 'MODULE_PATHNAME'
LANGUAGE 'C' IMMUTABLE STRICT; 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 RETURNS bool
AS 'MODULE_PATHNAME' AS 'MODULE_PATHNAME'
LANGUAGE 'C' IMMUTABLE STRICT; 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 RETURNS bool
AS 'MODULE_PATHNAME' AS 'MODULE_PATHNAME'
LANGUAGE 'C' IMMUTABLE STRICT; 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 -- support routines for indexing
...@@ -199,13 +220,25 @@ LANGUAGE 'C' IMMUTABLE STRICT; ...@@ -199,13 +220,25 @@ LANGUAGE 'C' IMMUTABLE STRICT;
CREATE OPERATOR < ( CREATE OPERATOR < (
LEFTARG = cube, RIGHTARG = cube, PROCEDURE = cube_lt, LEFTARG = cube, RIGHTARG = cube, PROCEDURE = cube_lt,
COMMUTATOR = '>', COMMUTATOR = '>', NEGATOR = '>=',
RESTRICT = scalarltsel, JOIN = scalarltjoinsel RESTRICT = scalarltsel, JOIN = scalarltjoinsel
); );
CREATE OPERATOR > ( CREATE OPERATOR > (
LEFTARG = cube, RIGHTARG = cube, PROCEDURE = cube_gt, 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 RESTRICT = scalargtsel, JOIN = scalargtjoinsel
); );
...@@ -240,14 +273,14 @@ CREATE OPERATOR >> ( ...@@ -240,14 +273,14 @@ CREATE OPERATOR >> (
); );
CREATE OPERATOR = ( CREATE OPERATOR = (
LEFTARG = cube, RIGHTARG = cube, PROCEDURE = cube_same, LEFTARG = cube, RIGHTARG = cube, PROCEDURE = cube_eq,
COMMUTATOR = '=', NEGATOR = '<>', COMMUTATOR = '=', NEGATOR = '<>',
RESTRICT = eqsel, JOIN = eqjoinsel, RESTRICT = eqsel, JOIN = eqjoinsel,
SORT1 = '<', SORT2 = '<' MERGES
); );
CREATE OPERATOR <> ( CREATE OPERATOR <> (
LEFTARG = cube, RIGHTARG = cube, PROCEDURE = cube_different, LEFTARG = cube, RIGHTARG = cube, PROCEDURE = cube_ne,
COMMUTATOR = '<>', NEGATOR = '=', COMMUTATOR = '<>', NEGATOR = '=',
RESTRICT = neqsel, JOIN = neqjoinsel RESTRICT = neqsel, JOIN = neqjoinsel
); );
...@@ -302,7 +335,16 @@ AS 'MODULE_PATHNAME' ...@@ -302,7 +335,16 @@ AS 'MODULE_PATHNAME'
LANGUAGE 'C'; 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 CREATE OPERATOR CLASS gist_cube_ops
DEFAULT FOR TYPE cube USING gist AS DEFAULT FOR TYPE cube USING gist AS
......
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
#include "postgres.h" #include "postgres.h"
#include "cubedata.h" #include "cubedata.h"
#include "buffer.h"
#undef yylex /* falure to redefine yylex will result in a call to the */ #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 */ #define yylex cube_yylex /* wrong scanner when running inside the postgres backend */
...@@ -17,7 +16,10 @@ ...@@ -17,7 +16,10 @@
extern int yylex(); /* defined as cube_yylex in cubescan.c */ extern int yylex(); /* defined as cube_yylex in cubescan.c */
extern int errno; 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); int cube_yyparse(void *result);
static int delim_count(char *s, char delim); static int delim_count(char *s, char delim);
...@@ -37,25 +39,9 @@ box: ...@@ -37,25 +39,9 @@ box:
O_BRACKET paren_list COMMA paren_list C_BRACKET { O_BRACKET paren_list COMMA paren_list C_BRACKET {
int dim; 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; dim = delim_count($2, ',') + 1;
if ( (delim_count($4, ',') + 1) != dim ) { if ( (delim_count($4, ',') + 1) != dim ) {
reset_parse_buffer();
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR), (errcode(ERRCODE_SYNTAX_ERROR),
errmsg("bad cube representation"), errmsg("bad cube representation"),
...@@ -64,7 +50,6 @@ box: ...@@ -64,7 +50,6 @@ box:
YYABORT; YYABORT;
} }
if (dim > CUBE_MAX_DIM) { if (dim > CUBE_MAX_DIM) {
reset_parse_buffer();
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR), (errcode(ERRCODE_SYNTAX_ERROR),
errmsg("bad cube representation"), errmsg("bad cube representation"),
...@@ -79,23 +64,10 @@ box: ...@@ -79,23 +64,10 @@ box:
| |
paren_list COMMA paren_list { paren_list COMMA paren_list {
int dim; 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; dim = delim_count($1, ',') + 1;
if ( (delim_count($3, ',') + 1) != dim ) { if ( (delim_count($3, ',') + 1) != dim ) {
reset_parse_buffer();
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR), (errcode(ERRCODE_SYNTAX_ERROR),
errmsg("bad cube representation"), errmsg("bad cube representation"),
...@@ -104,7 +76,6 @@ box: ...@@ -104,7 +76,6 @@ box:
YYABORT; YYABORT;
} }
if (dim > CUBE_MAX_DIM) { if (dim > CUBE_MAX_DIM) {
reset_parse_buffer();
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR), (errcode(ERRCODE_SYNTAX_ERROR),
errmsg("bad cube representation"), errmsg("bad cube representation"),
...@@ -119,33 +90,9 @@ box: ...@@ -119,33 +90,9 @@ box:
paren_list { paren_list {
int dim; 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; dim = delim_count($1, ',') + 1;
if (dim > CUBE_MAX_DIM) { if (dim > CUBE_MAX_DIM) {
reset_parse_buffer();
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR), (errcode(ERRCODE_SYNTAX_ERROR),
errmsg("bad cube representation"), errmsg("bad cube representation"),
...@@ -161,33 +108,9 @@ box: ...@@ -161,33 +108,9 @@ box:
list { list {
int dim; 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; dim = delim_count($1, ',') + 1;
if (dim > CUBE_MAX_DIM) { if (dim > CUBE_MAX_DIM) {
reset_parse_buffer();
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR), (errcode(ERRCODE_SYNTAX_ERROR),
errmsg("bad cube representation"), errmsg("bad cube representation"),
...@@ -207,8 +130,9 @@ paren_list: ...@@ -207,8 +130,9 @@ paren_list:
list: list:
FLOAT { FLOAT {
$$ = palloc(strlen(parse_buffer()) + 1); /* alloc enough space to be sure whole list will fit */
strcpy($$, $1); $$ = palloc(scanbuflen + 1);
strcpy($$, $1);
} }
| |
list COMMA FLOAT { list COMMA FLOAT {
...@@ -220,39 +144,6 @@ list: ...@@ -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 static int
delim_count(char *s, char delim) delim_count(char *s, char delim)
{ {
......
...@@ -5,33 +5,30 @@ ...@@ -5,33 +5,30 @@
#include "postgres.h" #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) */ /* Avoid exit() on fatal scanner errors (a bit ugly -- see yy_fatal_error) */
#define fprintf(file, fmt, msg) ereport(ERROR, (errmsg_internal("%s", msg))) #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 */ /* flex 2.5.4 doesn't bother with a decl for this */
#define YY_DECL int cube_yylex YY_PROTO(( void )); \ int cube_yylex(void);
int cube_yylex YY_PROTO(( void ))
#define yylval cube_yylval
void cube_scanner_init(const char *str);
/* redefined YY_INPUT reads byte-wise from the memory area defined in buffer.c */ void cube_scanner_finish(void);
#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);
%} %}
%option 8bit %option 8bit
%option never-interactive %option never-interactive
%option nounput %option nounput
%option noyywrap %option noyywrap
%option prefix="cube_yy"
n [0-9]+ n [0-9]+
...@@ -52,8 +49,61 @@ float ({integer}|{real})([eE]{integer})? ...@@ -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);
} }
...@@ -257,53 +257,54 @@ SELECT '[(0,0,0,0),(1,0,0,0)]'::cube AS cube; ...@@ -257,53 +257,54 @@ SELECT '[(0,0,0,0),(1,0,0,0)]'::cube AS cube;
-- invalid input: parse errors -- invalid input: parse errors
SELECT ''::cube AS cube; 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; SELECT 'ABC'::cube AS cube;
ERROR: bad cube representation 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; SELECT '()'::cube AS cube;
ERROR: bad cube representation 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; SELECT '[]'::cube AS cube;
ERROR: bad cube representation 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; SELECT '[()]'::cube AS cube;
ERROR: bad cube representation 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; SELECT '[(1)]'::cube AS cube;
ERROR: bad cube representation 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; SELECT '[(1),]'::cube AS cube;
ERROR: bad cube representation 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; SELECT '[(1),2]'::cube AS cube;
ERROR: bad cube representation 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; SELECT '[(1),(2),(3)]'::cube AS cube;
ERROR: bad cube representation 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; SELECT '1,'::cube AS cube;
ERROR: bad cube representation 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; SELECT '1,2,'::cube AS cube;
ERROR: bad cube representation 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; SELECT '1,,2'::cube AS cube;
ERROR: bad cube representation 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; SELECT '(1,)'::cube AS cube;
ERROR: bad cube representation 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; SELECT '(1,2,)'::cube AS cube;
ERROR: bad cube representation 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; SELECT '(1,,2)'::cube AS cube;
ERROR: bad cube representation 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 -- invalid input: semantic errors and trailing garbage
SELECT '[(1),(2)],'::cube AS cube; -- 0 SELECT '[(1),(2)],'::cube AS cube; -- 0
ERROR: bad cube representation 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 SELECT '[(1,2,3),(2,3)]'::cube AS cube; -- 1
ERROR: bad cube representation ERROR: bad cube representation
DETAIL: different point dimensions in (1,2,3) and (2,3) DETAIL: different point dimensions in (1,2,3) and (2,3)
...@@ -312,7 +313,7 @@ ERROR: bad cube representation ...@@ -312,7 +313,7 @@ ERROR: bad cube representation
DETAIL: different point dimensions in (1,2) and (1,2,3) DETAIL: different point dimensions in (1,2) and (1,2,3)
SELECT '(1),(2),'::cube AS cube; -- 2 SELECT '(1),(2),'::cube AS cube; -- 2
ERROR: bad cube representation 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 SELECT '(1,2,3),(2,3)'::cube AS cube; -- 3
ERROR: bad cube representation ERROR: bad cube representation
DETAIL: different point dimensions in (1,2,3) and (2,3) DETAIL: different point dimensions in (1,2,3) and (2,3)
...@@ -321,25 +322,25 @@ ERROR: bad cube representation ...@@ -321,25 +322,25 @@ ERROR: bad cube representation
DETAIL: different point dimensions in (1,2) and (1,2,3) DETAIL: different point dimensions in (1,2) and (1,2,3)
SELECT '(1,2,3)ab'::cube AS cube; -- 4 SELECT '(1,2,3)ab'::cube AS cube; -- 4
ERROR: bad cube representation 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 SELECT '(1,2,3)a'::cube AS cube; -- 5
ERROR: bad cube representation 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 SELECT '(1,2)('::cube AS cube; -- 5
ERROR: bad cube representation 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 SELECT '1,2ab'::cube AS cube; -- 6
ERROR: bad cube representation 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 SELECT '1 e7'::cube AS cube; -- 6
ERROR: bad cube representation 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 SELECT '1,2a'::cube AS cube; -- 7
ERROR: bad cube representation 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 SELECT '1..2'::cube AS cube; -- 7
ERROR: bad cube representation 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 -- Testing building cubes from float8 values
-- --
...@@ -435,7 +436,7 @@ SELECT '24, 33.20'::cube != '24, 33.21'::cube AS bool; ...@@ -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; SELECT '(2,0),(3,1)'::cube = '(2,0,0,0,0),(3,1,0,0,0)'::cube AS bool;
bool bool
------ ------
t f
(1 row) (1 row)
SELECT '(2,0),(3,1)'::cube = '(2,0,0,0,0),(3,1,0,0,1)'::cube AS bool; SELECT '(2,0),(3,1)'::cube = '(2,0,0,0,0),(3,1,0,0,1)'::cube AS bool;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册