]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
*** empty log message ***
authorMichael Meskes <meskes@postgresql.org>
Thu, 27 Jan 2000 19:01:35 +0000 (19:01 +0000)
committerMichael Meskes <meskes@postgresql.org>
Thu, 27 Jan 2000 19:01:35 +0000 (19:01 +0000)
14 files changed:
src/interfaces/ecpg/ChangeLog
src/interfaces/ecpg/lib/ecpglib.c
src/interfaces/ecpg/preproc/c_keywords.c
src/interfaces/ecpg/preproc/ecpg.c
src/interfaces/ecpg/preproc/extern.h
src/interfaces/ecpg/preproc/pgc.l
src/interfaces/ecpg/preproc/preproc.y
src/interfaces/ecpg/preproc/type.h
src/interfaces/ecpg/test/Makefile
src/interfaces/ecpg/test/stp.pgc [new file with mode: 0644]
src/interfaces/ecpg/test/test1.pgc
src/interfaces/ecpg/test/test2.pgc
src/interfaces/ecpg/test/test3.pgc
src/interfaces/ecpg/test/test5.pgc [new file with mode: 0644]

index bb8517a4b0f7191d0cb31b95b455cfcdbc19e876..aaa63f616a211df44e86d28fbec84b419164e8ae 100644 (file)
@@ -775,5 +775,21 @@ Mon Jan 17 21:55:40 CET 2000
        - Synced preproc.y with gram.y.
        - Changed FETCH syntax using Rene's final patch. Made it more
          standard compliant.
+
+Thu Jan 20 10:00:50 CET 2000
+
+       - Synced preproc.y with gram.y.
+
+Fri Jan 21 14:52:27 CET 2000
+
+       - Added more log output to ecpglib.
+
+Thu Jan 27 08:12:05 CET 2000
+
+       - Added another patch by Rene Hogendoorn.
+       - Fixed error messages in pgc.l.
+       - Improved variable parsing.
+       - Synced preproc.y with gram.y.
        - Set library version to 3.0.10.
        - Set ecpg version to 2.7.0.
+
index 5190dd0635c6409a1904189235873ff38ff17b39..7e755782715b8d99b22fbc35acec7212c0e1696b 100644 (file)
@@ -9,7 +9,7 @@
    slightly modified)
  */
 
-/* Taken over as part of PostgreSQL by Michael Meskes <meskes@debian.org>
+/* Taken over as part of PostgreSQL by Michael Meskes <meskes@postgresql.org>
    on Feb. 5th, 1998 */
 
 #include <stdio.h>
@@ -724,6 +724,9 @@ ECPGexecute(struct statement * stmt)
                                                *((void **) var->pointer) = var->value;
                                                add_mem(var->value, stmt->lineno);
                                        }
+                                       
+                                       
+                                       ECPGlog("ECPGexecute line %d: TYPE db: %d c: %d\n", stmt->lineno, PQftype(results, act_field), var->type);
 
                                        for (act_tuple = 0; act_tuple < ntuples && status; act_tuple++)
                                        {
@@ -764,7 +767,7 @@ ECPGexecute(struct statement * stmt)
                                                                status = false;
                                                                break;
                                                }
-
+                                               
                                                switch (var->type)
                                                {
                                                                long            res;
index 4d04c00dd9cae5b5c996ac00bf9cb50fb223236d..15e1494eea5fe1c414e5248ded28dbc4b193fe9e 100644 (file)
  */
 static ScanKeyword ScanKeywords[] = {
        /* name                                 value                   */
-       {"VARCHAR", S_VARCHAR},
+       {"VARCHAR", VARCHAR},
        {"auto", S_AUTO},
-       {"bool", S_BOOL},
-       {"char", S_CHAR},
+       {"bool", SQL_BOOL},
+       {"char", CHAR},
        {"const", S_CONST},
-       {"double", S_DOUBLE},
-       {"enum", S_ENUM},
+       {"double", DOUBLE},
+       {"enum", SQL_ENUM},
        {"extern", S_EXTERN},
-       {"float", S_FLOAT},
-       {"int", S_INT},
-       {"long", S_LONG},
+       {"float", FLOAT},
+       {"int", SQL_INT},
+       {"long", SQL_LONG},
        {"register", S_REGISTER},
-       {"short", S_SHORT},
-       {"signed", S_SIGNED},
+       {"short", SQL_SHORT},
+       {"signed", SQL_SIGNED},
        {"static", S_STATIC},
-       {"struct", S_STRUCT},
-       {"union", S_UNION},
-       {"unsigned", S_UNSIGNED},
-       {"varchar", S_VARCHAR},
+       {"struct", SQL_STRUCT},
+       {"union", UNION},
+       {"unsigned", SQL_UNSIGNED},
+       {"varchar", VARCHAR},
+       {"volatile", S_VOLATILE},
 };
 
 ScanKeyword *
index 46c29ba2a2d0fe8d6d800e2826957555613c9788..2da1761c6d21fb7592ea3a926eb59f70710722e3 100644 (file)
@@ -1,5 +1,5 @@
 /* New main for ecpg, the PostgreSQL embedded SQL precompiler. */
-/* (C) Michael Meskes <meskes@debian.org> Feb 5th, 1998 */
+/* (C) Michael Meskes <meskes@postgresql.org> Feb 5th, 1998 */
 /* Placed under the same copyright as PostgresSQL */
 
 #include <unistd.h>
index e921cf664fb5274654e41a32d3b96adeb203b5d1..682ead43ec81b9154c66c2632833f16da61b7f80 100644 (file)
@@ -40,6 +40,7 @@ extern int    yylex(void);
 extern void yyerror(char *);
 extern void *mm_alloc(size_t), *mm_realloc(void *, size_t);
 extern char *mm_strdup(const char *);
+extern void mmerror(enum errortype, char * );
 ScanKeyword *ScanECPGKeywordLookup(char *);
 ScanKeyword *ScanCKeywordLookup(char *);
 
index 7477676d2ffd42aa60397c18038022b3d640bd67..f69f21b94d0dc138790545874f1849e3e147fcb4 100644 (file)
@@ -12,7 +12,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.49 2000/01/26 05:58:41 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.50 2000/01/27 19:00:39 meskes Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -246,7 +246,7 @@ cppline                     {space}*#(.*\\{line_end})*.*
                                        errno = 0;
                                        yylval.ival = strtol(literalbuf, &endptr, 2);
                                        if (*endptr != '\0' || errno == ERANGE)
-                                               yyerror("ERROR: Bad binary integer input!");
+                                               mmerror(ET_ERROR, "Bad binary integer input!");
                                        return ICONST;
                                }
 <xh>{xhinside} |
