*** empty log message ***
authorMichael Meskes
Thu, 27 Jan 2000 19:01:35 +0000 (19:01 +0000)
committerMichael Meskes
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 debian.org>
+/* Taken over as part of PostgreSQL by Michael Meskes postgresql.org>
    on Feb. 5th, 1998 */
 
 #include 
@@ -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 debian.org> Feb 5th, 1998 */
+/* (C) Michael Meskes postgresql.org> Feb 5th, 1998 */
 /* Placed under the same copyright as PostgresSQL */
 
 #include 
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;
                }
 {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;
                }
 :{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})*.*
 
 {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})*.*
 
 {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})*.*
                    }
 {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})*.*
 
 {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     indicator ECPGExecute ECPGPrepare ecpg_using
 %type      storage_clause opt_initializer c_anything blockstart
 %type      blockend variable_list variable c_thing c_term
-%type     opt_pointer cvariable ECPGDisconnect dis_name
+%type     opt_pointer cvariable ECPGDisconnect dis_name storage_modifier
 %type     stmt symbol opt_symbol ECPGRelease execstring server_name
 %type     connection_object opt_server opt_port c_stuff opt_reference
 %type      user_name opt_user char_variable ora_user ident
 %type      db_prefix server opt_options opt_connection_name c_list
-%type     ECPGSetConnection cpp_line s_enum ECPGTypedef c_args
+%type     ECPGSetConnection cpp_line ECPGTypedef c_args
 %type     enum_type civariableonly ECPGCursorStmt ECPGDeallocate
-%type     ECPGFree ECPGDeclare ECPGVar sql_variable_declarations
-%type     sql_declaration sql_variable_list sql_variable opt_at
+%type     ECPGFree ECPGDeclare ECPGVar opt_at enum_definition
 %type      struct_type s_struct declaration declarations variable_declarations
 %type      s_struct s_union union_type ECPGSetAutocommit on_off
 
-%type   simple_type varchar_type
+%type   simple_type signed_type unsigned_type varchar_type
 
-%type    type ctype
+%type    type
 
 %type   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  DROP [COLUMN]  {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  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
+   {
             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
             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 
+#include 
+
+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);
+   }