*** empty log message ***

This commit is contained in:
Michael Meskes 2000-01-27 19:01:35 +00:00
parent dd979f66be
commit b53955f38a
14 changed files with 281 additions and 327 deletions

View 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.

View 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;

View File

@ -19,25 +19,26 @@
*/
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 *

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

View 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 *);

View 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)

View 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);
}
s_enum: S_ENUM opt_symbol { $$ = cat2_str(make_str("enum"), $2); }
| SQL_ENUM 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_union: UNION 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_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(); }
| S_AUTO { $$ = make_str("auto"); }
| S_CONST { $$ = make_str("const"); }
| S_EXTERN { $$ = make_str("extern"); }
| S_REGISTER { $$ = make_str("register"); }
| S_STATIC { $$ = make_str("static"); }
| 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("("); }

View File

@ -138,3 +138,5 @@ struct arguments
struct variable *indicator;
struct arguments *next;
};
enum errortype {ET_WARN, ET_ERROR, ET_FATAL};

View 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

View File

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

View 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]);

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

View 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");

View File

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