+ Sat Feb 21 19:10:55 CET 1998

+
+       - use char[] as string not as array of bytes that is integers
+
+ Sun Feb 22 16:37:36 CET 1998
+
+       - use long for all size variables
+       - added execute immediate statement
+
+ Sun Feb 22 20:41:32 CET 1998
+
+       - use varcharsize = 1 for all simple types, 0 means pointer, > 1
+         means array if type is char resp. unsigned char
+
+ Thu Feb 24 12:26:12 CET 1998
+
+       - allow 'go to' in whenever statement as well as 'goto'
+       - new argument 'stop' for whenever statement

From: Michael Meskes <meskes@topsystem.de>
This commit is contained in:
Marc G. Fournier 1998-02-24 15:52:13 +00:00
parent 0227a4e114
commit 80e12829cf
10 changed files with 247 additions and 105 deletions

View File

@ -38,3 +38,21 @@ Thu Feb 19 12:48:14 CET 1998
- added do option to whenever statement
Sat Feb 21 19:10:55 CET 1998
- use char[] as string not as array of bytes that is integers
Sun Feb 22 16:37:36 CET 1998
- use long for all size variables
- added execute immediate statement
Sun Feb 22 20:41:32 CET 1998
- use varcharsize = 1 for all simple types, 0 means pointer, > 1
means array if type is char resp. unsigned char
Thu Feb 24 12:26:12 CET 1998
- allow 'go to' in whenever statement as well as 'goto'
- new argument 'stop' for whenever statement

View File

@ -1,5 +1,4 @@
SUBDIRS = include lib preproc doc
all install uninstall clean:
$(MAKE) -C include $@
$(MAKE) -C lib $@
$(MAKE) -C preproc $@

View File

@ -40,8 +40,22 @@ could be realised in a script.
Now comes my list (MM):
What do we do with enum data types?
The return code is alway -1 in case of an error. You cannot see which error
occured by examining the return code.
The cursor is opened when the declare statement is issued.
The cursor is opened when the declare statement is issued.
ecpg does not understand enum datatypes.
The is no exec sql prepare statement.
The complete structure definition has to be listed inside the declare
section for ecpg to be able to understand it.
Each variable has to be defined on a line on its own.
There is no way yet to fill a complete array with one call except arrays of
[unsigned] char which are considered strings.
ecpg cannot use pointer variables except [unsigned] char *

View File

@ -96,9 +96,9 @@ ECPGdo(int lineno, char *query,...)
while (type != ECPGt_EOIT)
{
void *value = NULL;
short varcharsize;
short size;
short arrsize;
long varcharsize;
long size;
long arrsize;
char *newcopy;
char *mallocedval = NULL;
@ -110,20 +110,18 @@ ECPGdo(int lineno, char *query,...)
contents to arrive in a comma-separated list on insert (I think). */
value = va_arg(ap, void *);
varcharsize = va_arg(ap, short);
size = va_arg(ap, short);
arrsize = va_arg(ap, short);
varcharsize = va_arg(ap, long);
size = va_arg(ap, long);
arrsize = va_arg(ap, long);
switch (type)
{
case ECPGt_char:
case ECPGt_short:
case ECPGt_int:
sprintf(buff, "%d", *(int *) value);
tobeinserted = buff;
break;
case ECPGt_unsigned_char:
case ECPGt_unsigned_short:
case ECPGt_unsigned_int:
sprintf(buff, "%d", *(unsigned int *) value);
@ -155,6 +153,27 @@ ECPGdo(int lineno, char *query,...)
tobeinserted = buff;
break;
case ECPGt_char:
case ECPGt_unsigned_char:
{
/* set slen to string length if type is char * */
int slen = (varcharsize == 0) ? strlen((char *) value) : varcharsize;
newcopy = (char *) malloc(slen + 1);
strncpy(newcopy, (char *) value, slen);
newcopy[slen] = '\0';
mallocedval = (char *) malloc(2 * strlen(newcopy) + 3);
strcpy(mallocedval, "'");
strcat(mallocedval, quote_postgres(newcopy));
strcat(mallocedval, "'");
free(newcopy);
tobeinserted = mallocedval;
}
break;
case ECPGt_varchar:
case ECPGt_varchar2:
{
@ -274,7 +293,7 @@ ECPGdo(int lineno, char *query,...)
if (n < 1)
{
ECPGlog("ECPGdo lineno %d: Incorrect number of matches: %d\n",
ECPGlog("ECPGdo line %d: Incorrect number of matches: %d\n",
lineno, n);
register_error(1, "Data not found line %d.", lineno);
break;
@ -293,9 +312,9 @@ ECPGdo(int lineno, char *query,...)
for (x = 0; x < m && status; x++)
{
void *value = NULL;
short varcharsize;
short size;
short arrsize;
long varcharsize;
long size;
long arrsize;
char *pval = PQgetvalue(results, 0, x);
@ -311,9 +330,9 @@ ECPGdo(int lineno, char *query,...)
/* We will have to decode the value */
type = va_arg(ap, enum ECPGttype);
value = va_arg(ap, void *);
varcharsize = va_arg(ap, short);
size = va_arg(ap, short);
arrsize = va_arg(ap, short);
varcharsize = va_arg(ap, long);
size = va_arg(ap, long);
arrsize = va_arg(ap, long);
switch (type)
{
@ -321,7 +340,6 @@ ECPGdo(int lineno, char *query,...)
unsigned long ures;
double dres;
case ECPGt_char:
case ECPGt_short:
case ECPGt_int:
case ECPGt_long:
@ -342,9 +360,6 @@ ECPGdo(int lineno, char *query,...)
/* Again?! Yes */
switch (type)
{
case ECPGt_char:
*(char *) value = (char) res;
break;
case ECPGt_short:
*(short *) value = (short) res;
break;
@ -360,7 +375,6 @@ ECPGdo(int lineno, char *query,...)
}
break;
case ECPGt_unsigned_char:
case ECPGt_unsigned_short:
case ECPGt_unsigned_int:
case ECPGt_unsigned_long:
@ -381,9 +395,6 @@ ECPGdo(int lineno, char *query,...)
/* Again?! Yes */
switch (type)
{
case ECPGt_unsigned_char:
*(unsigned char *) value = (unsigned char) ures;
break;
case ECPGt_unsigned_short:
*(unsigned short *) value = (unsigned short) ures;
break;
@ -452,6 +463,20 @@ ECPGdo(int lineno, char *query,...)
return false;
break;
case ECPGt_char:
case ECPGt_unsigned_char:
{
if (varcharsize == 0)
{
/* char* */
strncpy((char *) value, pval, strlen(pval));
((char *) value)[strlen(pval)] = '\0';
}
else
strncpy((char *) value, pval, varcharsize);
}
break;
case ECPGt_varchar:
{
struct ECPGgeneric_varchar *var =

View File

@ -5,22 +5,22 @@ MAJOR_VERSION=1
MINOR_VERSION=0
PATCHLEVEL=0
CFLAGS=-I$(SRCDIR)/include -I../include -Wall -DMAJOR_VERSION=$(MAJOR_VERSION) -DMINOR_VERSION=$(MINOR_VERSION) -DPATCHLEVEL=$(PATCHLEVEL)
CFLAGS+=-I$(SRCDIR)/include -I../include -Wall -DMAJOR_VERSION=$(MAJOR_VERSION) -DMINOR_VERSION=$(MINOR_VERSION) -DPATCHLEVEL=$(PATCHLEVEL)
all:: ecpg
clean:
rm -f *.o core a.out ecpg y.tab.h y.tab.c *~
rm -f *.o core a.out ecpg y.tab.h y.tab.c pgc.c *~
install: all
$(INSTALL) $(INSTLOPTS) ecpg $(DESTDIR)$(BINDIR)
$(INSTALL) $(INSTL_EXE_OPTS) ecpg $(DESTDIR)$(BINDIR)
uninstall:
rm -f $(DESTDIR)$(BINDIR)/ecpg
# Rule that really do something.
ecpg: y.tab.o pgc.o type.o ecpg.o ../lib/typename.o
$(CC) -Wall -o ecpg y.tab.o pgc.o type.o ecpg.o ../lib/typename.o $(LEXLIB)
$(CC) -o ecpg y.tab.o pgc.o type.o ecpg.o ../lib/typename.o $(LEXLIB)
y.tab.h y.tab.c: preproc.y
$(YACC) $(YFLAGS) $<

View File

@ -29,6 +29,7 @@ end [eE][nN][dD]
exec [eE][xX][eE][cC]
execute [eE][xX][eE][cC][uU][tT][eE]
found [fF][oO][uU][nN][dD]
go [gG][oO]
goto [gG][oO][tT][oO]
immediate [iI][mM][mM][eE][dD][iI][aA][tT][eE]
include [iI][nN][cC][lL][uU][dD][eE]
@ -41,6 +42,8 @@ section [sS][eE][cC][tT][iI][oO][nN]
sql [sS][qQ][lL]
sqlerror [sS][qQ][lL][eE][rR][rR][oO][rR]
sqlprint [sS][qQ][lL][pP][rR][iI][nN][tT]
stop [sS][tT][oO][pP]
to [tT][oO]
varchar [vV][aA][rR][cC][hH][aA][rR]
varchar2 [vV][aA][rR][cC][hH][aA][rR]2
whenever [wW][hH][eE][nN][eE][vV][eE][rR]
@ -69,6 +72,8 @@ work [wW][oO][rR][kK]
<SQL>{continue} { dbg(SQL_CONTINUE); return SQL_CONTINUE; }
<SQL>{into} { dbg(SQL_INTO); return SQL_INTO; }
<SQL>{goto} { dbg(SQL_GOTO); return SQL_GOTO; }
<SQL>{go}{ws}{to} { dbg(SQL_GOTO); return SQL_GOTO; }
<SQL>{stop} { dbg(SQL_STOP); return SQL_STOP; }
<SQL>{do} { dbg(SQL_DO); return SQL_DO; }
{length} { dbg(S_LENGTH); return S_LENGTH; }

View File

@ -52,7 +52,9 @@ print_action(struct when *w)
break;
case W_DO: fprintf(yyout, "%s;", w->str);
break;
default: fprintf(yyout, "{/* not implemented yet */}");
case W_STOP: fprintf(yyout, "exit (1);");
break;
default: fprintf(yyout, "{/* %d not implemented yet */}", w->code);
break;
}
}
@ -168,8 +170,8 @@ struct arguments {
static struct arguments * argsinsert = NULL;
static struct arguments * argsresult = NULL;
void
reset_variables()
static void
reset_variables(void)
{
argsinsert = NULL;
argsresult = NULL;
@ -177,7 +179,7 @@ reset_variables()
/* Add a variable to a request. */
void
static void
add_variable(struct arguments ** list, struct variable * var)
{
struct arguments * p = (struct arguments *)malloc(sizeof(struct arguments));
@ -191,7 +193,7 @@ add_variable(struct arguments ** list, struct variable * var)
This is a recursive function that works from the end of the list and
deletes the list as we go on.
*/
void
static void
dump_variables(struct arguments * list)
{
if (list == NULL)
@ -217,7 +219,7 @@ dump_variables(struct arguments * list)
int tagname;
struct ECPGtemp_type type;
char * symbolname;
int indexsize;
long indexsize;
enum ECPGttype type_enum;
struct when action;
}
@ -227,19 +229,20 @@ dump_variables(struct arguments * list)
%token <tagname> SQL_CONNECT SQL_OPEN SQL_EXECUTE SQL_IMMEDIATE
%token <tagname> SQL_COMMIT SQL_ROLLBACK SQL_RELEASE SQL_WORK SQL_WHENEVER
%token <tagname> SQL_SQLERROR SQL_NOT_FOUND SQL_BREAK SQL_CONTINUE
%token <tagname> SQL_DO SQL_GOTO SQL_SQLPRINT
%token <tagname> SQL_DO SQL_GOTO SQL_SQLPRINT SQL_STOP
%token <tagname> S_SYMBOL S_LENGTH S_ANYTHING S_LABEL
%token <tagname> S_VARCHAR S_VARCHAR2
%token <tagname> S_EXTERN S_STATIC S_AUTO S_CONST S_REGISTER S_STRUCT S_SIGNED
%token <tagname> S_EXTERN S_STATIC S_AUTO S_CONST S_REGISTER S_STRUCT
%token <tagname> S_UNSIGNED S_SIGNED
%token <tagname> S_LONG S_SHORT S_INT S_CHAR S_FLOAT S_DOUBLE S_BOOL
%token <tagname> '[' ']' ';' ',' '{' '}' '=' '*' '(' ')'
%type <type> type type_detailed varchar_type simple_type array_type struct_type
%type <type> type type_detailed varchar_type simple_type struct_type string_type
/* % type <type> array_type pointer_type */
%type <symbolname> symbol label
%type <tagname> maybe_storage_clause varchar_tag db_name
%type <type_enum> simple_tag
%type <type_enum> simple_tag char_tag
%type <indexsize> index length
%type <action> action
%type <tagname> canything sqlanything both_anything vartext commit_release
@ -286,7 +289,7 @@ variable_declaration : type initializer ';' {
if (struct_level == 0)
{
new_variable($<type>1.name, $<type>1.typ);
free($<type>1.name);
free((void *)$<type>1.name);
}
fprintf(yyout, ";");
}
@ -319,15 +322,16 @@ symbol : S_SYMBOL {
type : maybe_storage_clause type_detailed { $<type>$ = $<type>2; };
type_detailed : varchar_type { $<type>$ = $<type>1; }
| simple_type { $<type>$ = $<type>1; }
| array_type {$<type>$ = $<type>1; }
| pointer_type {$<type>$ = $<type>1; }
| string_type { $<type>$ = $<type>1; }
/* | array_type {$<type>$ = $<type>1; }
| pointer_type {$<type>$ = $<type>1; }*/
| struct_type {$<type>$ = $<type>1; };
varchar_type : varchar_tag symbol index {
if ($<indexsize>3 > 0)
fprintf(yyout, "struct varchar_%s { int len; char arr[%d]; } %s", $<symbolname>2, $<indexsize>3, $<symbolname>2);
if ($<indexsize>3 > 0L)
fprintf(yyout, "struct varchar_%s { int len; char arr[%ld]; } %s", $<symbolname>2, $<indexsize>3, $<symbolname>2);
else
fprintf(yyout, "struct varchar_%s { int len; char arr[%d]; } %s", $<symbolname>2, $<indexsize>3, $<symbolname>2);
fprintf(yyout, "struct varchar_%s { int len; char arr[]; } %s", $<symbolname>2, $<symbolname>2);
if (struct_level == 0)
{
$<type>$.name = $<symbolname>2;
@ -345,15 +349,53 @@ simple_type : simple_tag symbol {
if (struct_level == 0)
{
$<type>$.name = $<symbolname>2;
$<type>$.typ = ECPGmake_simple_type($<type_enum>1);
$<type>$.typ = ECPGmake_simple_type($<type_enum>1, 1);
}
else
ECPGmake_record_member($<symbolname>2, ECPGmake_simple_type($<type_enum>1), &(record_member_list[struct_level-1]));
ECPGmake_record_member($<symbolname>2, ECPGmake_simple_type($<type_enum>1, 1), &(record_member_list[struct_level-1]));
}
string_type : char_tag symbol index {
if ($<indexsize>3 > 0L)
fprintf(yyout, "%s %s [%ld]", ECPGtype_name($<type_enum>1), $<symbolname>2, $<indexsize>3);
else
fprintf(yyout, "%s %s []", ECPGtype_name($<type_enum>1), $<symbolname>2);
if (struct_level == 0)
{
$<type>$.name = $<symbolname>2;
$<type>$.typ = ECPGmake_simple_type($<type_enum>1, $<indexsize>3);
}
else
ECPGmake_record_member($<symbolname>2, ECPGmake_simple_type($<type_enum>1, $<indexsize>3), &(record_member_list[struct_level-1]));
}
| char_tag '*' symbol {
fprintf(yyout, "%s *%s", ECPGtype_name($<type_enum>1), $<symbolname>3);
if (struct_level == 0)
{
$<type>$.name = $<symbolname>3;
$<type>$.typ = ECPGmake_simple_type($<type_enum>1, 0);
}
else
ECPGmake_record_member($<symbolname>3, ECPGmake_simple_type($<type_enum>1, 0), &(record_member_list[struct_level-1]));
}
| char_tag symbol {
fprintf(yyout, "%s %s", ECPGtype_name($<type_enum>1), $<symbolname>2);
if (struct_level == 0)
{
$<type>$.name = $<symbolname>2;
$<type>$.typ = ECPGmake_simple_type($<type_enum>1, 1);
}
else
ECPGmake_record_member($<symbolname>2, ECPGmake_simple_type($<type_enum>1, 1), &(record_member_list[struct_level-1]));
}
char_tag : S_CHAR { $<type_enum>$ = ECPGt_char; }
| S_UNSIGNED S_CHAR { $<type_enum>$ = ECPGt_unsigned_char; }
/*
array_type : simple_tag symbol index {
if ($<indexsize>3 > 0)
fprintf(yyout, "%s %s [%d]", ECPGtype_name($<type_enum>1), $<symbolname>2, $<indexsize>3);
fprintf(yyout, "%s %s [%ld]", ECPGtype_name($<type_enum>1), $<symbolname>2, $<indexsize>3);
else
fprintf(yyout, "%s %s []", ECPGtype_name($<type_enum>1), $<symbolname>2);
if (struct_level == 0)
@ -375,6 +417,7 @@ pointer_type : simple_tag '*' symbol {
else
ECPGmake_record_member($<symbolname>3, ECPGmake_array_type(ECPGmake_simple_type($<type_enum>1), 0), &(record_member_list[struct_level-1]));
}
*/
s_struct : S_STRUCT symbol {
struct_level++;
@ -394,9 +437,7 @@ struct_type : s_struct '{' variable_declarations '}' symbol {
record_member_list[struct_level] = NULL;
}
simple_tag : S_CHAR { $<type_enum>$ = ECPGt_char; }
| S_UNSIGNED S_CHAR { $<type_enum>$ = ECPGt_unsigned_char; }
| S_SHORT { $<type_enum>$ = ECPGt_short; }
simple_tag : S_SHORT { $<type_enum>$ = ECPGt_short; }
| S_UNSIGNED S_SHORT { $<type_enum>$ = ECPGt_unsigned_short; }
| S_INT { $<type_enum>$ = ECPGt_int; }
| S_UNSIGNED S_INT { $<type_enum>$ = ECPGt_unsigned_int; }
@ -415,9 +456,9 @@ maybe_storage_clause : S_EXTERN { fwrite(yytext, yyleng, 1, yyout); }
| /* empty */ { };
index : '[' length ']' { $<indexsize>$ = $<indexsize>2; }
| '[' ']' { $<indexsize>$ = 0; }
| '[' ']' { $<indexsize>$ = 0L; }
length : S_LENGTH { $<indexsize>$ = atoi(yytext); }
length : S_LENGTH { $<indexsize>$ = atol(yytext); }
sqlinclude : SQL_START SQL_INCLUDE { fprintf(yyout, "#include \""); }
filename SQL_SEMI { fprintf(yyout, ".h\""); output_line_number(); };
@ -430,7 +471,7 @@ sqlconnect : SQL_START SQL_CONNECT { fprintf(yyout, "ECPGconnect("); }
SQL_SEMI { fprintf(yyout, ");"); whenever_action();}
db_name : SQL_STRING { fprintf(yyout, "\""); fwrite(yytext + 1, yyleng - 2, 1, yyout); fprintf(yyout, "\""); }
| ':' symbol { /* check if we have a char variabnle */
| ':' symbol { /* check if we have a char variable */
struct variable *p = find_variable($<symbolname>2);
enum ECPGttype typ = p->type->typ;
@ -465,45 +506,55 @@ sqlrollback : SQL_START SQL_ROLLBACK SQL_SEMI {
whenever_action();
};
sqlexecute : SQL_START { /* Reset stack */
reset_variables();
fprintf(yyout, "ECPGdo(__LINE__, \"");
} SQL_EXECUTE SQL_IMMEDIATE sqlstatement_words SQL_SEMI {
/* Dump */
fprintf(yyout, "\", ");
dump_variables(argsinsert);
fprintf(yyout, "ECPGt_EOIT, ");
/* dump_variables(argsresult); output variables must not exist here */
fprintf(yyout, "ECPGt_EORT );");
sqlexecute : SQL_START SQL_EXECUTE SQL_IMMEDIATE ':' symbol SQL_SEMI {
fprintf(yyout, "ECPGdo(__LINE__, %s, ECPGt_EOIT, ECPGt_EORT );", $5);
whenever_action();
};
sqlwhenever : SQL_START SQL_WHENEVER SQL_SQLERROR action SQL_SEMI{
when_error = $<action>4;
sqlwhenever : SQL_START SQL_WHENEVER SQL_SQLERROR {
fprintf(yyout, "/* exec sql whenever sqlerror ");
} action SQL_SEMI{
when_error.code = $<action>5.code;
when_error.str = $<action>5.str;
fprintf(yyout, "; */\n");
}
| SQL_START SQL_WHENEVER SQL_NOT_FOUND action SQL_SEMI{
when_nf = $<action>4;
| SQL_START SQL_WHENEVER SQL_NOT_FOUND {
fprintf(yyout, "/* exec sql whenever not found ");
} action SQL_SEMI{
when_nf.code = $<action>5.code;
when_nf.str=$<action>5.str;
fprintf(yyout, "; */\n");
}
action : SQL_BREAK {
$<action>$.code = W_BREAK;
$<action>$.str = NULL;
fprintf(yyout, "break");
}
| SQL_CONTINUE {
$<action>$.code = W_CONTINUE;
$<action>$.str = NULL;
fprintf(yyout, "continue");
}
| SQL_SQLPRINT {
$<action>$.code = W_SQLPRINT;
$<action>$.str = NULL;
fprintf(yyout, "sqlprint");
}
| SQL_STOP {
$<action>$.code = W_STOP;
$<action>$.str = NULL;
fprintf(yyout, "stop");
}
| SQL_GOTO label {
$<action>$.code = W_GOTO;
$<action>$.str = $<symbolname>2;
fprintf(yyout, "goto %s", $<symbolname>2);
}
| SQL_GOTO symbol {
| SQL_GOTO symbol {
$<action>$.code = W_GOTO;
$<action>$.str = $<symbolname>2;
fprintf(yyout, "goto %s", $<symbolname>2);
}
| SQL_DO symbol '(' {
do_str = (char *) mm_alloc(do_length = strlen($<symbolname>2) + 4);
@ -513,6 +564,7 @@ action : SQL_BREAK {
do_str[strlen(do_str)]=')';
$<action>$.code = W_DO;
$<action>$.str = do_str;
fprintf(yyout, "do %s", do_str);
do_str = NULL;
do_length = 0;
}
@ -599,6 +651,7 @@ blockend : '}' {
fwrite(yytext, yyleng, 1, yyout);
}
%%
static void yyerror(char * error)
{
fprintf(stderr, "%s in line %d\n", error, yylineno);

View File

@ -57,21 +57,21 @@ ECPGmake_record_member(char *name, struct ECPGtype *type, struct ECPGrecord_memb
}
struct ECPGtype *
ECPGmake_simple_type(enum ECPGttype typ)
ECPGmake_simple_type(enum ECPGttype typ, long siz)
{
struct ECPGtype *ne = (struct ECPGtype *) mm_alloc(sizeof(struct ECPGtype));
ne->typ = typ;
ne->size = 0;
ne->size = siz;
ne->u.element = 0;
return ne;
}
struct ECPGtype *
ECPGmake_varchar_type(enum ECPGttype typ, unsigned short siz)
ECPGmake_varchar_type(enum ECPGttype typ, long siz)
{
struct ECPGtype *ne = ECPGmake_simple_type(typ);
struct ECPGtype *ne = ECPGmake_simple_type(typ, 1);
ne->size = siz;
@ -79,9 +79,9 @@ ECPGmake_varchar_type(enum ECPGttype typ, unsigned short siz)
}
struct ECPGtype *
ECPGmake_array_type(struct ECPGtype *typ, unsigned short siz)
ECPGmake_array_type(struct ECPGtype *typ, long siz)
{
struct ECPGtype *ne = ECPGmake_simple_type(ECPGt_array);
struct ECPGtype *ne = ECPGmake_simple_type(ECPGt_array, siz);
ne->size = siz;
ne->u.element = typ;
@ -92,7 +92,7 @@ ECPGmake_array_type(struct ECPGtype *typ, unsigned short siz)
struct ECPGtype *
ECPGmake_record_type(struct ECPGrecord_member *rm)
{
struct ECPGtype *ne = ECPGmake_simple_type(ECPGt_record);
struct ECPGtype *ne = ECPGmake_simple_type(ECPGt_record, 1);
ne->u.members = rm;
@ -104,9 +104,9 @@ ECPGmake_record_type(struct ECPGrecord_member *rm)
The type is dumped as:
type-tag <comma> - enum ECPGttype
reference-to-variable <comma> - void *
size <comma> - short size of this field (if varchar)
arrsize <comma> - short number of elements in the arr
offset <comma> - short offset to the next element
size <comma> - long size of this field (if varchar)
arrsize <comma> - long number of elements in the arr
offset <comma> - offset to the next element
Where:
type-tag is one of the simple types or varchar.
reference-to-variable can be a reference to a struct element.
@ -115,9 +115,9 @@ ECPGmake_record_type(struct ECPGrecord_member *rm)
the variable (required to do array fetches of records).
*/
void ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype typ,
short varcharsize,
unsigned short arrsiz, const char *siz, const char *prefix);
void ECPGdump_a_record(FILE *o, const char *name, unsigned short arrsiz,
long varcharsize,
long arrsiz, const char *siz, const char *prefix);
void ECPGdump_a_record(FILE *o, const char *name, long arrsiz,
struct ECPGtype *typ, const char *offset, const char *prefix);
@ -162,67 +162,75 @@ ECPGdump_a_type(FILE *o, const char *name, struct ECPGtype *typ, const char *pre
string, it represents the offset needed if we are in an array of records. */
void
ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype typ,
short varcharsize,
unsigned short arrsiz,
long varcharsize,
long arrsiz,
const char *siz,
const char *prefix)
{
switch (typ)
{
case ECPGt_char:
fprintf(o, "\n\tECPGt_char,&%s%s,0,%d,%s, ", prefix ? prefix : "", name, arrsiz,
if (varcharsize == 0) /* pointer */
fprintf(o, "\n\tECPGt_char,%s%s,%ldL,%ldL,%s, ", prefix ? prefix : "", name, varcharsize, arrsiz,
siz == NULL ? "sizeof(char)" : siz);
else
fprintf(o, "\n\tECPGt_char,&%s%s,%ldL,%ldL,%s, ", prefix ? prefix : "", name, varcharsize, arrsiz,
siz == NULL ? "sizeof(char)" : siz);
break;
case ECPGt_unsigned_char:
fprintf(o, "\n\tECPGt_unsigned_char,&%s%s,0,%d,%s, ", prefix ? prefix : "", name, arrsiz,
if (varcharsize == 0) /* pointer */
fprintf(o, "\n\tECPGt_unsigned_char,%s%s,%ldL,%ldL,%s, ", prefix ? prefix : "", name, varcharsize, arrsiz,
siz == NULL ? "sizeof(char)" : siz);
else
fprintf(o, "\n\tECPGt_unsigned_char,&%s%s,%ldL,%ldL,%s, ", prefix ? prefix : "", name, varcharsize, arrsiz,
siz == NULL ? "sizeof(unsigned char)" : siz);
break;
case ECPGt_short:
fprintf(o, "\n\tECPGt_short,&%s%s,0,%d,%s, ", prefix ? prefix : "", name, arrsiz,
fprintf(o, "\n\tECPGt_short,&%s%s,0L,%ldL,%s, ", prefix ? prefix : "", name, arrsiz,
siz == NULL ? "sizeof(short)" : siz);
break;
case ECPGt_unsigned_short:
fprintf(o,
"\n\tECPGt_unsigned_short,&%s%s,0,%d,%s, ", prefix ? prefix : "", name, arrsiz,
"\n\tECPGt_unsigned_short,&%s%s,0L,%ldL,%s, ", prefix ? prefix : "", name, arrsiz,
siz == NULL ? "sizeof(unsigned short)" : siz);
break;
case ECPGt_int:
fprintf(o, "\n\tECPGt_int,&%s%s,0,%d,%s, ", prefix ? prefix : "", name, arrsiz,
fprintf(o, "\n\tECPGt_int,&%s%s,0L,%ldL,%s, ", prefix ? prefix : "", name, arrsiz,
siz == NULL ? "sizeof(int)" : siz);
break;
case ECPGt_unsigned_int:
fprintf(o, "\n\tECPGt_unsigned_int,&%s%s,0,%d,%s, ", prefix ? prefix : "", name, arrsiz,
fprintf(o, "\n\tECPGt_unsigned_int,&%s%s,0L,%ldL,%s, ", prefix ? prefix : "", name, arrsiz,
siz == NULL ? "sizeof(unsigned int)" : siz);
break;
case ECPGt_long:
fprintf(o, "\n\tECPGt_long,&%s%s,0,%d,%s, ", prefix ? prefix : "", name, arrsiz,
fprintf(o, "\n\tECPGt_long,&%s%s,0L,%ldL,%s, ", prefix ? prefix : "", name, arrsiz,
siz == NULL ? "sizeof(long)" : siz);
break;
case ECPGt_unsigned_long:
fprintf(o, "\n\tECPGt_unsigned_int,&%s%s,0,%d,%s, ", prefix ? prefix : "", name, arrsiz,
fprintf(o, "\n\tECPGt_unsigned_int,&%s%s,0L,%ldL,%s, ", prefix ? prefix : "", name, arrsiz,
siz == NULL ? "sizeof(unsigned int)" : siz);
break;
case ECPGt_float:
fprintf(o, "\n\tECPGt_float,&%s%s,0,%d,%s, ", prefix ? prefix : "", name, arrsiz,
fprintf(o, "\n\tECPGt_float,&%s%s,0L,%ldL,%s, ", prefix ? prefix : "", name, arrsiz,
siz == NULL ? "sizeof(float)" : siz);
break;
case ECPGt_double:
fprintf(o, "\n\tECPGt_double,&%s%s,0,%d,%s, ", prefix ? prefix : "", name, arrsiz,
fprintf(o, "\n\tECPGt_double,&%s%s,0L,%ldL,%s, ", prefix ? prefix : "", name, arrsiz,
siz == NULL ? "sizeof(double)" : siz);
break;
case ECPGt_bool:
fprintf(o, "\n\tECPGt_bool,&%s%s,0,%d,%s, ", prefix ? prefix : "", name, arrsiz,
fprintf(o, "\n\tECPGt_bool,&%s%s,0L,%ldL,%s, ", prefix ? prefix : "", name, arrsiz,
siz == NULL ? "sizeof(bool)" : siz);
break;
case ECPGt_varchar:
case ECPGt_varchar2:
if (siz == NULL)
fprintf(o, "\n\tECPGt_varchar,&%s%s,%d,%d,sizeof(struct varchar_%s), ",
fprintf(o, "\n\tECPGt_varchar,&%s%s,%ldL,%ldL,sizeof(struct varchar_%s), ",
prefix ? prefix : "", name,
varcharsize,
arrsiz, name);
else
fprintf(o, "\n\tECPGt_varchar,&%s%s,%d,%d,%s, ",
fprintf(o, "\n\tECPGt_varchar,&%s%s,%ldL,%ldL,%s, ",
prefix ? prefix : "", name,
varcharsize,
arrsiz, siz);
@ -235,7 +243,7 @@ ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype typ,
/* Penetrate a record and dump the contents. */
void
ECPGdump_a_record(FILE *o, const char *name, unsigned short arrsiz, struct ECPGtype *typ, const char *offsetarg, const char *prefix)
ECPGdump_a_record(FILE *o, const char *name, long arrsiz, struct ECPGtype *typ, const char *offsetarg, const char *prefix)
{
/* If offset is NULL, then this is the first recursive level. If not then
we are in a record in a record and the offset is used as offset.

View File

@ -9,7 +9,7 @@ struct ECPGrecord_member {
struct ECPGtype {
enum ECPGttype typ;
unsigned short size; /* For array it is the number of elements.
long size; /* For array it is the number of elements.
* For varchar it is the maxsize of the area.
*/
union {
@ -23,9 +23,9 @@ struct ECPGtype {
/* Everything is malloced. */
struct ECPGrecord_member * ECPGmake_record_member(char *, struct ECPGtype *, struct ECPGrecord_member **);
struct ECPGtype * ECPGmake_simple_type(enum ECPGttype);
struct ECPGtype * ECPGmake_varchar_type(enum ECPGttype, unsigned short);
struct ECPGtype * ECPGmake_array_type(struct ECPGtype *, unsigned short);
struct ECPGtype * ECPGmake_simple_type(enum ECPGttype, long);
struct ECPGtype * ECPGmake_varchar_type(enum ECPGttype, long);
struct ECPGtype * ECPGmake_array_type(struct ECPGtype *, long);
struct ECPGtype * ECPGmake_record_type(struct ECPGrecord_member *);
/* Frees a type. */
@ -59,7 +59,8 @@ enum WHEN {
W_BREAK,
W_SQLPRINT,
W_GOTO,
W_DO
W_DO,
W_STOP
};
struct when

View File

@ -34,6 +34,16 @@ exec sql end declare section;
strcpy(msg, "connect");
exec sql connect 'mm';
strcpy(msg, "create");
exec sql create table meskes(name char8, born int4, age int2);
strcpy(msg, "insert");
exec sql insert into meskes(name, born, age) values ('Petra', 19661202, 31);
exec sql insert into meskes(name, born, age) values ('Michael', 19660117, 32);
exec sql insert into meskes(name, born, age) values ('Carsten', 19910103, 7);
exec sql insert into meskes(name, born, age) values ('Marc', 19930907, 4);
exec sql insert into meskes(name, born, age) values ('Chris', 19970923, 0);
strcpy(msg, "declare");
exec sql declare cur cursor for
select name, born, age from meskes;
@ -41,14 +51,23 @@ exec sql end declare section;
exec sql open cur;
while (1) {
/* make sure we leave this loop */
exec sql whenever not found break;
strcpy(msg, "fetch");
exec sql fetch in cur into :personal;
printf ("%8.8s was born %d (age = %d)\n", personal.name.arr, personal.birth.born, personal.birth.age);
}
/* back to normal behaviour */
exec sql whenever not found sqlprint;
strcpy(msg, "close");
exec sql close cur;
strcpy(msg, "drop");
exec sql drop table meskes;
strcpy(msg, "commit");
exec sql commit;