@@ -268,7 +268,7 @@ cppline                     {space}*#(.*\\{line_end})*.*
                                        errno = 0;
                                        yylval.ival = strtol(literalbuf, &endptr, 16);
                                        if (*endptr != '\0' || errno == ERANGE)
-                                               yyerror("ERROR: Bad hexadecimal integer input");
+                                               mmerror(ET_ERROR, "Bad hexadecimal integer input");
                                        return ICONST;
                                }
 
@@ -355,7 +355,7 @@ cppline                     {space}*#(.*\\{line_end})*.*
                                                errno = 0;
                                                yylval.dval = strtod((char *)yytext,&endptr);
                                                if (*endptr != '\0' || errno == ERANGE)
-                                                       yyerror("ERROR: Bad float8 input");
+                                                       mmerror(ET_ERROR, "Bad float8 input");
                                                return FCONST;
                                        }
                                        yylval.str = mm_strdup((char*)yytext);
@@ -367,7 +367,7 @@ cppline                     {space}*#(.*\\{line_end})*.*
                                        errno = 0;
                                        yylval.dval = strtod((char *)yytext,&endptr);
                                        if (*endptr != '\0' || errno == ERANGE)
-                                               yyerror("ERROR: Bad float input");
+                                               mmerror(ET_ERROR, "Bad float input");
                                        return FCONST;
                                }
 <SQL>:{identifier}(("->"|\.){identifier})*     {
@@ -385,6 +385,13 @@ cppline                    {space}*#(.*\\{line_end})*.*
                                                if (isascii((unsigned char)lower_text[i]) && isupper(lower_text[i]))
                                                        lower_text[i] = tolower(lower_text[i]);
 
+                                       if (i >= NAMEDATALEN)
+                                       {
+                                               sprintf(errortext, "Identifier \"%s\" will be truncated to \"%.*s\"", yytext, NAMEDATALEN-1, yytext);
+                                               mmerror (ET_WARN, errortext);
+                                                yytext[NAMEDATALEN-1] = '\0';
+                                       }
+
                                        keyword = ScanKeywordLookup((char*)lower_text);
                                        if (keyword != NULL) {
                                                return keyword->value;
@@ -509,10 +516,10 @@ cppline                   {space}*#(.*\\{line_end})*.*
 
 <C,xskip>{exec_sql}{elif}{space_or_nl}*        {       /* pop stack */
                                                if ( preproc_tos == 0 ) {
-                                                   yyerror("ERROR: missing matching 'EXEC SQL IFDEF / EXEC SQL IFNDEF'");
+                                                   mmerror(ET_FATAL, "Missing matching 'EXEC SQL IFDEF / EXEC SQL IFNDEF'");
                                                }
                                                else if ( stacked_if_value[preproc_tos].else_branch ) {
-                                                   yyerror("ERROR: missing 'EXEC SQL ENDIF;'");
+                                                   mmerror(ET_FATAL, "Missing 'EXEC SQL ENDIF;'");
                                                }
                                                else {
                                                    preproc_tos--;
@@ -523,7 +530,7 @@ cppline                     {space}*#(.*\\{line_end})*.*
 
 <C,xskip>{exec_sql}{else}{space_or_nl}*";" {   /* only exec sql endif pops the stack, so take care of duplicated 'else' */
                                                if ( stacked_if_value[preproc_tos].else_branch ) {
-                                                   yyerror("ERROR: duplicated 'EXEC SQL ELSE;'");
+                                                   mmerror(ET_FATAL, "Duplicated 'EXEC SQL ELSE;'");
                                                }
                                                else {
                                                    stacked_if_value[preproc_tos].else_branch = TRUE;
@@ -541,7 +548,7 @@ cppline                     {space}*#(.*\\{line_end})*.*
                                        }
 <C,xskip>{exec_sql}{endif}{space_or_nl}*";" { 
                                                if ( preproc_tos == 0 ) {
-                                                   yyerror("ERROR: unmatched 'EXEC SQL ENDIF;'");
+                                                   mmerror(ET_FATAL, "Unmatched 'EXEC SQL ENDIF;'");
                                                }
                                                else {
                                                    preproc_tos--;
@@ -559,7 +566,7 @@ cppline                     {space}*#(.*\\{line_end})*.*
 
 <xcond>{identifier}{space_or_nl}*";" {
                                        if ( preproc_tos >= MAX_NESTED_IF-1 ) {
-                                           yyerror("ERROR: too many nested 'EXEC SQL IFDEF' conditions");
+                                           mmerror(ET_FATAL, "Too many nested 'EXEC SQL IFDEF' conditions");
                                        }
                                        else {
                                            struct _defines *defptr;
@@ -680,7 +687,7 @@ cppline                     {space}*#(.*\\{line_end})*.*
                          if ( preproc_tos > 0 ) {
                              preproc_tos = 0;
 
-                             yyerror("ERROR: missing 'EXEC SQL ENDIF;'");
+                             mmerror(ET_FATAL, "Missing 'EXEC SQL ENDIF;'");
                          }
 
                          if (yy_buffer == NULL)
index c43ffcfa577fbd9407b033a2c5f85879cd780777..7b8d16f31a474738e1abc94fd153ed4ac0ce2421 100644 (file)
@@ -24,6 +24,7 @@ int   struct_level = 0;
 char   errortext[128];
 static char    *connection = NULL;
 static int      QueryIsRule = 0, ForUpdateNotAllowed = 0, FoundInto = 0;
+static int     initializer = 0;
 static struct this_type actual_type[STRUCT_DEPTH];
 static char     *actual_storage[STRUCT_DEPTH];
 static char     *actual_startline[STRUCT_DEPTH];
@@ -36,12 +37,10 @@ struct variable no_indicator = {"no_indicator", &ecpg_no_indicator, 0, NULL};
 
 struct ECPGtype ecpg_query = {ECPGt_char_variable, 0L, {NULL}};
 
-enum errortype {ET_WARN, ET_ERROR, ET_FATAL};
-
 /*
  * Handle parsing errors and warnings
  */
-static void
+void
 mmerror(enum errortype type, char * error)
 {
 
@@ -643,10 +642,8 @@ adjust_array(enum ECPGttype type_enum, int *dimension, int *length, int type_dim
 %token         SQL_VAR SQL_WHENEVER
 
 /* C token */
-%token         S_ANYTHING S_AUTO S_BOOL S_CHAR S_CONST S_DOUBLE S_ENUM S_EXTERN
-%token         S_FLOAT S_INT S
-%token         S_LONG S_REGISTER S_SHORT S_SIGNED S_STATIC S_STRUCT
-%token         S_UNION S_UNSIGNED S_VARCHAR
+%token         S_ANYTHING S_AUTO S_CONST S_EXTERN
+%token         S_REGISTER S_STATIC S_VOLATILE
 
 /* I need this and don't know where it is defined inside the backend */
 %token         TYPECAST
@@ -814,21 +811,20 @@ adjust_array(enum ECPGttype type_enum, int *dimension, int *length, int type_dim
 %type  <str>   indicator ECPGExecute ECPGPrepare ecpg_using
 %type  <str>    storage_clause opt_initializer c_anything blockstart
 %type  <str>    blockend variable_list variable c_thing c_term
-%type  <str>   opt_pointer cvariable ECPGDisconnect dis_name
+%type  <str>   opt_pointer cvariable ECPGDisconnect dis_name storage_modifier
 %type  <str>   stmt symbol opt_symbol ECPGRelease execstring server_name
 %type  <str>   connection_object opt_server opt_port c_stuff opt_reference
 %type  <str>    user_name opt_user char_variable ora_user ident
 %type  <str>    db_prefix server opt_options opt_connection_name c_list
-%type  <str>   ECPGSetConnection cpp_line s_enum ECPGTypedef c_args
+%type  <str>   ECPGSetConnection cpp_line ECPGTypedef c_args
 %type  <str>   enum_type civariableonly ECPGCursorStmt ECPGDeallocate
-%type  <str>   ECPGFree ECPGDeclare ECPGVar sql_variable_declarations
-%type  <str>   sql_declaration sql_variable_list sql_variable opt_at
+%type  <str>   ECPGFree ECPGDeclare ECPGVar opt_at enum_definition
 %type  <str>    struct_type s_struct declaration declarations variable_declarations
 %type  <str>    s_struct s_union union_type ECPGSetAutocommit on_off
 
-%type  <type_enum> simple_type varchar_type
+%type  <type_enum> simple_type signed_type unsigned_type varchar_type
 
-%type  <type>  type ctype
+%type  <type>  type
 
 %type  <action> action
 
@@ -943,7 +939,8 @@ stmt:  AlterTableStmt                       { output_statement($1, 0); }
                                                output_statement($1, 0);
                                        }
                | ECPGFree              {
-                                               fprintf(yyout, "{ ECPGdeallocate(__LINE__, %s, \"%s\");", connection ? connection : "NULL", $1); 
+                                               fprintf(yyout, "{ ECPGdeallocate(__LINE__, \"%s\");", $1);
+
                                                whenever_action(2);
                                                free($1);
                                        }
@@ -1320,9 +1317,9 @@ DEFAULT} */
                }
 /* ALTER TABLE <name> DROP [COLUMN] <name> {RESTRICT|CASCADE} */
        | ALTER TABLE relation_name opt_inh_star DROP opt_column ColId
-               drop_behavior
+               /* drop_behavior */
                {
-                       $$ = cat_str(6, make_str("alter table"), $3, $4, make_str("drop"), $6, $7, $8);
+                       $$ = cat_str(5, make_str("alter table"), $3, $4, make_str("drop"), $6, $7);
                }
 /* ALTER TABLE <name> ADD CONSTRAINT ... */
        | ALTER TABLE relation_name opt_inh_star ADD TableConstraint
@@ -2584,21 +2581,21 @@ createdb_opt_location:  LOCATION '=' Sconst     { $$ = cat2_str(make_str("location =
 createdb_opt_encoding:  ENCODING '=' Sconst  
                        {
 #ifndef MULTIBYTE
-                               mmerror(ET_ERROR, "WITH ENCODING is not supported.");
+                               mmerror(ET_ERROR, "Multi-byte support is not enabled.");
 #endif
                                $$ = cat2_str(make_str("encoding ="), $3);
                        }
                | ENCODING '=' Iconst  
                        {
 #ifndef MULTIBYTE
-                               mmerror(ET_ERROR, "WITH ENCODING is not supported.");
+                               mmerror(ET_ERROR, "Multi-byte support is not enabled.");
 #endif
                                $$ = cat2_str(make_str("encoding ="), $3);
                        }
                | ENCODING '=' DEFAULT
                        {
 #ifndef MULTIBYTE
-                               mmerror(ET_ERROR, "WITH ENCODING is not supported.");
+                               mmerror(ET_ERROR, "Multi-byte support is not enabled.");
 #endif
                                $$ = make_str("encoding = default");
                        }
@@ -3405,17 +3402,16 @@ opt_decimal:  '(' Iconst ',' Iconst ')'
                                }
                ;
 
-/* SQL92 character data types
+/* 
+ * SQL92 character data types
  * The following implements CHAR() and VARCHAR().
  *                                                             - ay 6/95
  */
 Character:  character '(' Iconst ')'
                                {
-                                       if (strncasecmp($1, "char", strlen("char")) && strncasecmp($1, "varchar", strlen("varchar")))
-                                               mmerror(ET_ERROR, "internal parsing error; unrecognized character type");
                                        if (atol($3) < 1)
                                        {
-                                               sprintf(errortext, "length for '%s' type must be at least 1",$1);
+                                               sprintf(errortext, "length for type '%s' type must be at least 1",$1);
                                                mmerror(ET_ERROR, errortext);
                                        }
                                        else if (atol($3) > MaxAttrSize)
@@ -4332,7 +4328,9 @@ ColLabel:  ColId                  { $$ = $1; }
                | EXPLAIN               { $$ = make_str("explain"); }
                | EXTEND                { $$ = make_str("extend"); }
                | FALSE_P               { $$ = make_str("false"); }
+               | FLOAT                 { $$ = make_str("float"); }
                | FOREIGN               { $$ = make_str("foreign"); }
+               | GLOBAL                { $$ = make_str("global"); }
                | GROUP                 { $$ = make_str("group"); }
                | LISTEN                { $$ = make_str("listen"); }
                | LOAD                  { $$ = make_str("load"); }
@@ -4620,30 +4618,40 @@ variable_declarations:  /* empty */ { $$ = EMPTY; }
 declarations:  declaration { $$ = $1; }
                        | declarations declaration { $$ = cat2_str($1, $2); }
 
-declaration: storage_clause
+declaration: storage_clause storage_modifier
        {
-               actual_storage[struct_level] = mm_strdup($1);
+               actual_storage[struct_level] = cat2_str(mm_strdup($1), mm_strdup($2));
                actual_startline[struct_level] = hashline_number();
        }
        type
        {
-               actual_type[struct_level].type_enum = $3.type_enum;
-               actual_type[struct_level].type_dimension = $3.type_dimension;
-               actual_type[struct_level].type_index = $3.type_index;
+               actual_type[struct_level].type_enum = $4.type_enum;
+               actual_type[struct_level].type_dimension = $4.type_dimension;
+               actual_type[struct_level].type_index = $4.type_index;
+
+               /* we do not need the string "varchar" for output */
+               /* so replace it with an empty string */
+               if ($4.type_enum == ECPGt_varchar)
+               {
+                       free($4.type_str);
+                       $4.type_str=EMPTY;
+               }
        }
        variable_list ';'
        {
-               $$ = cat_str(5, actual_startline[struct_level], $1, $3.type_str, $5, make_str(";\n"));
+               $$ = cat_str(6, actual_startline[struct_level], $1, $2, $4.type_str, $6, make_str(";\n"));
        }
 
 storage_clause : S_EXTERN      { $$ = make_str("extern"); }
        | S_STATIC              { $$ = make_str("static"); }
-       | S_SIGNED              { $$ = make_str("signed"); }
-       | S_CONST               { $$ = make_str("const"); }
        | S_REGISTER            { $$ = make_str("register"); }
        | S_AUTO                        { $$ = make_str("auto"); }
        | /* empty */           { $$ = EMPTY; }
 
+storage_modifier : S_CONST      { $$ = make_str("const"); }
+       | S_VOLATILE             { $$ = make_str("volatile"); }
+       | /* empty */            { $$ = EMPTY; }
+
 type: simple_type
                {
                        $$.type_enum = $1;
@@ -4654,7 +4662,7 @@ type: simple_type
        | varchar_type
                {
                        $$.type_enum = ECPGt_varchar;
-                       $$.type_str = EMPTY;
+                       $$.type_str = make_str("varchar");;
                        $$.type_dimension = -1;
                        $$.type_index = -1;
                }
@@ -4691,12 +4699,16 @@ type: simple_type
                        struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list);
                }
 
-enum_type: s_enum '{' c_list '}'
+enum_type: SQL_ENUM opt_symbol enum_definition
        {
-               $$ = cat_str(4, $1, make_str("{"), $3, make_str("}"));
+               $$ = cat_str(3, make_str("enum"), $2, $3);
+       }
+       |  SQL_ENUM symbol
+       {
+               $$ = cat2_str(make_str("enum"), $2);
        }
-       
-s_enum: S_ENUM opt_symbol      { $$ = cat2_str(make_str("enum"), $2); }
+
+enum_definition: '{' c_list '}'        { $$ = cat_str(3, make_str("{"), $2, make_str("}")); }
 
 struct_type: s_struct '{' variable_declarations '}'
        {
@@ -4712,38 +4724,64 @@ union_type: s_union '{' variable_declarations '}'
            $$ = cat_str(4, $1, make_str("{"), $3, make_str("}"));
        }
 
-s_struct : S_STRUCT opt_symbol
+s_struct: SQL_STRUCT opt_symbol
         {
             struct_member_list[struct_level++] = NULL;
             if (struct_level >= STRUCT_DEPTH)
                  mmerror(ET_ERROR, "Too many levels in nested structure definition");
+
+           /* reset this variable so we see if there was */
+           /* an initializer specified */
+           initializer = 0;
+
            $$ = cat2_str(make_str("struct"), $2);
        }
 
-s_union : S_UNION opt_symbol
+s_unionUNION opt_symbol
         {
             struct_member_list[struct_level++] = NULL;
             if (struct_level >= STRUCT_DEPTH)
                  mmerror(ET_ERROR, "Too many levels in nested structure definition");
+
+           /* reset this variable so we see if there was */
+           /* an initializer specified */
+           initializer = 0;
+
            $$ = cat2_str(make_str("union"), $2);
        }
 
 opt_symbol: /* empty */        { $$ = EMPTY; }
        | symbol                { $$ = $1; }
 
-simple_type: S_SHORT           { $$ = ECPGt_short; }
-           | S_UNSIGNED S_SHORT { $$ = ECPGt_unsigned_short; }
-          | S_INT              { $$ = ECPGt_int; }
-           | S_UNSIGNED S_INT  { $$ = ECPGt_unsigned_int; }
-          | S_LONG             { $$ = ECPGt_long; }
-           | S_UNSIGNED S_LONG { $$ = ECPGt_unsigned_long; }
-           | S_FLOAT           { $$ = ECPGt_float; }
-           | S_DOUBLE          { $$ = ECPGt_double; }
-          | S_BOOL             { $$ = ECPGt_bool; };
-          | S_CHAR             { $$ = ECPGt_char; }
-           | S_UNSIGNED S_CHAR { $$ = ECPGt_unsigned_char; }
+simple_type: unsigned_type             { $$=$1; }
+       |       opt_signed signed_type  { $$=$2; }
+       ;
 
-varchar_type:  S_VARCHAR               { $$ = ECPGt_varchar; }
+unsigned_type: SQL_UNSIGNED SQL_SHORT                  { $$ = ECPGt_unsigned_short; }
+               | SQL_UNSIGNED SQL_SHORT SQL_INT        { $$ = ECPGt_unsigned_short; }
+               | SQL_UNSIGNED                          { $$ = ECPGt_unsigned_int; }
+               | SQL_UNSIGNED SQL_INT                  { $$ = ECPGt_unsigned_int; }
+               | SQL_UNSIGNED SQL_LONG                 { $$ = ECPGt_unsigned_long; }
+               | SQL_UNSIGNED SQL_LONG SQL_INT         { $$ = ECPGt_unsigned_long; }
+               | SQL_UNSIGNED CHAR                     { $$ = ECPGt_unsigned_char; }
+               ;
+
+signed_type: SQL_SHORT          { $$ = ECPGt_short; }
+           | SQL_SHORT SQL_INT  { $$ = ECPGt_short; }
+           | SQL_INT            { $$ = ECPGt_int; }
+           | SQL_LONG           { $$ = ECPGt_long; }
+           | SQL_LONG SQL_INT   { $$ = ECPGt_long; }
+           | SQL_BOOL          { $$ = ECPGt_bool; };
+           | FLOAT             { $$ = ECPGt_float; }
+           | DOUBLE            { $$ = ECPGt_double; }
+           | CHAR              { $$ = ECPGt_char; }
+          ;
+
+opt_signed:    SQL_SIGNED
+       |       /* EMPTY */
+       ;
+
+varchar_type:  VARCHAR         { $$ = ECPGt_varchar; }
 
 variable_list: variable 
        {
@@ -4830,7 +4868,10 @@ variable: opt_pointer symbol opt_array_bounds opt_initializer
                }
 
 opt_initializer: /* empty */           { $$ = EMPTY; }
-       | '=' c_term                    { $$ = cat2_str(make_str("="), $2); }
+       | '=' c_term                    { 
+                                               initializer = 1;
+                                               $$ = cat2_str(make_str("="), $2);
+                                       }
 
 opt_pointer: /* empty */       { $$ = EMPTY; }
        | '*'                   { $$ = make_str("*"); }
@@ -4966,19 +5007,24 @@ ECPGSetConnection:  SET SQL_CONNECTION to_equal connection_object
 /*
  * define a new type for embedded SQL
  */
-ECPGTypedef: TYPE_P symbol IS ctype opt_type_array_bounds opt_reference
+ECPGTypedef: TYPE_P symbol IS type opt_type_array_bounds opt_reference
        {
                /* add entry to list */
                struct typedefs *ptr, *this;
                int dimension = $5.index1;
                int length = $5.index2;
 
+               if (($4.type_enum == ECPGt_struct ||
+                    $4.type_enum == ECPGt_union) &&
+                   initializer == 1)
+                       mmerror(ET_ERROR, "Initializer not allowed in EXEC SQL VAR command");
+
                for (ptr = types; ptr != NULL; ptr = ptr->next)
                {
                        if (strcmp($2, ptr->name) == 0)
                        {
                                /* re-definition is a bug */
-                               sprintf(errortext, "type %s already defined", $2);
+                               sprintf(errortext, "Type %s already defined", $2);
                                mmerror(ET_ERROR, errortext);
                        }
                }
@@ -5050,237 +5096,21 @@ opt_type_array_bounds:  '[' ']' opt_type_array_bounds
 opt_reference: SQL_REFERENCE { $$ = make_str("reference"); }
        | /* empty */        { $$ = EMPTY; }
 
-ctype: CHAR
-       {
-               $$.type_str = make_str("char");
-                $$.type_enum = ECPGt_char;
-               $$.type_index = -1;
-               $$.type_dimension = -1;
-       }
-       | VARCHAR
-       {
-               $$.type_str = make_str("varchar");
-                $$.type_enum = ECPGt_varchar;
-               $$.type_index = -1;
-               $$.type_dimension = -1;
-       }
-       | FLOAT
-       {
-               $$.type_str = make_str("float");
-                $$.type_enum = ECPGt_float;
-               $$.type_index = -1;
-               $$.type_dimension = -1;
-       }
-       | DOUBLE
-       {
-               $$.type_str = make_str("double");
-                $$.type_enum = ECPGt_double;
-               $$.type_index = -1;
-               $$.type_dimension = -1;
-       }
-       | opt_signed SQL_INT
-       {
-               $$.type_str = make_str("int");
-                       $$.type_enum = ECPGt_int;
-               $$.type_index = -1;
-               $$.type_dimension = -1;
-       }
-       | SQL_ENUM
-       {
-               $$.type_str = make_str("int");
-                       $$.type_enum = ECPGt_int;
-               $$.type_index = -1;
-               $$.type_dimension = -1;
-       }
-       | opt_signed SQL_SHORT
-       {
-               $$.type_str = make_str("short");
-                       $$.type_enum = ECPGt_short;
-               $$.type_index = -1;
-               $$.type_dimension = -1;
-       }
-       | opt_signed SQL_LONG
-       {
-               $$.type_str = make_str("long");
-                       $$.type_enum = ECPGt_long;
-               $$.type_index = -1;
-               $$.type_dimension = -1;
-       }
-       | SQL_BOOL
-       {
-               $$.type_str = make_str("bool");
-                       $$.type_enum = ECPGt_bool;
-               $$.type_index = -1;
-               $$.type_dimension = -1;
-       }
-       | SQL_UNSIGNED SQL_INT
-       {
-               $$.type_str = make_str("unsigned int");
-                       $$.type_enum = ECPGt_unsigned_int;
-               $$.type_index = -1;
-               $$.type_dimension = -1;
-       }
-       | SQL_UNSIGNED SQL_SHORT
-       {
-               $$.type_str = make_str("unsigned short");
-                       $$.type_enum = ECPGt_unsigned_short;
-               $$.type_index = -1;
-               $$.type_dimension = -1;
-       }
-       | SQL_UNSIGNED SQL_LONG
-       {
-               $$.type_str = make_str("unsigned long");
-                       $$.type_enum = ECPGt_unsigned_long;
-               $$.type_index = -1;
-               $$.type_dimension = -1;
-       }
-       | SQL_STRUCT
-       {
-               struct_member_list[struct_level++] = NULL;
-               if (struct_level >= STRUCT_DEPTH)
-                       mmerror(ET_ERROR, "Too many levels in nested structure definition");
-       } '{' sql_variable_declarations '}'
-       {
-               ECPGfree_struct_member(struct_member_list[struct_level--]);
-               $$.type_str = cat_str(3, make_str("struct {"), $4, make_str("}"));
-               $$.type_enum = ECPGt_struct;
-                $$.type_index = -1;
-                $$.type_dimension = -1;
-       }
-       | UNION
-       {
-               struct_member_list[struct_level++] = NULL;
-               if (struct_level >= STRUCT_DEPTH)
-                       mmerror(ET_ERROR, "Too many levels in nested structure definition");
-       } '{' sql_variable_declarations '}'
-       {
-               ECPGfree_struct_member(struct_member_list[struct_level--]);
-               $$.type_str = cat_str(3, make_str("union {"), $4, make_str("}"));
-               $$.type_enum = ECPGt_union;
-                $$.type_index = -1;
-                $$.type_dimension = -1;
-       }
-       | symbol
-       {
-               struct typedefs *this = get_typedef($1);
-
-               $$.type_str = mm_strdup($1);
-               $$.type_enum = this->type->type_enum;
-               $$.type_dimension = this->type->type_dimension;
-               $$.type_index = this->type->type_index;
-               struct_member_list[struct_level] = this->struct_member_list;
-       }
-
-opt_signed: SQL_SIGNED | /* empty */
-
-sql_variable_declarations: /* empty */
-       {
-               $$ = EMPTY;
-       }
-       | sql_declaration sql_variable_declarations
-       {
-               $$ = cat2_str($1, $2);
-       }
-       ;
-
-sql_declaration: ctype
-       {
-               actual_type[struct_level].type_enum = $1.type_enum;
-               actual_type[struct_level].type_dimension = $1.type_dimension;
-               actual_type[struct_level].type_index = $1.type_index;
-       }
-       sql_variable_list ';'
-       {
-               $$ = cat_str(3, $1.type_str, $3, make_str(";"));
-       }
-
-sql_variable_list: sql_variable 
-       {
-               $$ = $1;
-       }
-       | sql_variable_list ',' sql_variable
-       {
-               $$ = cat_str(3, $1, make_str(","), $3);
-       }
-
-sql_variable: opt_pointer symbol opt_array_bounds
-               {
-                       int dimension = $3.index1;
-                       int length = $3.index2;
-                       struct ECPGtype * type;
-                        char dim[14L];
-
-                       adjust_array(actual_type[struct_level].type_enum, &dimension, &length, actual_type[struct_level].type_dimension, actual_type[struct_level].type_index, strlen($1));
-
-                       switch (actual_type[struct_level].type_enum)
-                       {
-                          case ECPGt_struct:
-                          case ECPGt_union:
-                               if (dimension < 0)
-                                   type = ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum);
-                               else
-                                   type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum), dimension); 
-
-                               break;
-                           case ECPGt_varchar:
-                               if (dimension == -1)
-                                   type = ECPGmake_simple_type(actual_type[struct_level].type_enum, length);
-                               else
-                                   type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, length), dimension);
-
-                               switch(dimension)
-                               {
-                                  case 0:
-                                      strcpy(dim, "[]");
-                                      break;
-                                 case -1:
-                                  case 1:
-                                      *dim = '\0';
-                                      break;
-                                  default:
-                                      sprintf(dim, "[%d]", dimension);
-                                      break;
-                                }
-
-                               break;
-                           case ECPGt_char:
-                           case ECPGt_unsigned_char:
-                               if (dimension == -1)
-                                   type = ECPGmake_simple_type(actual_type[struct_level].type_enum, length);
-                               else
-                                   type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, length), dimension);
-
-                               break;
-                           default:
-                              if (length >= 0)
-                                   mmerror(ET_ERROR, "No multi-dimensional array support for simple data types");
-
-                               if (dimension < 0)
-                                   type = ECPGmake_simple_type(actual_type[struct_level].type_enum, 1);
-                               else
-                                   type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, 1), dimension);
-
-                               break;
-                       }
-
-                       if (struct_level == 0)
-                               new_variable($2, type);
-                       else
-                               ECPGmake_struct_member($2, type, &(struct_member_list[struct_level - 1]));
-
-                       $$ = cat_str(3, $1, $2, $3.str);
-               }
-
 /*
  * define the type of one variable for embedded SQL
  */
-ECPGVar: SQL_VAR symbol IS ctype opt_type_array_bounds opt_reference
+ECPGVar: SQL_VAR symbol IS type opt_type_array_bounds opt_reference
        {
                struct variable *p = find_variable($2);
                int dimension = $5.index1;
                int length = $5.index2;
                struct ECPGtype * type;
 
+               if (($4.type_enum == ECPGt_struct ||
+                    $4.type_enum == ECPGt_union) &&
+                   initializer == 1)
+                       mmerror(ET_ERROR, "Initializer not allowed in EXEC SQL VAR command");
+
                adjust_array($4.type_enum, &dimension, &length, $4.type_dimension, $4.type_index, strlen($6));
 
                switch ($4.type_enum)
@@ -5561,25 +5391,25 @@ c_anything:  IDENT      { $$ = $1; }
        | '-'           { $$ = make_str("-"); }
        | '/'           { $$ = make_str("/"); }
        | '%'           { $$ = make_str("%"); }
+       | S_ANYTHING    { $$ = make_name(); }
        | S_AUTO        { $$ = make_str("auto"); }
-       | S_BOOL        { $$ = make_str("bool"); }
-       | S_CHAR        { $$ = make_str("char"); }
        | S_CONST       { $$ = make_str("const"); }
-       | S_DOUBLE      { $$ = make_str("double"); }
-       | S_ENUM        { $$ = make_str("enum"); }
        | S_EXTERN      { $$ = make_str("extern"); }
-       | S_FLOAT       { $$ = make_str("float"); }
-        | S_INT                { $$ = make_str("int"); }
-       | S_LONG        { $$ = make_str("long"); }
        | S_REGISTER    { $$ = make_str("register"); }
-       | S_SHORT       { $$ = make_str("short"); }
-       | S_SIGNED      { $$ = make_str("signed"); }
        | S_STATIC      { $$ = make_str("static"); }
-        | S_STRUCT     { $$ = make_str("struct"); }
-        | S_UNION      { $$ = make_str("union"); }
-       | S_UNSIGNED    { $$ = make_str("unsigned"); }
-       | S_VARCHAR     { $$ = make_str("varchar"); }
-       | S_ANYTHING    { $$ = make_name(); }
+       | SQL_BOOL      { $$ = make_str("bool"); }
+       | SQL_ENUM      { $$ = make_str("enum"); }
+        | SQL_INT      { $$ = make_str("int"); }
+       | SQL_LONG      { $$ = make_str("long"); }
+       | SQL_SHORT     { $$ = make_str("short"); }
+       | SQL_SIGNED    { $$ = make_str("signed"); }
+        | SQL_STRUCT   { $$ = make_str("struct"); }
+       | SQL_UNSIGNED  { $$ = make_str("unsigned"); }
+       | CHAR          { $$ = make_str("char"); }
+       | DOUBLE        { $$ = make_str("double"); }
+       | FLOAT         { $$ = make_str("float"); }
+        | UNION                { $$ = make_str("union"); }
+       | VARCHAR       { $$ = make_str("varchar"); }
         | '['          { $$ = make_str("["); }
        | ']'           { $$ = make_str("]"); }
 /*        | '('                { $$ = make_str("("); }
index 1af1e63344fb3f711b37f3a557456c6cf1c848ed..efc8c6692382905f61b6a3ec827f3146567274d0 100644 (file)
@@ -138,3 +138,5 @@ struct arguments
        struct variable *indicator;
        struct arguments *next;
 };
+
+enum errortype {ET_WARN, ET_ERROR, ET_FATAL};
index e183ebc4b9f60b6a07b0cf5721fef72d9334dbdd..0af784f8eab6faff4f1157417f274c82209c650b 100644 (file)
@@ -1,10 +1,12 @@
-all: test1 test2 test3 test4 perftest
+all: stp.so test1 test2 test3 test4 test5 perftest
 
 #LDFLAGS=-g -I /usr/local/pgsql/include -L/usr/local/pgsql/lib -lecpg -lpq -lcrypt
 LDFLAGS=-g -I../include -I/usr/include/postgresql  -L/usr/lib/postgresql -L../lib -lecpg -lpq -lcrypt
+#LDFLAGS=-g -I/usr/include/postgresql -lecpg -lpq -lcrypt
 
 #ECPG=/usr/local/pgsql/bin/ecpg
 ECPG=../preproc/ecpg -I../include
+#ECPG=/usr/bin/ecpg -I/usr/include/postgresql
 
 .SUFFIXES: .pgc .c
 
@@ -12,10 +14,16 @@ test1: test1.c
 test2: test2.c
 test3: test3.c
 test4: test4.c
+test5: test5.c
 perftest: perftest.c
 
 .pgc.c:
        $(ECPG) $? 
 
+stp.so: stp.c
+       cc -fPIC -I../include -I/usr/include/postgresql -c -o stp.o stp.c
+       cc -shared -Wl,-soname,stp.so -o stp.so stp.o -lpq -lecpg
+
+
 clean:
-       -/bin/rm test1 test2 test3 test4 perftest *.c log
+       -/bin/rm test1 test2 test3 test4 test5 perftest *.c log stp.o stp.so
diff --git a/src/interfaces/ecpg/test/stp.pgc b/src/interfaces/ecpg/test/stp.pgc
new file mode 100644 (file)
index 0000000..6021ae0
--- /dev/null
@@ -0,0 +1,16 @@
+EXEC SQL INCLUDE sqlca;
+
+int my_fun (void)
+       {
+       EXEC SQL BEGIN DECLARE SECTION;
+       int                     sql_index = 0;
+       EXEC SQL END DECLARE SECTION;   
+
+       EXEC SQL WHENEVER SQLERROR GOTO Error;
+       EXEC SQL SELECT MIN(index) INTO :sql_index FROM tab;
+
+       return (sql_index);
+
+Error:
+       return (sqlca.sqlcode); 
+       }
index d8980ade54ba2742350c5a571d70668739d3b280..02a631a12f51ba7abe51da0c60db8d16a0fd8bae 100644 (file)
@@ -94,11 +94,20 @@ exec sql end declare section;
         strcpy(msg, "select");
         exec sql select name, amount, letter into :name, :amount, :letter from "Test";
 
+       printf("Database: mm\n");
         for (i=0, j=sqlca.sqlerrd[2]; i<j; i++)
+       {
             printf("name[%d]=%8.8s\tamount[%d]=%d\tletter[%d]=%c\n", i, name[i], i, amount[i],i, letter[i][0]);
+           amount[i]+=1000;
+       }
 
+       strcpy(msg, "insert");
+       exec sql at pm insert into "Test" (name, amount, letter) values (:name, :amount, :letter);
+
+        strcpy(msg, "select");
         exec sql at pm select * into :name, :amount, :letter from "Test";
 
+       printf("Database: pm\n");
         for (i=0, j=sqlca.sqlerrd[2]; i<j; i++)
             printf("name[%d]=%8.8s\tamount[%d]=%d\tletter[%d]=%c\n", i, name[i], i, amount[i],i, letter[i][0]);
         
index 3288b7df6a58bbd5b4b2675fdcd85e48629c8963..2c5d16c4448773216fd5e7a5879a5b77998b1dda 100644 (file)
@@ -62,7 +62,7 @@ exec sql end declare section;
 
        while (1) {
                strcpy(msg, "fetch");
-               exec sql fetch from cur into :personal:ind_personal, :married:ind_married, :children.integer:ind_children.smallint;
+               exec sql fetch cur into :personal:ind_personal, :married:ind_married, :children.integer:ind_children.smallint;
                printf("%8.8s", personal.name.arr);
                if (ind_personal.ind_birth.born >= 0)
                        printf(", born %d", personal.birth.born);
index 8e0f6c30c6ef55259b3c531609e324f6b883af14..8ba8995e3347968720abb97291357e520e9fd2fa 100644 (file)
@@ -19,7 +19,7 @@ exec sql begin declare section;
        int ind_children;
        str *married = NULL;
        char *wifesname="Petra";
-       char *query="select * from meskes where name = :var1";
+       char *query="select * from meskes where name = ?";
 exec sql end declare section;
 
        exec sql declare cur cursor for
@@ -54,7 +54,7 @@ exec sql end declare section;
 
        while (1) {
                strcpy(msg, "fetch");
-               exec sql fetch cur into :personal:ind_personal, :married:ind_married, :children:ind_children;
+               exec sql fetch from cur into :personal:ind_personal, :married:ind_married, :children:ind_children;
                printf("%8.8s", personal.name.arr);
                if (ind_personal.ind_birth.born >= 0)
                        printf(", born %d", personal.birth.born);
@@ -74,7 +74,7 @@ exec sql end declare section;
        exec sql close cur;
 
        /* and now a query with prepare */
-       exec sql prepare MM from "select name, born, age, married, children from meskes where name = ?";
+       exec sql prepare MM from :query;
        exec sql declare prep cursor for MM;
 
        strcpy(msg, "open");
diff --git a/src/interfaces/ecpg/test/test5.pgc b/src/interfaces/ecpg/test/test5.pgc
new file mode 100644 (file)
index 0000000..1e0c60c
--- /dev/null
@@ -0,0 +1,61 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+EXEC SQL INCLUDE sqlca;
+
+static void ErrorExit (void);
+
+int main (void)
+       {
+       EXEC SQL BEGIN DECLARE SECTION;
+       int                     result;
+       int                     values[2], i;
+       EXEC SQL END DECLARE SECTION;
+       FILE *dbgs;
+       
+       
+        if ((dbgs = fopen("log", "w")) != NULL)
+                ECPGdebug(1, dbgs);
+
+       EXEC SQL WHENEVER SQLERROR DO ErrorExit();
+       EXEC SQL CONNECT TO 'mm';
+       EXEC SQL CREATE TABLE tab (index int);
+       EXEC SQL INSERT INTO tab(index) values(14);
+       EXEC SQL INSERT INTO tab(index) values(7);
+       EXEC SQL COMMIT;
+
+       EXEC SQL CREATE FUNCTION my_fun () RETURNS int AS
+               '/home/postgres/pgsql/src/interfaces/ecpg.mm/test/stp.so' LANGUAGE 'C';
+       EXEC SQL COMMIT;
+
+       EXEC SQL SELECT index INTO :values FROM tab;
+       for (i = 0; i < 2; i++)
+               printf("tab[%d] = %d\n", i, values[i]);
+
+       EXEC SQL SELECT my_fun () INTO :result;
+       printf ("result = %d\n", result);
+       
+       EXEC SQL DROP TABLE tab;
+       EXEC SQL DROP FUNCTION my_fun ();
+       EXEC SQL COMMIT;
+       EXEC SQL DISCONNECT;
+
+       if (dbgs != NULL)
+                fclose(dbgs);
+       exit (0);
+       }
+
+       
+static void ErrorExit (void)
+       {
+       EXEC SQL WHENEVER SQLERROR CONTINUE;
+       
+       sqlprint();
+
+       EXEC SQL DROP TABLE tab;
+       EXEC SQL DROP FUNCTION my_fun ();
+       EXEC SQL COMMIT;
+
+       EXEC SQL DISCONNECT;
+       exit (-1);
+       }