Commit 043be9ad authored by Tom Lane's avatar Tom Lane

Make contrib/seg 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.
parent 03e47392
# $Header: /cvsroot/pgsql/contrib/seg/Makefile,v 1.9 2003/05/14 03:27:22 tgl Exp $ # $Header: /cvsroot/pgsql/contrib/seg/Makefile,v 1.10 2003/09/14 02:18:49 tgl Exp $
subdir = contrib/seg subdir = contrib/seg
top_builddir = ../.. top_builddir = ../..
include $(top_builddir)/src/Makefile.global include $(top_builddir)/src/Makefile.global
MODULE_big = seg MODULE_big = seg
OBJS = seg.o segparse.o buffer.o OBJS = seg.o segparse.o
DATA_built = seg.sql DATA_built = seg.sql
DOCS = README.seg DOCS = README.seg
REGRESS = seg REGRESS = seg
...@@ -27,7 +27,7 @@ endif ...@@ -27,7 +27,7 @@ endif
segscan.c: segscan.l segscan.c: segscan.l
ifdef FLEX ifdef FLEX
$(FLEX) $(FLEXFLAGS) -Pseg_yy -o'$@' $< $(FLEX) $(FLEXFLAGS) -o'$@' $<
else else
@$(missing) flex $< $@ @$(missing) flex $< $@
endif endif
......
...@@ -56,12 +56,6 @@ Makefile building instructions for the shared library ...@@ -56,12 +56,6 @@ Makefile building instructions for the shared library
README.seg the file you are now reading README.seg the file you are now reading
buffer.c global variables and buffer access utilities
shared between the parser (segparse.y) and the
scanner (segscan.l)
buffer.h function prototypes for buffer.c
seg.c the implementation of this data type in c seg.c the implementation of this data type in c
seg.sql.in SQL code needed to register this type with postgres seg.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 seg_flush_scanner_buffer(void); /* defined in segscan.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;
seg_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);
...@@ -394,35 +394,29 @@ SELECT '100(+-)1'::seg AS seg; ...@@ -394,35 +394,29 @@ SELECT '100(+-)1'::seg AS seg;
-- invalid input -- invalid input
SELECT ''::seg AS seg; SELECT ''::seg AS seg;
ERROR: can't parse an empty string ERROR: bad seg representation
DETAIL: syntax error at end of input
SELECT 'ABC'::seg AS seg; SELECT 'ABC'::seg AS seg;
ERROR: syntax error ERROR: bad seg representation
DETAIL: syntax error at or near position 1, character ('A', \101), input: 'ABC' DETAIL: syntax error at or near "A"
SELECT '1ABC'::seg AS seg; SELECT '1ABC'::seg AS seg;
ERROR: syntax error ERROR: bad seg representation
DETAIL: syntax error at or near position 2, character ('A', \101), input: '1ABC' DETAIL: syntax error at or near "A"
SELECT '1.'::seg AS seg; SELECT '1.'::seg AS seg;
ERROR: syntax error ERROR: bad seg representation
DETAIL: syntax error at or near position 2, character ('.', \056), input: '1.' DETAIL: syntax error at or near "."
SELECT '1.....'::seg AS seg; SELECT '1.....'::seg AS seg;
ERROR: syntax error ERROR: bad seg representation
DETAIL: syntax error at or near position 6, character ('.', \056), input: '1.....' DETAIL: syntax error at or near ".."
SELECT '.1'::seg AS seg; SELECT '.1'::seg AS seg;
ERROR: syntax error ERROR: bad seg representation
DETAIL: syntax error at or near position 2, character ('1', \061), input: '.1' DETAIL: syntax error at or near "."
SELECT '1..2.'::seg AS seg; SELECT '1..2.'::seg AS seg;
ERROR: syntax error ERROR: bad seg representation
DETAIL: syntax error at or near position 5, character ('.', \056), input: '1..2.' DETAIL: syntax error at or near "."
SELECT '1 e7'::seg AS seg; SELECT '1 e7'::seg AS seg;
ERROR: syntax error ERROR: bad seg representation
DETAIL: syntax error at or near position 3, character ('e', \145), input: '1 e7' DETAIL: syntax error at or near "e"
SELECT '1e700'::seg AS seg; SELECT '1e700'::seg AS seg;
ERROR: syntax error ERROR: syntax error
DETAIL: numeric value 1e700 unrepresentable DETAIL: numeric value 1e700 unrepresentable
......
...@@ -23,8 +23,10 @@ ...@@ -23,8 +23,10 @@
#define GIST_QUERY_DEBUG #define GIST_QUERY_DEBUG
*/ */
extern void set_parse_buffer(char *str);
extern int seg_yyparse(); extern int seg_yyparse();
extern void seg_yyerror(const char *message);
extern void seg_scanner_init(const char *str);
extern void seg_scanner_finish(void);
/* /*
extern int seg_yydebug; extern int seg_yydebug;
...@@ -99,16 +101,13 @@ seg_in(char *str) ...@@ -99,16 +101,13 @@ seg_in(char *str)
{ {
SEG *result = palloc(sizeof(SEG)); SEG *result = palloc(sizeof(SEG));
set_parse_buffer(str); seg_scanner_init(str);
/*
* seg_yydebug = 1;
*/
if (seg_yyparse(result) != 0) if (seg_yyparse(result) != 0)
{ seg_yyerror("bogus input");
pfree(result);
return NULL; seg_scanner_finish();
}
return (result); return (result);
} }
...@@ -880,7 +879,6 @@ seg_gt(SEG * a, SEG * b) ...@@ -880,7 +879,6 @@ seg_gt(SEG * a, SEG * b)
return seg_cmp(a, b) > 0; return seg_cmp(a, b) > 0;
} }
bool bool
seg_ge(SEG * a, SEG * b) seg_ge(SEG * a, SEG * b)
{ {
......
...@@ -7,12 +7,12 @@ SET search_path = public; ...@@ -7,12 +7,12 @@ SET search_path = public;
CREATE FUNCTION seg_in(cstring) CREATE FUNCTION seg_in(cstring)
RETURNS seg RETURNS seg
AS 'MODULE_PATHNAME' AS 'MODULE_PATHNAME'
LANGUAGE 'C'; LANGUAGE 'C' IMMUTABLE STRICT;
CREATE FUNCTION seg_out(seg) CREATE FUNCTION seg_out(seg)
RETURNS cstring RETURNS cstring
AS 'MODULE_PATHNAME' AS 'MODULE_PATHNAME'
LANGUAGE 'C'; LANGUAGE 'C' IMMUTABLE STRICT;
CREATE TYPE seg ( CREATE TYPE seg (
INTERNALLENGTH = 12, INTERNALLENGTH = 12,
...@@ -138,6 +138,13 @@ COMMENT ON FUNCTION seg_different(seg, seg) IS ...@@ -138,6 +138,13 @@ COMMENT ON FUNCTION seg_different(seg, seg) IS
-- support routines for indexing -- support routines for indexing
CREATE OR REPLACE FUNCTION seg_cmp(seg, seg)
RETURNS int4
AS 'MODULE_PATHNAME'
LANGUAGE 'C' STRICT;
COMMENT ON FUNCTION seg_cmp(seg, seg) IS 'btree comparison function';
CREATE FUNCTION seg_union(seg, seg) CREATE FUNCTION seg_union(seg, seg)
RETURNS seg RETURNS seg
AS 'MODULE_PATHNAME' AS 'MODULE_PATHNAME'
...@@ -263,8 +270,7 @@ CREATE OPERATOR = ( ...@@ -263,8 +270,7 @@ CREATE OPERATOR = (
NEGATOR = '<>', NEGATOR = '<>',
RESTRICT = eqsel, RESTRICT = eqsel,
JOIN = eqjoinsel, JOIN = eqjoinsel,
SORT1 = '<', MERGES
SORT2 = '<'
); );
CREATE OPERATOR <> ( CREATE OPERATOR <> (
...@@ -333,7 +339,16 @@ AS 'MODULE_PATHNAME' ...@@ -333,7 +339,16 @@ AS 'MODULE_PATHNAME'
LANGUAGE 'C'; LANGUAGE 'C';
-- Create the operator class for indexing -- Create the operator classes for indexing
CREATE OPERATOR CLASS seg_ops
DEFAULT FOR TYPE seg USING btree AS
OPERATOR 1 < ,
OPERATOR 2 <= ,
OPERATOR 3 = ,
OPERATOR 4 >= ,
OPERATOR 5 > ,
FUNCTION 1 seg_cmp(seg, seg);
CREATE OPERATOR CLASS gist_seg_ops CREATE OPERATOR CLASS gist_seg_ops
DEFAULT FOR TYPE seg USING gist DEFAULT FOR TYPE seg USING gist
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
#include <math.h> #include <math.h>
#include "segdata.h" #include "segdata.h"
#include "buffer.h"
#ifdef __CYGWIN__ #ifdef __CYGWIN__
#define HUGE HUGE_VAL #define HUGE HUGE_VAL
...@@ -19,7 +18,7 @@ ...@@ -19,7 +18,7 @@
extern int yylex(); /* defined as seg_yylex in segscan.c */ extern int yylex(); /* defined as seg_yylex in segscan.c */
extern int significant_digits( char *str ); /* defined in seg.c */ extern int significant_digits( char *str ); /* defined in seg.c */
int seg_yyerror( char *msg ); void seg_yyerror(const char *message);
int seg_yyparse( void *result ); int seg_yyparse( void *result );
float seg_atof( char *value ); float seg_atof( char *value );
...@@ -72,7 +71,6 @@ range: ...@@ -72,7 +71,6 @@ range:
((SEG *)result)->lower = $1.val; ((SEG *)result)->lower = $1.val;
((SEG *)result)->upper = $3.val; ((SEG *)result)->upper = $3.val;
if ( ((SEG *)result)->lower > ((SEG *)result)->upper ) { if ( ((SEG *)result)->lower > ((SEG *)result)->upper ) {
reset_parse_buffer();
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE), (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("swapped boundaries: %g is greater than %g", errmsg("swapped boundaries: %g is greater than %g",
...@@ -145,7 +143,6 @@ float seg_atof ( char *value ) { ...@@ -145,7 +143,6 @@ float seg_atof ( char *value ) {
if ( errno ) { if ( errno ) {
snprintf(buf, 256, "numeric value %s unrepresentable", value); snprintf(buf, 256, "numeric value %s unrepresentable", value);
reset_parse_buffer();
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR), (errcode(ERRCODE_SYNTAX_ERROR),
errmsg("syntax error"), errmsg("syntax error"),
...@@ -156,35 +153,4 @@ float seg_atof ( char *value ) { ...@@ -156,35 +153,4 @@ float seg_atof ( char *value ) {
} }
int seg_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 near position %d, character ('%c', \\%03o), input: '%s'\n",
msg,
position,
parse_buffer()[position - 1],
parse_buffer()[position - 1],
parse_buffer()
);
reset_parse_buffer();
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("syntax error"),
errdetail("%s", buf)));
return 0;
}
#include "segscan.c" #include "segscan.c"
...@@ -5,32 +5,29 @@ ...@@ -5,32 +5,29 @@
#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;
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 seg_yylex YY_PROTO(( void )); \ int seg_yylex(void);
int seg_yylex YY_PROTO(( void ))
#define yylval seg_yylval
/* redefined YY_INPUT reads byte-wise from the memory area defined in buffer.c */ void seg_scanner_init(const char *str);
#undef YY_INPUT void seg_scanner_finish(void);
#define YY_INPUT(buf,result,max_size) \
{ \
int c = read_parse_buffer(); \
result = (c == '\0') ? YY_NULL : (buf[0] = c, 1); \
}
void seg_flush_scanner_buffer(void);
%} %}
%option 8bit %option 8bit
%option never-interactive %option never-interactive
%option nounput %option nounput
%option noyywrap %option noyywrap
%option prefix="seg_yy"
range (\.\.)(\.)? range (\.\.)(\.)?
...@@ -52,8 +49,61 @@ float ({integer}|{real})([eE]{integer})? ...@@ -52,8 +49,61 @@ float ({integer}|{real})([eE]{integer})?
%% %%
int seg_yylex(); void
yyerror(const char *message)
{
if (*yytext == YY_END_OF_BUFFER_CHAR)
{
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("bad seg representation"),
/* translator: %s is typically "syntax error" */
errdetail("%s at end of input", message)));
}
else
{
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("bad seg representation"),
/* translator: first %s is typically "syntax error" */
errdetail("%s at or near \"%s\"", message, yytext)));
}
}
/*
* Called before any actual parsing is done
*/
void
seg_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 seg_flush_scanner_buffer(void) { /*
YY_FLUSH_BUFFER; * Called after parsing is done to clean up after seg_scanner_init()
*/
void
seg_scanner_finish(void)
{
yy_delete_buffer(scanbufhandle);
pfree(scanbuf);
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment