mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-24 18:55:04 +08:00
+ 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:
parent
0227a4e114
commit
80e12829cf
@ -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
|
||||
|
@ -1,5 +1,4 @@
|
||||
SUBDIRS = include lib preproc doc
|
||||
|
||||
all install uninstall clean:
|
||||
$(MAKE) -C include $@
|
||||
$(MAKE) -C lib $@
|
||||
$(MAKE) -C preproc $@
|
||||
|
@ -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 *
|
||||
|
||||
|
@ -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 =
|
||||
|
@ -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) $<
|
||||
|
@ -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; }
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user