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
top_builddir = ../..
include $(top_builddir)/src/Makefile.global
MODULE_big = seg
OBJS = seg.o segparse.o buffer.o
OBJS = seg.o segparse.o
DATA_built = seg.sql
DOCS = README.seg
REGRESS = seg
......@@ -27,7 +27,7 @@ endif
segscan.c: segscan.l
ifdef FLEX
$(FLEX) $(FLEXFLAGS) -Pseg_yy -o'$@' $<
$(FLEX) $(FLEXFLAGS) -o'$@' $<
else
@$(missing) flex $< $@
endif
......
......@@ -56,12 +56,6 @@ Makefile building instructions for the shared library
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.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;
-- invalid input
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;
ERROR: syntax error
DETAIL: syntax error at or near position 1, character ('A', \101), input: 'ABC'
ERROR: bad seg representation
DETAIL: syntax error at or near "A"
SELECT '1ABC'::seg AS seg;
ERROR: syntax error
DETAIL: syntax error at or near position 2, character ('A', \101), input: '1ABC'
ERROR: bad seg representation
DETAIL: syntax error at or near "A"
SELECT '1.'::seg AS seg;
ERROR: syntax error
DETAIL: syntax error at or near position 2, character ('.', \056), input: '1.'
ERROR: bad seg representation
DETAIL: syntax error at or near "."
SELECT '1.....'::seg AS seg;
ERROR: syntax error
DETAIL: syntax error at or near position 6, character ('.', \056), input: '1.....'
ERROR: bad seg representation
DETAIL: syntax error at or near ".."
SELECT '.1'::seg AS seg;
ERROR: syntax error
DETAIL: syntax error at or near position 2, character ('1', \061), input: '.1'
ERROR: bad seg representation
DETAIL: syntax error at or near "."
SELECT '1..2.'::seg AS seg;
ERROR: syntax error
DETAIL: syntax error at or near position 5, character ('.', \056), input: '1..2.'
ERROR: bad seg representation
DETAIL: syntax error at or near "."
SELECT '1 e7'::seg AS seg;
ERROR: syntax error
DETAIL: syntax error at or near position 3, character ('e', \145), input: '1 e7'
ERROR: bad seg representation
DETAIL: syntax error at or near "e"
SELECT '1e700'::seg AS seg;
ERROR: syntax error
DETAIL: numeric value 1e700 unrepresentable
......
......@@ -23,8 +23,10 @@
#define GIST_QUERY_DEBUG
*/
extern void set_parse_buffer(char *str);
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;
......@@ -99,16 +101,13 @@ seg_in(char *str)
{
SEG *result = palloc(sizeof(SEG));
set_parse_buffer(str);
seg_scanner_init(str);
/*
* seg_yydebug = 1;
*/
if (seg_yyparse(result) != 0)
{
pfree(result);
return NULL;
}
seg_yyerror("bogus input");
seg_scanner_finish();
return (result);
}
......@@ -880,7 +879,6 @@ seg_gt(SEG * a, SEG * b)
return seg_cmp(a, b) > 0;
}
bool
seg_ge(SEG * a, SEG * b)
{
......
......@@ -7,12 +7,12 @@ SET search_path = public;
CREATE FUNCTION seg_in(cstring)
RETURNS seg
AS 'MODULE_PATHNAME'
LANGUAGE 'C';
LANGUAGE 'C' IMMUTABLE STRICT;
CREATE FUNCTION seg_out(seg)
RETURNS cstring
AS 'MODULE_PATHNAME'
LANGUAGE 'C';
LANGUAGE 'C' IMMUTABLE STRICT;
CREATE TYPE seg (
INTERNALLENGTH = 12,
......@@ -138,6 +138,13 @@ COMMENT ON FUNCTION seg_different(seg, seg) IS
-- 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)
RETURNS seg
AS 'MODULE_PATHNAME'
......@@ -263,8 +270,7 @@ CREATE OPERATOR = (
NEGATOR = '<>',
RESTRICT = eqsel,
JOIN = eqjoinsel,
SORT1 = '<',
SORT2 = '<'
MERGES
);
CREATE OPERATOR <> (
......@@ -333,7 +339,16 @@ AS 'MODULE_PATHNAME'
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
DEFAULT FOR TYPE seg USING gist
......
......@@ -6,7 +6,6 @@
#include <math.h>
#include "segdata.h"
#include "buffer.h"
#ifdef __CYGWIN__
#define HUGE HUGE_VAL
......@@ -19,7 +18,7 @@
extern int yylex(); /* defined as seg_yylex in segscan.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 );
float seg_atof( char *value );
......@@ -72,7 +71,6 @@ range:
((SEG *)result)->lower = $1.val;
((SEG *)result)->upper = $3.val;
if ( ((SEG *)result)->lower > ((SEG *)result)->upper ) {
reset_parse_buffer();
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("swapped boundaries: %g is greater than %g",
......@@ -145,7 +143,6 @@ float seg_atof ( char *value ) {
if ( errno ) {
snprintf(buf, 256, "numeric value %s unrepresentable", value);
reset_parse_buffer();
ereport(ERROR,
(errcode(ERRCODE_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"
......@@ -5,32 +5,29 @@
#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;
static char *scanbuf;
static int scanbuflen;
/* flex screws a couple symbols when used with the -P option; fix those */
#define YY_DECL int seg_yylex YY_PROTO(( void )); \
int seg_yylex YY_PROTO(( void ))
#define yylval seg_yylval
/* flex 2.5.4 doesn't bother with a decl for this */
int seg_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 seg_flush_scanner_buffer(void);
void seg_scanner_init(const char *str);
void seg_scanner_finish(void);
%}
%option 8bit
%option never-interactive
%option nounput
%option noyywrap
%option prefix="seg_yy"
range (\.\.)(\.)?
......@@ -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