]> granicus.if.org Git - postgresql/commitdiff
Make contrib/seg work with flex 2.5.31. Fix it up to have a real
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 14 Sep 2003 02:18:49 +0000 (02:18 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 14 Sep 2003 02:18:49 +0000 (02:18 +0000)
btree operator class, too, since in PG 7.4 you can't GROUP without one.

contrib/seg/Makefile
contrib/seg/README.seg
contrib/seg/buffer.c [deleted file]
contrib/seg/buffer.h [deleted file]
contrib/seg/expected/seg.out
contrib/seg/seg.c
contrib/seg/seg.sql.in
contrib/seg/segparse.y
contrib/seg/segscan.l

index 2fe7ffb06d8ee49400e72ee6c8aa79fec5df6d0d..514a1c4b79321f1b6dd2668bda21d7446fa88252 100644 (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
 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
index 5c80ebcd5c4a450b01fb3ebef81b14f63eab3e32..99ae8648cda258c32cb66a8921f19309341b6920 100644 (file)
@@ -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
diff --git a/contrib/seg/buffer.c b/contrib/seg/buffer.c
deleted file mode 100644 (file)
index b38e4fc..0000000
+++ /dev/null
@@ -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;
-}
diff --git a/contrib/seg/buffer.h b/contrib/seg/buffer.h
deleted file mode 100644 (file)
index eef9124..0000000
+++ /dev/null
@@ -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);
index 341d174e0d6e9e037e1b75dd44323ffd51aa439e..cfa8171e6813b39bf001d80bb3bad311de9de3d7 100644 (file)
@@ -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
index 443fe3f5a26ed01f437a81033d574f87907e810b..c26f9d27cd75843d8ce0f99aa7c00b94d17f60ae 100644 (file)
 #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)
 {
index a1e7e0cf4889fd9a0f3d0b682d09f19ca0e15c1b..2bfd96593dc8f447b68f70e229f61dc89517bbd7 100644 (file)
@@ -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 
index 9c69efede63205448e3f687d2dd24daa59843c99..d8de412081122e1aa892f7dfbb0a6bb6dd6701f6 100644 (file)
@@ -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"
index 190174d7427be5eabcddfa2689d31c7bea64d529..21eb5fa02076e9090c3ac02eadb252c7e3cb1b25 100644 (file)
@@ -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);
 }