1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-20 05:03:10 +03:00

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.
This commit is contained in:
Tom Lane
2003-09-14 02:18:49 +00:00
parent 03e47392e0
commit 043be9ad96
9 changed files with 116 additions and 191 deletions

View File

@ -1,11 +1,11 @@
# $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
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

View File

@ -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

View File

@ -1,84 +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 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;
}

View File

@ -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);

View File

@ -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

View File

@ -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)
{ {
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)
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)
{ {

View File

@ -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
-- 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 = (
NEGATOR = '<>', NEGATOR = '<>',
RESTRICT = eqsel, RESTRICT = eqsel,
JOIN = eqjoinsel, JOIN = eqjoinsel,
SORT1 = '<', MERGES
SORT2 = '<'
); );
CREATE OPERATOR <> ( CREATE OPERATOR <> (
@ -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

View File

@ -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 @@
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:
((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 ) {
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 ) {
} }
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"

View File

@ -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})?
%% %%
int seg_yylex(); void
yyerror(const char *message)
void seg_flush_scanner_buffer(void) { {
YY_FLUSH_BUFFER; 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);
}
/*
* Called after parsing is done to clean up after seg_scanner_init()
*/
void
seg_scanner_finish(void)
{
yy_delete_buffer(scanbufhandle);
pfree(scanbuf);
} }