From: Michael Meskes <Michael_Meskes@topmail.de>
+ + Tue Feb 23 17:32:25 CET 1999 + + - Other than a struct a union itself cannot be specified as variable. + + Fri Feb 26 07:18:25 CET 1999 + + - Synced preproc.y with gram.y. + + Sat Feb 27 20:30:03 CET 1999 + + - Added automatic allocating for NULL pointers.
This commit is contained in:
parent
51f0f6ddc8
commit
d077c61492
@ -475,5 +475,17 @@ Mon Feb 22 19:47:45 CET 1999
|
|||||||
requires me to increase the major version number.
|
requires me to increase the major version number.
|
||||||
- Synced pgc.l with scan.l.
|
- Synced pgc.l with scan.l.
|
||||||
- Added support for unions.
|
- Added support for unions.
|
||||||
|
|
||||||
|
Tue Feb 23 17:32:25 CET 1999
|
||||||
|
|
||||||
|
- Other than a struct a union itself cannot be specified as variable.
|
||||||
|
|
||||||
|
Fri Feb 26 07:18:25 CET 1999
|
||||||
|
|
||||||
|
- Synced preproc.y with gram.y.
|
||||||
|
|
||||||
|
Sat Feb 27 20:30:03 CET 1999
|
||||||
|
|
||||||
|
- Added automatic allocating for NULL pointers.
|
||||||
- Set library version to 3.0.0
|
- Set library version to 3.0.0
|
||||||
- Set ecpg version to 3.0.0
|
- Set ecpg version to 3.0.0
|
||||||
|
@ -11,9 +11,11 @@ DESCRIPTOR statement will be ignored.
|
|||||||
|
|
||||||
it would be nice to be able to use :var[:index] as cvariable
|
it would be nice to be able to use :var[:index] as cvariable
|
||||||
|
|
||||||
support for dynamic SQL with unknown number of variables with SQLDA structure
|
it would also be nice to be able to work with varchar * (inculding automatic
|
||||||
|
allocating)
|
||||||
|
|
||||||
allocate memory for pointers as C input variables
|
support for dynamic SQL with unknown number of variables with SQLDA structure
|
||||||
|
or something similar
|
||||||
|
|
||||||
Missing statements:
|
Missing statements:
|
||||||
- exec sql allocate
|
- exec sql allocate
|
||||||
|
@ -43,6 +43,7 @@ extern "C"
|
|||||||
ECPGt_varchar, ECPGt_varchar2,
|
ECPGt_varchar, ECPGt_varchar2,
|
||||||
ECPGt_array,
|
ECPGt_array,
|
||||||
ECPGt_struct,
|
ECPGt_struct,
|
||||||
|
ECPGt_union,
|
||||||
ECPGt_char_variable,
|
ECPGt_char_variable,
|
||||||
ECPGt_EOIT, /* End of insert types. */
|
ECPGt_EOIT, /* End of insert types. */
|
||||||
ECPGt_EORT, /* End of result types. */
|
ECPGt_EORT, /* End of result types. */
|
||||||
|
@ -64,6 +64,7 @@ struct variable
|
|||||||
{
|
{
|
||||||
enum ECPGttype type;
|
enum ECPGttype type;
|
||||||
void *value;
|
void *value;
|
||||||
|
void *pointer;
|
||||||
long varcharsize;
|
long varcharsize;
|
||||||
long arrsize;
|
long arrsize;
|
||||||
long offset;
|
long offset;
|
||||||
@ -91,6 +92,12 @@ struct prepared_statement
|
|||||||
struct prepared_statement *next;
|
struct prepared_statement *next;
|
||||||
} *prep_stmts = NULL;
|
} *prep_stmts = NULL;
|
||||||
|
|
||||||
|
struct auto_mem
|
||||||
|
{
|
||||||
|
void *pointer;
|
||||||
|
struct auto_mem *next;
|
||||||
|
} *auto_allocs = NULL;
|
||||||
|
|
||||||
static int simple_debug = 0;
|
static int simple_debug = 0;
|
||||||
static FILE *debugstream = NULL;
|
static FILE *debugstream = NULL;
|
||||||
|
|
||||||
@ -98,12 +105,25 @@ static void
|
|||||||
register_error(long code, char *fmt,...)
|
register_error(long code, char *fmt,...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
|
struct auto_mem *am;
|
||||||
|
|
||||||
sqlca.sqlcode = code;
|
sqlca.sqlcode = code;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
vsprintf(sqlca.sqlerrm.sqlerrmc, fmt, args);
|
vsprintf(sqlca.sqlerrm.sqlerrmc, fmt, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
sqlca.sqlerrm.sqlerrml = strlen(sqlca.sqlerrm.sqlerrmc);
|
sqlca.sqlerrm.sqlerrml = strlen(sqlca.sqlerrm.sqlerrmc);
|
||||||
|
|
||||||
|
/* free all memory we allocate for the user */
|
||||||
|
for (am = auto_allocs; am;)
|
||||||
|
{
|
||||||
|
struct auto_mem *act = am;
|
||||||
|
|
||||||
|
am = am->next;
|
||||||
|
free(act->pointer);
|
||||||
|
free(act);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto_allocs = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct connection *
|
static struct connection *
|
||||||
@ -186,6 +206,15 @@ ecpg_strdup(const char *string, int lineno)
|
|||||||
return (new);
|
return (new);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
add_mem(void *ptr, int lineno)
|
||||||
|
{
|
||||||
|
struct auto_mem *am = (struct auto_mem *) ecpg_alloc(sizeof(struct auto_mem), lineno);
|
||||||
|
|
||||||
|
am->next = auto_allocs;
|
||||||
|
auto_allocs = am;
|
||||||
|
}
|
||||||
|
|
||||||
/* This function returns a newly malloced string that has the ' and \
|
/* This function returns a newly malloced string that has the ' and \
|
||||||
in the argument quoted with \.
|
in the argument quoted with \.
|
||||||
*/
|
*/
|
||||||
@ -301,19 +330,10 @@ create_statement(int lineno, struct connection *connection, struct statement **
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
var->type = type;
|
var->type = type;
|
||||||
var->value = va_arg(ap, void *);
|
var->pointer = va_arg(ap, void *);
|
||||||
var->varcharsize = va_arg(ap, long);
|
|
||||||
var->arrsize = va_arg(ap, long);
|
|
||||||
var->offset = va_arg(ap, long);
|
|
||||||
var->ind_type = va_arg(ap, enum ECPGttype);
|
|
||||||
var->ind_value = va_arg(ap, void *);
|
|
||||||
var->ind_varcharsize = va_arg(ap, long);
|
|
||||||
var->ind_arrsize = va_arg(ap, long);
|
|
||||||
var->ind_offset = va_arg(ap, long);
|
|
||||||
var->next = NULL;
|
|
||||||
|
|
||||||
/* if variable is NULL, the statement hasn't been prepared */
|
/* if variable is NULL, the statement hasn't been prepared */
|
||||||
if (var->value == NULL)
|
if (var->pointer == NULL)
|
||||||
{
|
{
|
||||||
ECPGlog("create_statement: invalid statement name\n");
|
ECPGlog("create_statement: invalid statement name\n");
|
||||||
register_error(ECPG_INVALID_STMT, "Invalid statement name in line %d", lineno);
|
register_error(ECPG_INVALID_STMT, "Invalid statement name in line %d", lineno);
|
||||||
@ -321,6 +341,22 @@ create_statement(int lineno, struct connection *connection, struct statement **
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var->varcharsize = va_arg(ap, long);
|
||||||
|
var->arrsize = va_arg(ap, long);
|
||||||
|
var->offset = va_arg(ap, long);
|
||||||
|
|
||||||
|
if (var->arrsize == 0 || var->varcharsize == 0)
|
||||||
|
var->value = *((void **)(var->pointer));
|
||||||
|
else
|
||||||
|
var->value = var->pointer;
|
||||||
|
|
||||||
|
var->ind_type = va_arg(ap, enum ECPGttype);
|
||||||
|
var->ind_value = va_arg(ap, void *);
|
||||||
|
var->ind_varcharsize = va_arg(ap, long);
|
||||||
|
var->ind_arrsize = va_arg(ap, long);
|
||||||
|
var->ind_offset = va_arg(ap, long);
|
||||||
|
var->next = NULL;
|
||||||
|
|
||||||
for (ptr = *list; ptr && ptr->next; ptr = ptr->next);
|
for (ptr = *list; ptr && ptr->next; ptr = ptr->next);
|
||||||
|
|
||||||
if (ptr == NULL)
|
if (ptr == NULL)
|
||||||
@ -478,8 +514,7 @@ ECPGexecute(struct statement * stmt)
|
|||||||
break;
|
break;
|
||||||
case ECPGt_char_variable:
|
case ECPGt_char_variable:
|
||||||
{
|
{
|
||||||
/* set slen to string length if type is char * */
|
int slen = strlen((char *) var->value);
|
||||||
int slen = (var->varcharsize == 0) ? strlen((char *) var->value) : var->varcharsize;
|
|
||||||
char *tmp;
|
char *tmp;
|
||||||
|
|
||||||
if (!(newcopy = ecpg_alloc(slen + 1, stmt->lineno)))
|
if (!(newcopy = ecpg_alloc(slen + 1, stmt->lineno)))
|
||||||
@ -632,13 +667,6 @@ ECPGexecute(struct statement * stmt)
|
|||||||
act_field;
|
act_field;
|
||||||
|
|
||||||
case PGRES_TUPLES_OK:
|
case PGRES_TUPLES_OK:
|
||||||
|
|
||||||
/*
|
|
||||||
* XXX Cheap Hack. For now, we see only the last group of
|
|
||||||
* tuples. This is clearly not the right way to do things
|
|
||||||
* !!
|
|
||||||
*/
|
|
||||||
|
|
||||||
nfields = PQnfields(results);
|
nfields = PQnfields(results);
|
||||||
sqlca.sqlerrd[2] = ntuples = PQntuples(results);
|
sqlca.sqlerrd[2] = ntuples = PQntuples(results);
|
||||||
status = true;
|
status = true;
|
||||||
@ -677,17 +705,66 @@ ECPGexecute(struct statement * stmt)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
|
/*
|
||||||
|
* allocate memory for NULL pointers
|
||||||
|
*/
|
||||||
|
if (var->arrsize == 0 || var->varcharsize == 0)
|
||||||
|
{
|
||||||
|
switch(var->type)
|
||||||
|
{
|
||||||
|
case ECPGt_char:
|
||||||
|
case ECPGt_unsigned_char:
|
||||||
|
if (var->value == NULL)
|
||||||
|
{
|
||||||
|
var->varcharsize = 0;
|
||||||
|
/* check strlen for each tuple */
|
||||||
|
for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
|
||||||
|
{
|
||||||
|
int len = strlen(PQgetvalue(results, act_tuple, act_field));
|
||||||
|
|
||||||
|
if (len > var->varcharsize)
|
||||||
|
var->varcharsize = len;
|
||||||
|
}
|
||||||
|
var->offset *= var->varcharsize;
|
||||||
|
add_mem((void *)(var->value) = *((void **)(var->pointer)) = (void *) ecpg_alloc(var->offset * ntuples, stmt->lineno), stmt->lineno);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#if 0
|
||||||
|
case ECPGt_varchar:
|
||||||
|
if (((struct ECPGgeneric_varchar *)var->value)->arr == NULL)
|
||||||
|
{
|
||||||
|
var->varcharsize = 0;
|
||||||
|
/* check strlen for each tuple */
|
||||||
|
for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
|
||||||
|
{
|
||||||
|
int len = strlen(PQgetvalue(results, act_tuple, act_field));
|
||||||
|
|
||||||
|
if (len > var->varcharsize)
|
||||||
|
var->varcharsize = len;
|
||||||
|
|
||||||
|
((struct ECPGgeneric_varchar *) ((long) var->value + var->offset * act_tuple))->arr = (char *) ecpg_alloc(len, stmt->lineno);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
if (var->value == NULL)
|
||||||
|
add_mem((void *)(var->value) = *((void **)(var->pointer)) = (void *) ecpg_alloc(var->offset * ntuples, stmt->lineno), stmt->lineno);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (act_tuple = 0; act_tuple < ntuples && status; act_tuple++)
|
||||||
{
|
{
|
||||||
pval = PQgetvalue(results, act_tuple, act_field);
|
pval = PQgetvalue(results, act_tuple, act_field);
|
||||||
|
|
||||||
ECPGlog("ECPGexecute line %d: RESULT: %s\n", stmt->lineno, pval ? pval : "");
|
ECPGlog("ECPGexecute line %d: RESULT: %s\n", stmt->lineno, pval ? pval : "");
|
||||||
|
|
||||||
/* Now the pval is a pointer to the var->value. */
|
/* Now the pval is a pointer to the value. */
|
||||||
/* We will have to decode the var->value */
|
/* We will have to decode the value */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* check for null var->value and set indicator
|
* check for null value and set indicator
|
||||||
* accordingly
|
* accordingly
|
||||||
*/
|
*/
|
||||||
switch (var->ind_type)
|
switch (var->ind_type)
|
||||||
@ -840,37 +917,28 @@ ECPGexecute(struct statement * stmt)
|
|||||||
case ECPGt_char:
|
case ECPGt_char:
|
||||||
case ECPGt_unsigned_char:
|
case ECPGt_unsigned_char:
|
||||||
{
|
{
|
||||||
if (var->varcharsize == 0)
|
strncpy((char *) ((long) var->value + var->offset * act_tuple), pval, var->varcharsize);
|
||||||
|
if (var->varcharsize && var->varcharsize < strlen(pval))
|
||||||
{
|
{
|
||||||
/* char* */
|
/* truncation */
|
||||||
strncpy(((char **) var->value)[act_tuple], pval, strlen(pval));
|
switch (var->ind_type)
|
||||||
(((char **) var->value)[act_tuple])[strlen(pval)] = '\0';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
strncpy((char *) ((long) var->value + var->offset * act_tuple), pval, var->varcharsize);
|
|
||||||
if (var->varcharsize < strlen(pval))
|
|
||||||
{
|
{
|
||||||
/* truncation */
|
case ECPGt_short:
|
||||||
switch (var->ind_type)
|
case ECPGt_unsigned_short:
|
||||||
{
|
((short *) var->ind_value)[act_tuple] = var->varcharsize;
|
||||||
case ECPGt_short:
|
break;
|
||||||
case ECPGt_unsigned_short:
|
case ECPGt_int:
|
||||||
((short *) var->ind_value)[act_tuple] = var->varcharsize;
|
case ECPGt_unsigned_int:
|
||||||
break;
|
((int *) var->ind_value)[act_tuple] = var->varcharsize;
|
||||||
case ECPGt_int:
|
break;
|
||||||
case ECPGt_unsigned_int:
|
case ECPGt_long:
|
||||||
((int *) var->ind_value)[act_tuple] = var->varcharsize;
|
case ECPGt_unsigned_long:
|
||||||
break;
|
((long *) var->ind_value)[act_tuple] = var->varcharsize;
|
||||||
case ECPGt_long:
|
break;
|
||||||
case ECPGt_unsigned_long:
|
default:
|
||||||
((long *) var->ind_value)[act_tuple] = var->varcharsize;
|
break;
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
sqlca.sqlwarn[0] = sqlca.sqlwarn[1] = 'W';
|
|
||||||
}
|
}
|
||||||
|
sqlca.sqlwarn[0] = sqlca.sqlwarn[1] = 'W';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -914,8 +982,7 @@ ECPGexecute(struct statement * stmt)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
register_error(ECPG_UNSUPPORTED, "Unsupported type %s on line %d.",
|
register_error(ECPG_UNSUPPORTED, "Unsupported type %s on line %d.", ECPGtype_name(var->type), stmt->lineno);
|
||||||
ECPGtype_name(var->type), stmt->lineno);
|
|
||||||
status = false;
|
status = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ preproc.c preproc.h: preproc.y
|
|||||||
mv y.tab.h preproc.h
|
mv y.tab.h preproc.h
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o core a.out ecpg$(X) *~
|
rm -f *.o core a.out ecpg$(X) *~ *.output *.tab.?
|
||||||
|
|
||||||
install: all
|
install: all
|
||||||
$(INSTALL) $(INSTL_EXE_OPTS) ecpg$(X) $(DESTDIR)$(BINDIR)
|
$(INSTALL) $(INSTL_EXE_OPTS) ecpg$(X) $(DESTDIR)$(BINDIR)
|
||||||
|
2801
src/interfaces/ecpg/preproc/pgc.c
Normal file
2801
src/interfaces/ecpg/preproc/pgc.c
Normal file
File diff suppressed because it is too large
Load Diff
16374
src/interfaces/ecpg/preproc/preproc.c
Normal file
16374
src/interfaces/ecpg/preproc/preproc.c
Normal file
File diff suppressed because it is too large
Load Diff
295
src/interfaces/ecpg/preproc/preproc.h
Normal file
295
src/interfaces/ecpg/preproc/preproc.h
Normal file
@ -0,0 +1,295 @@
|
|||||||
|
typedef union {
|
||||||
|
double dval;
|
||||||
|
int ival;
|
||||||
|
char * str;
|
||||||
|
struct when action;
|
||||||
|
struct index index;
|
||||||
|
int tagname;
|
||||||
|
struct this_type type;
|
||||||
|
enum ECPGttype type_enum;
|
||||||
|
} YYSTYPE;
|
||||||
|
#define SQL_AT 257
|
||||||
|
#define SQL_BOOL 258
|
||||||
|
#define SQL_BREAK 259
|
||||||
|
#define SQL_CALL 260
|
||||||
|
#define SQL_CONNECT 261
|
||||||
|
#define SQL_CONNECTION 262
|
||||||
|
#define SQL_CONTINUE 263
|
||||||
|
#define SQL_DEALLOCATE 264
|
||||||
|
#define SQL_DISCONNECT 265
|
||||||
|
#define SQL_ENUM 266
|
||||||
|
#define SQL_FOUND 267
|
||||||
|
#define SQL_FREE 268
|
||||||
|
#define SQL_GO 269
|
||||||
|
#define SQL_GOTO 270
|
||||||
|
#define SQL_IDENTIFIED 271
|
||||||
|
#define SQL_IMMEDIATE 272
|
||||||
|
#define SQL_INDICATOR 273
|
||||||
|
#define SQL_INT 274
|
||||||
|
#define SQL_LONG 275
|
||||||
|
#define SQL_OPEN 276
|
||||||
|
#define SQL_PREPARE 277
|
||||||
|
#define SQL_RELEASE 278
|
||||||
|
#define SQL_REFERENCE 279
|
||||||
|
#define SQL_SECTION 280
|
||||||
|
#define SQL_SEMI 281
|
||||||
|
#define SQL_SHORT 282
|
||||||
|
#define SQL_SIGNED 283
|
||||||
|
#define SQL_SQLERROR 284
|
||||||
|
#define SQL_SQLPRINT 285
|
||||||
|
#define SQL_SQLWARNING 286
|
||||||
|
#define SQL_START 287
|
||||||
|
#define SQL_STOP 288
|
||||||
|
#define SQL_STRUCT 289
|
||||||
|
#define SQL_UNSIGNED 290
|
||||||
|
#define SQL_VAR 291
|
||||||
|
#define SQL_WHENEVER 292
|
||||||
|
#define S_ANYTHING 293
|
||||||
|
#define S_AUTO 294
|
||||||
|
#define S_BOOL 295
|
||||||
|
#define S_CHAR 296
|
||||||
|
#define S_CONST 297
|
||||||
|
#define S_DOUBLE 298
|
||||||
|
#define S_ENUM 299
|
||||||
|
#define S_EXTERN 300
|
||||||
|
#define S_FLOAT 301
|
||||||
|
#define S_INT 302
|
||||||
|
#define S 303
|
||||||
|
#define S_LONG 304
|
||||||
|
#define S_REGISTER 305
|
||||||
|
#define S_SHORT 306
|
||||||
|
#define S_SIGNED 307
|
||||||
|
#define S_STATIC 308
|
||||||
|
#define S_STRUCT 309
|
||||||
|
#define S_UNION 310
|
||||||
|
#define S_UNSIGNED 311
|
||||||
|
#define S_VARCHAR 312
|
||||||
|
#define TYPECAST 313
|
||||||
|
#define ABSOLUTE 314
|
||||||
|
#define ACTION 315
|
||||||
|
#define ADD 316
|
||||||
|
#define ALL 317
|
||||||
|
#define ALTER 318
|
||||||
|
#define AND 319
|
||||||
|
#define ANY 320
|
||||||
|
#define AS 321
|
||||||
|
#define ASC 322
|
||||||
|
#define BEGIN_TRANS 323
|
||||||
|
#define BETWEEN 324
|
||||||
|
#define BOTH 325
|
||||||
|
#define BY 326
|
||||||
|
#define CASCADE 327
|
||||||
|
#define CASE 328
|
||||||
|
#define CAST 329
|
||||||
|
#define CHAR 330
|
||||||
|
#define CHARACTER 331
|
||||||
|
#define CHECK 332
|
||||||
|
#define CLOSE 333
|
||||||
|
#define COALESCE 334
|
||||||
|
#define COLLATE 335
|
||||||
|
#define COLUMN 336
|
||||||
|
#define COMMIT 337
|
||||||
|
#define CONSTRAINT 338
|
||||||
|
#define CREATE 339
|
||||||
|
#define CROSS 340
|
||||||
|
#define CURRENT 341
|
||||||
|
#define CURRENT_DATE 342
|
||||||
|
#define CURRENT_TIME 343
|
||||||
|
#define CURRENT_TIMESTAMP 344
|
||||||
|
#define CURRENT_USER 345
|
||||||
|
#define CURSOR 346
|
||||||
|
#define DAY_P 347
|
||||||
|
#define DECIMAL 348
|
||||||
|
#define DECLARE 349
|
||||||
|
#define DEFAULT 350
|
||||||
|
#define DELETE 351
|
||||||
|
#define DESC 352
|
||||||
|
#define DISTINCT 353
|
||||||
|
#define DOUBLE 354
|
||||||
|
#define DROP 355
|
||||||
|
#define ELSE 356
|
||||||
|
#define END_TRANS 357
|
||||||
|
#define EXCEPT 358
|
||||||
|
#define EXECUTE 359
|
||||||
|
#define EXISTS 360
|
||||||
|
#define EXTRACT 361
|
||||||
|
#define FALSE_P 362
|
||||||
|
#define FETCH 363
|
||||||
|
#define FLOAT 364
|
||||||
|
#define FOR 365
|
||||||
|
#define FOREIGN 366
|
||||||
|
#define FROM 367
|
||||||
|
#define FULL 368
|
||||||
|
#define GRANT 369
|
||||||
|
#define GROUP 370
|
||||||
|
#define HAVING 371
|
||||||
|
#define HOUR_P 372
|
||||||
|
#define IN 373
|
||||||
|
#define INNER_P 374
|
||||||
|
#define INSENSITIVE 375
|
||||||
|
#define INSERT 376
|
||||||
|
#define INTERSECT 377
|
||||||
|
#define INTERVAL 378
|
||||||
|
#define INTO 379
|
||||||
|
#define IS 380
|
||||||
|
#define ISOLATION 381
|
||||||
|
#define JOIN 382
|
||||||
|
#define KEY 383
|
||||||
|
#define LANGUAGE 384
|
||||||
|
#define LEADING 385
|
||||||
|
#define LEFT 386
|
||||||
|
#define LEVEL 387
|
||||||
|
#define LIKE 388
|
||||||
|
#define LOCAL 389
|
||||||
|
#define MATCH 390
|
||||||
|
#define MINUTE_P 391
|
||||||
|
#define MONTH_P 392
|
||||||
|
#define NAMES 393
|
||||||
|
#define NATIONAL 394
|
||||||
|
#define NATURAL 395
|
||||||
|
#define NCHAR 396
|
||||||
|
#define NEXT 397
|
||||||
|
#define NO 398
|
||||||
|
#define NOT 399
|
||||||
|
#define NULLIF 400
|
||||||
|
#define NULL_P 401
|
||||||
|
#define NUMERIC 402
|
||||||
|
#define OF 403
|
||||||
|
#define ON 404
|
||||||
|
#define ONLY 405
|
||||||
|
#define OPTION 406
|
||||||
|
#define OR 407
|
||||||
|
#define ORDER 408
|
||||||
|
#define OUTER_P 409
|
||||||
|
#define PARTIAL 410
|
||||||
|
#define POSITION 411
|
||||||
|
#define PRECISION 412
|
||||||
|
#define PRIMARY 413
|
||||||
|
#define PRIOR 414
|
||||||
|
#define PRIVILEGES 415
|
||||||
|
#define PROCEDURE 416
|
||||||
|
#define PUBLIC 417
|
||||||
|
#define READ 418
|
||||||
|
#define REFERENCES 419
|
||||||
|
#define RELATIVE 420
|
||||||
|
#define REVOKE 421
|
||||||
|
#define RIGHT 422
|
||||||
|
#define ROLLBACK 423
|
||||||
|
#define SCROLL 424
|
||||||
|
#define SECOND_P 425
|
||||||
|
#define SELECT 426
|
||||||
|
#define SET 427
|
||||||
|
#define SUBSTRING 428
|
||||||
|
#define TABLE 429
|
||||||
|
#define TEMP 430
|
||||||
|
#define THEN 431
|
||||||
|
#define TIME 432
|
||||||
|
#define TIMESTAMP 433
|
||||||
|
#define TIMEZONE_HOUR 434
|
||||||
|
#define TIMEZONE_MINUTE 435
|
||||||
|
#define TO 436
|
||||||
|
#define TRAILING 437
|
||||||
|
#define TRANSACTION 438
|
||||||
|
#define TRIM 439
|
||||||
|
#define TRUE_P 440
|
||||||
|
#define UNION 441
|
||||||
|
#define UNIQUE 442
|
||||||
|
#define UPDATE 443
|
||||||
|
#define USER 444
|
||||||
|
#define USING 445
|
||||||
|
#define VALUES 446
|
||||||
|
#define VARCHAR 447
|
||||||
|
#define VARYING 448
|
||||||
|
#define VIEW 449
|
||||||
|
#define WHEN 450
|
||||||
|
#define WHERE 451
|
||||||
|
#define WITH 452
|
||||||
|
#define WORK 453
|
||||||
|
#define YEAR_P 454
|
||||||
|
#define ZONE 455
|
||||||
|
#define TRIGGER 456
|
||||||
|
#define TYPE_P 457
|
||||||
|
#define ABORT_TRANS 458
|
||||||
|
#define AFTER 459
|
||||||
|
#define AGGREGATE 460
|
||||||
|
#define ANALYZE 461
|
||||||
|
#define BACKWARD 462
|
||||||
|
#define BEFORE 463
|
||||||
|
#define BINARY 464
|
||||||
|
#define CACHE 465
|
||||||
|
#define CLUSTER 466
|
||||||
|
#define COPY 467
|
||||||
|
#define CREATEDB 468
|
||||||
|
#define CREATEUSER 469
|
||||||
|
#define CYCLE 470
|
||||||
|
#define DATABASE 471
|
||||||
|
#define DELIMITERS 472
|
||||||
|
#define DO 473
|
||||||
|
#define EACH 474
|
||||||
|
#define ENCODING 475
|
||||||
|
#define EXPLAIN 476
|
||||||
|
#define EXTEND 477
|
||||||
|
#define FORWARD 478
|
||||||
|
#define FUNCTION 479
|
||||||
|
#define HANDLER 480
|
||||||
|
#define INCREMENT 481
|
||||||
|
#define INDEX 482
|
||||||
|
#define INHERITS 483
|
||||||
|
#define INSTEAD 484
|
||||||
|
#define ISNULL 485
|
||||||
|
#define LANCOMPILER 486
|
||||||
|
#define LIMIT 487
|
||||||
|
#define LISTEN 488
|
||||||
|
#define UNLISTEN 489
|
||||||
|
#define LOAD 490
|
||||||
|
#define LOCATION 491
|
||||||
|
#define LOCK_P 492
|
||||||
|
#define MAXVALUE 493
|
||||||
|
#define MINVALUE 494
|
||||||
|
#define MOVE 495
|
||||||
|
#define NEW 496
|
||||||
|
#define NOCREATEDB 497
|
||||||
|
#define NOCREATEUSER 498
|
||||||
|
#define NONE 499
|
||||||
|
#define NOTHING 500
|
||||||
|
#define NOTIFY 501
|
||||||
|
#define NOTNULL 502
|
||||||
|
#define OFFSET 503
|
||||||
|
#define OIDS 504
|
||||||
|
#define OPERATOR 505
|
||||||
|
#define PASSWORD 506
|
||||||
|
#define PROCEDURAL 507
|
||||||
|
#define RECIPE 508
|
||||||
|
#define RENAME 509
|
||||||
|
#define RESET 510
|
||||||
|
#define RETURNS 511
|
||||||
|
#define ROW 512
|
||||||
|
#define RULE 513
|
||||||
|
#define SERIAL 514
|
||||||
|
#define SEQUENCE 515
|
||||||
|
#define SETOF 516
|
||||||
|
#define SHOW 517
|
||||||
|
#define START 518
|
||||||
|
#define STATEMENT 519
|
||||||
|
#define STDIN 520
|
||||||
|
#define STDOUT 521
|
||||||
|
#define TRUSTED 522
|
||||||
|
#define UNTIL 523
|
||||||
|
#define VACUUM 524
|
||||||
|
#define VALID 525
|
||||||
|
#define VERBOSE 526
|
||||||
|
#define VERSION 527
|
||||||
|
#define IDENT 528
|
||||||
|
#define SCONST 529
|
||||||
|
#define Op 530
|
||||||
|
#define CSTRING 531
|
||||||
|
#define CVARIABLE 532
|
||||||
|
#define CPP_LINE 533
|
||||||
|
#define ICONST 534
|
||||||
|
#define PARAM 535
|
||||||
|
#define FCONST 536
|
||||||
|
#define OP 537
|
||||||
|
#define UMINUS 538
|
||||||
|
|
||||||
|
|
||||||
|
extern YYSTYPE yylval;
|
@ -144,7 +144,8 @@ find_struct_member(char *name, char *str, struct ECPGstruct_member *members)
|
|||||||
case ECPGt_array:
|
case ECPGt_array:
|
||||||
return(new_variable(name, ECPGmake_array_type(members->typ->u.element, members->typ->size)));
|
return(new_variable(name, ECPGmake_array_type(members->typ->u.element, members->typ->size)));
|
||||||
case ECPGt_struct:
|
case ECPGt_struct:
|
||||||
return(new_variable(name, ECPGmake_struct_type(members->typ->u.members)));
|
case ECPGt_union:
|
||||||
|
return(new_variable(name, ECPGmake_struct_type(members->typ->u.members, members->typ->typ)));
|
||||||
default:
|
default:
|
||||||
return(new_variable(name, ECPGmake_simple_type(members->typ->typ, members->typ->size)));
|
return(new_variable(name, ECPGmake_simple_type(members->typ->typ, members->typ->size)));
|
||||||
}
|
}
|
||||||
@ -175,14 +176,39 @@ find_struct(char * name, char *next)
|
|||||||
*next = '\0';
|
*next = '\0';
|
||||||
p = find_variable(name);
|
p = find_variable(name);
|
||||||
|
|
||||||
/* restore the name, we will need it later on */
|
|
||||||
*next = c;
|
|
||||||
if (c == '-')
|
if (c == '-')
|
||||||
{
|
{
|
||||||
|
if (p->type->typ != ECPGt_struct && p->type->typ != ECPGt_union)
|
||||||
|
{
|
||||||
|
sprintf(errortext, "variable %s is not a pointer", name);
|
||||||
|
yyerror (errortext);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p->type->u.element->typ != ECPGt_struct && p->type->u.element->typ != ECPGt_union)
|
||||||
|
{
|
||||||
|
sprintf(errortext, "variable %s is not a pointer to a structure or a union", name);
|
||||||
|
yyerror (errortext);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* restore the name, we will need it later on */
|
||||||
|
*next = c;
|
||||||
next++;
|
next++;
|
||||||
|
|
||||||
return find_struct_member(name, next, p->type->u.element->u.members);
|
return find_struct_member(name, next, p->type->u.element->u.members);
|
||||||
}
|
}
|
||||||
else return find_struct_member(name, next, p->type->u.members);
|
else
|
||||||
|
{
|
||||||
|
if (p->type->typ != ECPGt_struct && p->type->typ != ECPGt_union)
|
||||||
|
{
|
||||||
|
sprintf(errortext, "variable %s is neither a structure nor a union", name);
|
||||||
|
yyerror (errortext);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* restore the name, we will need it later on */
|
||||||
|
*next = c;
|
||||||
|
|
||||||
|
return find_struct_member(name, next, p->type->u.members);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct variable *
|
static struct variable *
|
||||||
@ -323,6 +349,7 @@ check_indicator(struct ECPGtype *var)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ECPGt_struct:
|
case ECPGt_struct:
|
||||||
|
case ECPGt_union:
|
||||||
for (p = var->u.members; p; p = p->next)
|
for (p = var->u.members; p; p = p->next)
|
||||||
check_indicator(p->typ);
|
check_indicator(p->typ);
|
||||||
break;
|
break;
|
||||||
@ -549,6 +576,7 @@ adjust_array(enum ECPGttype type_enum, int *dimension, int *length, int type_dim
|
|||||||
switch (type_enum)
|
switch (type_enum)
|
||||||
{
|
{
|
||||||
case ECPGt_struct:
|
case ECPGt_struct:
|
||||||
|
case ECPGt_union:
|
||||||
/* pointer has to get dimension 0 */
|
/* pointer has to get dimension 0 */
|
||||||
if (pointer)
|
if (pointer)
|
||||||
{
|
{
|
||||||
@ -740,8 +768,7 @@ adjust_array(enum ECPGttype type_enum, int *dimension, int *length, int type_dim
|
|||||||
%type <str> opt_table opt_union opt_unique sort_clause sortby_list
|
%type <str> opt_table opt_union opt_unique sort_clause sortby_list
|
||||||
%type <str> sortby OptUseOp opt_inh_star relation_name_list name_list
|
%type <str> sortby OptUseOp opt_inh_star relation_name_list name_list
|
||||||
%type <str> group_clause having_clause from_clause c_list
|
%type <str> group_clause having_clause from_clause c_list
|
||||||
%type <str> from_list from_val join_expr join_outer join_spec join_list
|
%type <str> table_list join_outer where_clause relation_expr row_op sub_type
|
||||||
%type <str> join_using where_clause relation_expr row_op sub_type
|
|
||||||
%type <str> opt_column_list insert_rest InsertStmt OptimizableStmt
|
%type <str> opt_column_list insert_rest InsertStmt OptimizableStmt
|
||||||
%type <str> columnList DeleteStmt LockStmt UpdateStmt CursorStmt
|
%type <str> columnList DeleteStmt LockStmt UpdateStmt CursorStmt
|
||||||
%type <str> NotifyStmt columnElem copy_dirn c_expr UnlistenStmt
|
%type <str> NotifyStmt columnElem copy_dirn c_expr UnlistenStmt
|
||||||
@ -754,7 +781,7 @@ adjust_array(enum ECPGttype type_enum, int *dimension, int *length, int type_dim
|
|||||||
%type <str> func_args_list func_args opt_with ProcedureStmt def_arg
|
%type <str> func_args_list func_args opt_with ProcedureStmt def_arg
|
||||||
%type <str> def_elem def_list definition def_name def_type DefineStmt
|
%type <str> def_elem def_list definition def_name def_type DefineStmt
|
||||||
%type <str> opt_instead event event_object RuleActionList,
|
%type <str> opt_instead event event_object RuleActionList,
|
||||||
%type <str> RuleActionBlock RuleActionMulti
|
%type <str> RuleActionBlock RuleActionMulti join_list
|
||||||
%type <str> RuleStmt opt_column opt_name oper_argtypes
|
%type <str> RuleStmt opt_column opt_name oper_argtypes
|
||||||
%type <str> MathOp RemoveFuncStmt aggr_argtype for_update_clause
|
%type <str> MathOp RemoveFuncStmt aggr_argtype for_update_clause
|
||||||
%type <str> RemoveAggrStmt remove_type RemoveStmt ExtendStmt RecipeStmt
|
%type <str> RemoveAggrStmt remove_type RemoveStmt ExtendStmt RecipeStmt
|
||||||
@ -773,8 +800,10 @@ adjust_array(enum ECPGttype type_enum, int *dimension, int *length, int type_dim
|
|||||||
%type <str> GrantStmt privileges operation_commalist operation
|
%type <str> GrantStmt privileges operation_commalist operation
|
||||||
%type <str> cursor_clause opt_cursor opt_readonly opt_of opt_lmode
|
%type <str> cursor_clause opt_cursor opt_readonly opt_of opt_lmode
|
||||||
%type <str> case_expr when_clause_list case_default case_arg when_clause
|
%type <str> case_expr when_clause_list case_default case_arg when_clause
|
||||||
%type <str> select_w_o_sort opt_select_limit select_limit_value,
|
%type <str> select_clause opt_select_limit select_limit_value,
|
||||||
%type <str> select_offset_value
|
%type <str> select_offset_value table_list using_expr join_expr
|
||||||
|
%type <str> using_list from_expr table_expr join_clause join_type
|
||||||
|
%type <str> join_qual update_list join_clause join_clause_with_union
|
||||||
|
|
||||||
%type <str> ECPGWhenever ECPGConnect connection_target ECPGOpen opt_using
|
%type <str> ECPGWhenever ECPGConnect connection_target ECPGOpen opt_using
|
||||||
%type <str> indicator ECPGExecute ecpg_expr dotext ECPGPrepare
|
%type <str> indicator ECPGExecute ecpg_expr dotext ECPGPrepare
|
||||||
@ -790,7 +819,7 @@ adjust_array(enum ECPGttype type_enum, int *dimension, int *length, int type_dim
|
|||||||
%type <str> ECPGFree ECPGDeclare ECPGVar sql_variable_declarations
|
%type <str> ECPGFree ECPGDeclare ECPGVar sql_variable_declarations
|
||||||
%type <str> sql_declaration sql_variable_list sql_variable opt_at
|
%type <str> sql_declaration sql_variable_list sql_variable opt_at
|
||||||
%type <str> struct_type s_struct declaration variable_declarations
|
%type <str> struct_type s_struct declaration variable_declarations
|
||||||
%type <str> s_struct_or_union sql_struct_or_union
|
%type <str> s_struct s_union union_type
|
||||||
|
|
||||||
%type <type_enum> simple_type varchar_type
|
%type <type_enum> simple_type varchar_type
|
||||||
|
|
||||||
@ -1320,20 +1349,15 @@ ColConstraint:
|
|||||||
{ $$ = $1; }
|
{ $$ = $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
/* The column constraint WITH NULL gives a shift/reduce error
|
/* DEFAULT NULL is already the default for Postgres.
|
||||||
* because it requires yacc to look more than one token ahead to
|
|
||||||
* resolve WITH TIME ZONE and WITH NULL.
|
|
||||||
* So, leave it out of the syntax for now.
|
|
||||||
| WITH NULL_P
|
|
||||||
{
|
|
||||||
$$ = NULL;
|
|
||||||
}
|
|
||||||
* - thomas 1998-09-12
|
|
||||||
*
|
|
||||||
* DEFAULT NULL is already the default for Postgres.
|
|
||||||
* Bue define it here and carry it forward into the system
|
* Bue define it here and carry it forward into the system
|
||||||
* to make it explicit.
|
* to make it explicit.
|
||||||
* - thomas 1998-09-13
|
* - thomas 1998-09-13
|
||||||
|
* WITH NULL and NULL are not SQL92-standard syntax elements,
|
||||||
|
* so leave them out. Use DEFAULT NULL to explicitly indicate
|
||||||
|
* that a column may have that value. WITH NULL leads to
|
||||||
|
* shift/reduce conflicts with WITH TIME ZONE anyway.
|
||||||
|
* - thomas 1999-01-08
|
||||||
*/
|
*/
|
||||||
ColConstraintElem: CHECK '(' constraint_expr ')'
|
ColConstraintElem: CHECK '(' constraint_expr ')'
|
||||||
{
|
{
|
||||||
@ -2801,8 +2825,11 @@ opt_of: OF columnList { $$ = make2_str(make1_str("of"), $2); }
|
|||||||
/***S*I***/
|
/***S*I***/
|
||||||
/* The new 'SelectStmt' rule adapted for the optional use of INTERSECT EXCEPT a nd UNION
|
/* The new 'SelectStmt' rule adapted for the optional use of INTERSECT EXCEPT a nd UNION
|
||||||
* accepts the use of '(' and ')' to select an order of set operations.
|
* accepts the use of '(' and ')' to select an order of set operations.
|
||||||
|
* The rule returns a SelectStmt Node having the set operations attached to
|
||||||
|
* unionClause and intersectClause (NIL if no set operations were present)
|
||||||
*/
|
*/
|
||||||
SelectStmt: select_w_o_sort sort_clause for_update_clause opt_select_limit
|
|
||||||
|
SelectStmt: select_clause sort_clause for_update_clause opt_select_limit
|
||||||
{
|
{
|
||||||
if (strlen($3) > 0 && ForUpdateNotAllowed != 0)
|
if (strlen($3) > 0 && ForUpdateNotAllowed != 0)
|
||||||
yyerror("SELECT FOR UPDATE is not allowed in this context");
|
yyerror("SELECT FOR UPDATE is not allowed in this context");
|
||||||
@ -2819,7 +2846,7 @@ SelectStmt: select_w_o_sort sort_clause for_update_clause opt_select_limit
|
|||||||
*
|
*
|
||||||
* The sort_clause is not handled here!
|
* The sort_clause is not handled here!
|
||||||
*/
|
*/
|
||||||
select_w_o_sort: '(' select_w_o_sort ')'
|
select_clause: '(' select_clause ')'
|
||||||
{
|
{
|
||||||
$$ = make3_str(make1_str("("), $2, make1_str(")"));
|
$$ = make3_str(make1_str("("), $2, make1_str(")"));
|
||||||
}
|
}
|
||||||
@ -2827,17 +2854,17 @@ select_w_o_sort: '(' select_w_o_sort ')'
|
|||||||
{
|
{
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
| select_w_o_sort EXCEPT select_w_o_sort
|
| select_clause EXCEPT select_clause
|
||||||
{
|
{
|
||||||
$$ = cat3_str($1, make1_str("except"), $3);
|
$$ = cat3_str($1, make1_str("except"), $3);
|
||||||
ForUpdateNotAllowed = 1;
|
ForUpdateNotAllowed = 1;
|
||||||
}
|
}
|
||||||
| select_w_o_sort UNION opt_union select_w_o_sort
|
| select_clause UNION opt_union select_clause
|
||||||
{
|
{
|
||||||
$$ = cat3_str($1, make1_str("union"), $3);
|
$$ = cat3_str($1, make1_str("union"), $3);
|
||||||
ForUpdateNotAllowed = 1;
|
ForUpdateNotAllowed = 1;
|
||||||
}
|
}
|
||||||
| select_w_o_sort INTERSECT opt_union select_w_o_sort
|
| select_clause INTERSECT opt_union select_clause
|
||||||
{
|
{
|
||||||
$$ = cat3_str($1, make1_str("intersect"), $3);
|
$$ = cat3_str($1, make1_str("intersect"), $3);
|
||||||
ForUpdateNotAllowed = 1;
|
ForUpdateNotAllowed = 1;
|
||||||
@ -2949,20 +2976,24 @@ having_clause: HAVING a_expr
|
|||||||
| /*EMPTY*/ { $$ = make1_str(""); }
|
| /*EMPTY*/ { $$ = make1_str(""); }
|
||||||
;
|
;
|
||||||
|
|
||||||
for_update_clause:
|
for_update_clause: FOR UPDATE update_list
|
||||||
FOR UPDATE
|
{
|
||||||
{
|
$$ = make1_str("for update");
|
||||||
$$ = make1_str("for update");
|
}
|
||||||
}
|
| /* EMPTY */
|
||||||
| FOR UPDATE OF va_list
|
{
|
||||||
{
|
$$ = make1_str("");
|
||||||
$$ = cat2_str(make1_str("for update of"), $4);
|
}
|
||||||
}
|
|
||||||
| /* EMPTY */
|
|
||||||
{
|
|
||||||
$$ = make1_str("");
|
|
||||||
}
|
|
||||||
;
|
;
|
||||||
|
update_list: OF va_list
|
||||||
|
{
|
||||||
|
$$ = cat2_str(make1_str("of"), $2);
|
||||||
|
}
|
||||||
|
| /* EMPTY */
|
||||||
|
{
|
||||||
|
$$ = make1_str("");
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
*
|
*
|
||||||
@ -2972,78 +3003,144 @@ for_update_clause:
|
|||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
from_clause: FROM '(' relation_expr join_expr JOIN relation_expr join_spec ')'
|
from_clause: FROM from_expr
|
||||||
{
|
{
|
||||||
yyerror("JOIN not yet implemented");
|
$$ = cat2_str(make1_str("from"), $2);
|
||||||
}
|
}
|
||||||
| FROM from_list { $$ = cat2_str(make1_str("from"), $2); }
|
| /* EMPTY */
|
||||||
| /*EMPTY*/ { $$ = make1_str(""); }
|
{
|
||||||
;
|
$$ = make1_str("");
|
||||||
|
}
|
||||||
|
|
||||||
from_list: from_list ',' from_val
|
|
||||||
{ $$ = cat3_str($1, make1_str(","), $3); }
|
|
||||||
| from_val CROSS JOIN from_val
|
|
||||||
{ yyerror("CROSS JOIN not yet implemented"); }
|
|
||||||
| from_val
|
|
||||||
{ $$ = $1; }
|
|
||||||
;
|
|
||||||
|
|
||||||
from_val: relation_expr AS ColLabel
|
from_expr: '(' join_clause_with_union ')'
|
||||||
{
|
{ $$ = make3_str(make1_str("("), $2, make1_str(")")); }
|
||||||
$$ = cat3_str($1, make1_str("as"), $3);
|
| join_clause
|
||||||
}
|
{ $$ = $1; }
|
||||||
| relation_expr ColId
|
| table_list
|
||||||
{
|
{ $$ = $1; }
|
||||||
|
;
|
||||||
|
|
||||||
|
table_list: table_list ',' table_expr
|
||||||
|
{ $$ = make3_str($1, make1_str(","), $3); }
|
||||||
|
| table_expr
|
||||||
|
{ $$ = $1; }
|
||||||
|
;
|
||||||
|
|
||||||
|
table_expr: relation_expr AS ColLabel
|
||||||
|
{
|
||||||
|
$$ = cat3_str($1, make1_str("as"), $3);
|
||||||
|
}
|
||||||
|
| relation_expr ColId
|
||||||
|
{
|
||||||
|
$$ = cat2_str($1, $2);
|
||||||
|
}
|
||||||
|
| relation_expr
|
||||||
|
{
|
||||||
|
$$ = $1;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
/* A UNION JOIN is the same as a FULL OUTER JOIN which *omits*
|
||||||
|
* all result rows which would have matched on an INNER JOIN.
|
||||||
|
* Let's reject this for now. - thomas 1999-01-08
|
||||||
|
*/
|
||||||
|
join_clause_with_union: join_clause
|
||||||
|
{ $$ = $1; }
|
||||||
|
| table_expr UNION JOIN table_expr
|
||||||
|
{ yyerror("UNION JOIN not yet implemented"); }
|
||||||
|
;
|
||||||
|
|
||||||
|
join_clause: table_expr join_list
|
||||||
|
{
|
||||||
$$ = cat2_str($1, $2);
|
$$ = cat2_str($1, $2);
|
||||||
}
|
}
|
||||||
| relation_expr
|
;
|
||||||
{
|
|
||||||
$$ = $1;
|
join_list: join_list join_expr
|
||||||
}
|
{
|
||||||
;
|
$$ = cat2_str($1, $2);
|
||||||
|
}
|
||||||
|
| join_expr
|
||||||
|
{
|
||||||
|
$$ = $1;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
/* This is everything but the left side of a join.
|
||||||
|
* Note that a CROSS JOIN is the same as an unqualified
|
||||||
|
* inner join, so just pass back the right-side table.
|
||||||
|
* A NATURAL JOIN implicitly matches column names between
|
||||||
|
* tables, so we'll collect those during the later transformation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
join_expr: join_type JOIN table_expr join_qual
|
||||||
|
{
|
||||||
|
$$ = cat4_str($1, make1_str("join"), $3, $4);
|
||||||
|
}
|
||||||
|
| NATURAL join_type JOIN table_expr
|
||||||
|
{
|
||||||
|
$$ = cat4_str(make1_str("natural"), $2, make1_str("join"), $4);
|
||||||
|
}
|
||||||
|
| CROSS JOIN table_expr
|
||||||
|
{ $$ = cat2_str(make1_str("cross join"), $3); }
|
||||||
|
;
|
||||||
|
|
||||||
|
/* OUTER is just noise... */
|
||||||
|
join_type: FULL join_outer
|
||||||
|
{
|
||||||
|
$$ = cat2_str(make1_str("full"), $2);
|
||||||
|
fprintf(stderr,"FULL OUTER JOIN not yet implemented\n");
|
||||||
|
}
|
||||||
|
| LEFT join_outer
|
||||||
|
{
|
||||||
|
$$ = cat2_str(make1_str("left"), $2);
|
||||||
|
fprintf(stderr,"LEFT OUTER JOIN not yet implemented\n");
|
||||||
|
}
|
||||||
|
| RIGHT join_outer
|
||||||
|
{
|
||||||
|
$$ = cat2_str(make1_str("right"), $2);
|
||||||
|
fprintf(stderr,"RIGHT OUTER JOIN not yet implemented\n");
|
||||||
|
}
|
||||||
|
| OUTER_P
|
||||||
|
{
|
||||||
|
$$ = make1_str("outer");
|
||||||
|
fprintf(stderr,"OUTER JOIN not yet implemented\n");
|
||||||
|
}
|
||||||
|
| INNER_P
|
||||||
|
{
|
||||||
|
$$ = make1_str("inner");
|
||||||
|
}
|
||||||
|
| /* EMPTY */
|
||||||
|
{
|
||||||
|
$$ = make1_str("");
|
||||||
|
}
|
||||||
|
|
||||||
join_expr: NATURAL join_expr { $$ = cat2_str(make1_str("natural"), $2); }
|
|
||||||
| FULL join_outer
|
|
||||||
{ yyerror("FULL OUTER JOIN not yet implemented"); }
|
|
||||||
| LEFT join_outer
|
|
||||||
{ yyerror("LEFT OUTER JOIN not yet implemented"); }
|
|
||||||
| RIGHT join_outer
|
|
||||||
{ yyerror("RIGHT OUTER JOIN not yet implemented"); }
|
|
||||||
| OUTER_P
|
|
||||||
{ yyerror("OUTER JOIN not yet implemented"); }
|
|
||||||
| INNER_P
|
|
||||||
{ yyerror("INNER JOIN not yet implemented"); }
|
|
||||||
| UNION
|
|
||||||
{ yyerror("UNION JOIN not yet implemented"); }
|
|
||||||
| /*EMPTY*/
|
|
||||||
{ yyerror("INNER JOIN not yet implemented"); }
|
|
||||||
;
|
|
||||||
|
|
||||||
join_outer: OUTER_P { $$ = make1_str("outer"); }
|
join_outer: OUTER_P { $$ = make1_str("outer"); }
|
||||||
| /*EMPTY*/ { $$ = make1_str(""); /* no qualifiers */ }
|
| /*EMPTY*/ { $$ = make1_str(""); /* no qualifiers */ }
|
||||||
;
|
;
|
||||||
|
|
||||||
join_spec: ON '(' a_expr ')' { $$ = make3_str(make1_str("on ("), $3, make1_str(")")); }
|
/* JOIN qualification clauses
|
||||||
| USING '(' join_list ')' { $$ = make3_str(make1_str("using ("), $3, make1_str(")")); }
|
* Possibilities are:
|
||||||
| /*EMPTY*/ { $$ = make1_str(""); /* no qualifiers */ }
|
* USING ( column list ) allows only unqualified column names,
|
||||||
;
|
* which must match between tables.
|
||||||
|
* ON expr allows more general qualifications.
|
||||||
|
* - thomas 1999-01-07
|
||||||
|
*/
|
||||||
|
|
||||||
join_list: join_using { $$ = $1; }
|
join_qual: USING '(' using_list ')' { $$ = make3_str(make1_str("using ("), $3, make1_str(")")); }
|
||||||
| join_list ',' join_using { $$ = cat3_str($1, make1_str(","), $3); }
|
| ON a_expr { $$ = cat2_str(make1_str("on"), $2); }
|
||||||
;
|
;
|
||||||
|
|
||||||
join_using: ColId
|
using_list: using_list ',' using_expr { $$ = make3_str($1, make1_str(","), $3); }
|
||||||
|
| using_expr { $$ = $1; }
|
||||||
|
;
|
||||||
|
|
||||||
|
using_expr: ColId
|
||||||
{
|
{
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
| ColId '.' ColId
|
|
||||||
{
|
|
||||||
$$ = make3_str($1, make1_str("."), $3);
|
|
||||||
}
|
|
||||||
| Iconst
|
|
||||||
{
|
|
||||||
$$ = $1;;
|
|
||||||
}
|
|
||||||
;
|
;
|
||||||
|
|
||||||
where_clause: WHERE a_expr { $$ = cat2_str(make1_str("where"), $2); }
|
where_clause: WHERE a_expr { $$ = cat2_str(make1_str("where"), $2); }
|
||||||
@ -4053,8 +4150,6 @@ case_expr: CASE case_arg when_clause_list case_default END_TRANS
|
|||||||
| COALESCE '(' expr_list ')'
|
| COALESCE '(' expr_list ')'
|
||||||
{
|
{
|
||||||
$$ = cat3_str(make1_str("coalesce("), $3, make1_str(")"));
|
$$ = cat3_str(make1_str("coalesce("), $3, make1_str(")"));
|
||||||
|
|
||||||
fprintf(stderr, "COALESCE() not yet fully implemented");
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -4390,7 +4485,6 @@ ColLabel: ColId { $$ = $1; }
|
|||||||
| COALESCE { $$ = make1_str("coalesce"); }
|
| COALESCE { $$ = make1_str("coalesce"); }
|
||||||
| CONSTRAINT { $$ = make1_str("constraint"); }
|
| CONSTRAINT { $$ = make1_str("constraint"); }
|
||||||
| COPY { $$ = make1_str("copy"); }
|
| COPY { $$ = make1_str("copy"); }
|
||||||
| CROSS { $$ = make1_str("cross"); }
|
|
||||||
| CURRENT { $$ = make1_str("current"); }
|
| CURRENT { $$ = make1_str("current"); }
|
||||||
| DO { $$ = make1_str("do"); }
|
| DO { $$ = make1_str("do"); }
|
||||||
| ELSE { $$ = make1_str("else"); }
|
| ELSE { $$ = make1_str("else"); }
|
||||||
@ -4733,6 +4827,13 @@ type: simple_type
|
|||||||
$$.type_dimension = -1;
|
$$.type_dimension = -1;
|
||||||
$$.type_index = -1;
|
$$.type_index = -1;
|
||||||
}
|
}
|
||||||
|
| union_type
|
||||||
|
{
|
||||||
|
$$.type_enum = ECPGt_union;
|
||||||
|
$$.type_str = $1;
|
||||||
|
$$.type_dimension = -1;
|
||||||
|
$$.type_index = -1;
|
||||||
|
}
|
||||||
| enum_type
|
| enum_type
|
||||||
{
|
{
|
||||||
$$.type_str = $1;
|
$$.type_str = $1;
|
||||||
@ -4766,16 +4867,28 @@ struct_type: s_struct '{' variable_declarations '}'
|
|||||||
$$ = cat4_str($1, make1_str("{"), $3, make1_str("}"));
|
$$ = cat4_str($1, make1_str("{"), $3, make1_str("}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
s_struct : s_struct_or_union opt_symbol
|
union_type: s_union '{' variable_declarations '}'
|
||||||
|
{
|
||||||
|
ECPGfree_struct_member(struct_member_list[struct_level]);
|
||||||
|
free(actual_storage[struct_level--]);
|
||||||
|
$$ = cat4_str($1, make1_str("{"), $3, make1_str("}"));
|
||||||
|
}
|
||||||
|
|
||||||
|
s_struct : S_STRUCT opt_symbol
|
||||||
{
|
{
|
||||||
struct_member_list[struct_level++] = NULL;
|
struct_member_list[struct_level++] = NULL;
|
||||||
if (struct_level >= STRUCT_DEPTH)
|
if (struct_level >= STRUCT_DEPTH)
|
||||||
yyerror("Too many levels in nested structure definition");
|
yyerror("Too many levels in nested structure definition");
|
||||||
$$ = cat2_str($1, $2);
|
$$ = cat2_str(make1_str("struct"), $2);
|
||||||
}
|
}
|
||||||
|
|
||||||
s_struct_or_union: S_STRUCT { $$ = make1_str("struct"); }
|
s_union : S_UNION opt_symbol
|
||||||
| S_UNION { $$ = make1_str("union"); }
|
{
|
||||||
|
struct_member_list[struct_level++] = NULL;
|
||||||
|
if (struct_level >= STRUCT_DEPTH)
|
||||||
|
yyerror("Too many levels in nested structure definition");
|
||||||
|
$$ = cat2_str(make1_str("union"), $2);
|
||||||
|
}
|
||||||
|
|
||||||
opt_symbol: /* empty */ { $$ = make1_str(""); }
|
opt_symbol: /* empty */ { $$ = make1_str(""); }
|
||||||
| symbol { $$ = $1; }
|
| symbol { $$ = $1; }
|
||||||
@ -4815,10 +4928,11 @@ variable: opt_pointer symbol opt_array_bounds opt_initializer
|
|||||||
switch (actual_type[struct_level].type_enum)
|
switch (actual_type[struct_level].type_enum)
|
||||||
{
|
{
|
||||||
case ECPGt_struct:
|
case ECPGt_struct:
|
||||||
|
case ECPGt_union:
|
||||||
if (dimension < 0)
|
if (dimension < 0)
|
||||||
type = ECPGmake_struct_type(struct_member_list[struct_level]);
|
type = ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum);
|
||||||
else
|
else
|
||||||
type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level]), dimension);
|
type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum), dimension);
|
||||||
|
|
||||||
$$ = make4_str($1, mm_strdup($2), $3.str, $4);
|
$$ = make4_str($1, mm_strdup($2), $3.str, $4);
|
||||||
break;
|
break;
|
||||||
@ -4846,7 +4960,8 @@ variable: opt_pointer symbol opt_array_bounds opt_initializer
|
|||||||
if (length > 0)
|
if (length > 0)
|
||||||
$$ = make4_str(make5_str(mm_strdup(actual_storage[struct_level]), make1_str(" struct varchar_"), mm_strdup($2), make1_str(" { int len; char arr["), mm_strdup(ascii_len)), make1_str("]; } "), mm_strdup($2), mm_strdup(dim));
|
$$ = make4_str(make5_str(mm_strdup(actual_storage[struct_level]), make1_str(" struct varchar_"), mm_strdup($2), make1_str(" { int len; char arr["), mm_strdup(ascii_len)), make1_str("]; } "), mm_strdup($2), mm_strdup(dim));
|
||||||
else
|
else
|
||||||
$$ = make4_str(make3_str(mm_strdup(actual_storage[struct_level]), make1_str(" struct varchar_"), mm_strdup($2)), make1_str(" { int len; char *arr; } "), mm_strdup($2), mm_strdup(dim));
|
yyerror ("pointer to varchar are not implemented yet");
|
||||||
|
/* $$ = make4_str(make3_str(mm_strdup(actual_storage[struct_level]), make1_str(" struct varchar_"), mm_strdup($2)), make1_str(" { int len; char *arr; }"), mm_strdup($2), mm_strdup(dim));*/
|
||||||
break;
|
break;
|
||||||
case ECPGt_char:
|
case ECPGt_char:
|
||||||
case ECPGt_unsigned_char:
|
case ECPGt_unsigned_char:
|
||||||
@ -5189,7 +5304,7 @@ ctype: CHAR
|
|||||||
$$.type_index = -1;
|
$$.type_index = -1;
|
||||||
$$.type_dimension = -1;
|
$$.type_dimension = -1;
|
||||||
}
|
}
|
||||||
| sql_struct_or_union
|
| SQL_STRUCT
|
||||||
{
|
{
|
||||||
struct_member_list[struct_level++] = NULL;
|
struct_member_list[struct_level++] = NULL;
|
||||||
if (struct_level >= STRUCT_DEPTH)
|
if (struct_level >= STRUCT_DEPTH)
|
||||||
@ -5197,11 +5312,24 @@ ctype: CHAR
|
|||||||
} '{' sql_variable_declarations '}'
|
} '{' sql_variable_declarations '}'
|
||||||
{
|
{
|
||||||
ECPGfree_struct_member(struct_member_list[struct_level--]);
|
ECPGfree_struct_member(struct_member_list[struct_level--]);
|
||||||
$$.type_str = cat4_str($1, make1_str("{"), $4, make1_str("}"));
|
$$.type_str = cat3_str(make1_str("struct {"), $4, make1_str("}"));
|
||||||
$$.type_enum = ECPGt_struct;
|
$$.type_enum = ECPGt_struct;
|
||||||
$$.type_index = -1;
|
$$.type_index = -1;
|
||||||
$$.type_dimension = -1;
|
$$.type_dimension = -1;
|
||||||
}
|
}
|
||||||
|
| UNION
|
||||||
|
{
|
||||||
|
struct_member_list[struct_level++] = NULL;
|
||||||
|
if (struct_level >= STRUCT_DEPTH)
|
||||||
|
yyerror("Too many levels in nested structure definition");
|
||||||
|
} '{' sql_variable_declarations '}'
|
||||||
|
{
|
||||||
|
ECPGfree_struct_member(struct_member_list[struct_level--]);
|
||||||
|
$$.type_str = cat3_str(make1_str("union {"), $4, make1_str("}"));
|
||||||
|
$$.type_enum = ECPGt_union;
|
||||||
|
$$.type_index = -1;
|
||||||
|
$$.type_dimension = -1;
|
||||||
|
}
|
||||||
| symbol
|
| symbol
|
||||||
{
|
{
|
||||||
struct typedefs *this = get_typedef($1);
|
struct typedefs *this = get_typedef($1);
|
||||||
@ -5213,9 +5341,6 @@ ctype: CHAR
|
|||||||
struct_member_list[struct_level] = this->struct_member_list;
|
struct_member_list[struct_level] = this->struct_member_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
sql_struct_or_union: SQL_STRUCT { $$ = make1_str("struct"); }
|
|
||||||
| UNION { $$ = make1_str("union"); }
|
|
||||||
|
|
||||||
opt_signed: SQL_SIGNED | /* empty */
|
opt_signed: SQL_SIGNED | /* empty */
|
||||||
|
|
||||||
sql_variable_declarations: /* empty */
|
sql_variable_declarations: /* empty */
|
||||||
@ -5260,10 +5385,11 @@ sql_variable: opt_pointer symbol opt_array_bounds
|
|||||||
switch (actual_type[struct_level].type_enum)
|
switch (actual_type[struct_level].type_enum)
|
||||||
{
|
{
|
||||||
case ECPGt_struct:
|
case ECPGt_struct:
|
||||||
|
case ECPGt_union:
|
||||||
if (dimension < 0)
|
if (dimension < 0)
|
||||||
type = ECPGmake_struct_type(struct_member_list[struct_level]);
|
type = ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum);
|
||||||
else
|
else
|
||||||
type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level]), dimension);
|
type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum), dimension);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case ECPGt_varchar:
|
case ECPGt_varchar:
|
||||||
@ -5330,10 +5456,11 @@ ECPGVar: SQL_VAR symbol IS ctype opt_type_array_bounds opt_reference
|
|||||||
switch ($4.type_enum)
|
switch ($4.type_enum)
|
||||||
{
|
{
|
||||||
case ECPGt_struct:
|
case ECPGt_struct:
|
||||||
|
case ECPGt_union:
|
||||||
if (dimension < 0)
|
if (dimension < 0)
|
||||||
type = ECPGmake_struct_type(struct_member_list[struct_level]);
|
type = ECPGmake_struct_type(struct_member_list[struct_level], $4.type_enum);
|
||||||
else
|
else
|
||||||
type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level]), dimension);
|
type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], $4.type_enum), dimension);
|
||||||
break;
|
break;
|
||||||
case ECPGt_varchar:
|
case ECPGt_varchar:
|
||||||
if (dimension == -1)
|
if (dimension == -1)
|
||||||
|
@ -47,7 +47,8 @@ ECPGstruct_member_dup(struct ECPGstruct_member * rm)
|
|||||||
switch (rm->typ->typ)
|
switch (rm->typ->typ)
|
||||||
{
|
{
|
||||||
case ECPGt_struct:
|
case ECPGt_struct:
|
||||||
type = ECPGmake_struct_type(rm->typ->u.members);
|
case ECPGt_union:
|
||||||
|
type = ECPGmake_struct_type(rm->typ->u.members, rm->typ->typ);
|
||||||
break;
|
break;
|
||||||
case ECPGt_array:
|
case ECPGt_array:
|
||||||
type = ECPGmake_array_type(ECPGmake_simple_type(rm->typ->u.element->typ, rm->typ->u.element->size), rm->typ->size);
|
type = ECPGmake_array_type(ECPGmake_simple_type(rm->typ->u.element->typ, rm->typ->u.element->size), rm->typ->size);
|
||||||
@ -108,9 +109,9 @@ ECPGmake_array_type(struct ECPGtype * typ, long siz)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct ECPGtype *
|
struct ECPGtype *
|
||||||
ECPGmake_struct_type(struct ECPGstruct_member * rm)
|
ECPGmake_struct_type(struct ECPGstruct_member * rm, enum ECPGttype type)
|
||||||
{
|
{
|
||||||
struct ECPGtype *ne = ECPGmake_simple_type(ECPGt_struct, 1);
|
struct ECPGtype *ne = ECPGmake_simple_type(type, 1);
|
||||||
|
|
||||||
ne->u.members = ECPGstruct_member_dup(rm);
|
ne->u.members = ECPGstruct_member_dup(rm);
|
||||||
|
|
||||||
@ -122,7 +123,7 @@ get_type(enum ECPGttype typ)
|
|||||||
{
|
{
|
||||||
switch (typ)
|
switch (typ)
|
||||||
{
|
{
|
||||||
case ECPGt_char:
|
case ECPGt_char:
|
||||||
return ("ECPGt_char");
|
return ("ECPGt_char");
|
||||||
break;
|
break;
|
||||||
case ECPGt_unsigned_char:
|
case ECPGt_unsigned_char:
|
||||||
@ -167,6 +168,8 @@ get_type(enum ECPGttype typ)
|
|||||||
sprintf(errortext, "illegal variable type %d\n", typ);
|
sprintf(errortext, "illegal variable type %d\n", typ);
|
||||||
yyerror(errortext);
|
yyerror(errortext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Dump a type.
|
/* Dump a type.
|
||||||
@ -202,38 +205,45 @@ ECPGdump_a_type(FILE *o, const char *name, struct ECPGtype * typ, const char *in
|
|||||||
switch (typ->typ)
|
switch (typ->typ)
|
||||||
{
|
{
|
||||||
case ECPGt_array:
|
case ECPGt_array:
|
||||||
if (IS_SIMPLE_TYPE(typ->u.element->typ))
|
switch (typ->u.element->typ)
|
||||||
{
|
{
|
||||||
ECPGdump_a_simple(o, name, typ->u.element->typ,
|
case ECPGt_array:
|
||||||
|
yyerror("No nested arrays allowed (except strings)"); /* array of array */
|
||||||
|
break;
|
||||||
|
case ECPGt_struct:
|
||||||
|
case ECPGt_union:
|
||||||
|
ECPGdump_a_struct(o, name, ind_name, typ->size, typ->u.element, ind_typ->u.element, NULL, prefix, ind_prefix);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (!IS_SIMPLE_TYPE(typ->u.element->typ))
|
||||||
|
yyerror("Internal error: unknown datatype, please inform pgsql-bugs@postgresql.org");
|
||||||
|
|
||||||
|
ECPGdump_a_simple(o, name, typ->u.element->typ,
|
||||||
typ->u.element->size, typ->size, NULL, prefix);
|
typ->u.element->size, typ->size, NULL, prefix);
|
||||||
if (ind_typ->typ == ECPGt_NO_INDICATOR)
|
if (ind_typ->typ == ECPGt_NO_INDICATOR)
|
||||||
ECPGdump_a_simple(o, ind_name, ind_typ->typ, ind_typ->size, -1, NULL, ind_prefix);
|
ECPGdump_a_simple(o, ind_name, ind_typ->typ, ind_typ->size, -1, NULL, ind_prefix);
|
||||||
else
|
else
|
||||||
{
|
|
||||||
if (ind_typ->typ != ECPGt_array)
|
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Indicator for an array has to be array too.\n");
|
if (ind_typ->typ != ECPGt_array)
|
||||||
exit(INDICATOR_NOT_ARRAY);
|
{
|
||||||
}
|
fprintf(stderr, "Indicator for an array has to be array too.\n");
|
||||||
ECPGdump_a_simple(o, ind_name, ind_typ->u.element->typ,
|
exit(INDICATOR_NOT_ARRAY);
|
||||||
|
}
|
||||||
|
ECPGdump_a_simple(o, ind_name, ind_typ->u.element->typ,
|
||||||
ind_typ->u.element->size, ind_typ->size, NULL, prefix);
|
ind_typ->u.element->size, ind_typ->size, NULL, prefix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (typ->u.element->typ == ECPGt_array)
|
|
||||||
{
|
|
||||||
yyerror("No nested arrays allowed (except strings)"); /* array of array */
|
|
||||||
}
|
|
||||||
else if (typ->u.element->typ == ECPGt_struct)
|
|
||||||
{
|
|
||||||
/* Array of structs */
|
|
||||||
ECPGdump_a_struct(o, name, ind_name, typ->size, typ->u.element, ind_typ->u.element, NULL, prefix, ind_prefix);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
yyerror("Internal error: unknown datatype, please inform pgsql-bugs@postgresql.org");
|
|
||||||
break;
|
break;
|
||||||
case ECPGt_struct:
|
case ECPGt_struct:
|
||||||
ECPGdump_a_struct(o, name, ind_name, 1, typ, ind_typ, NULL, prefix, ind_prefix);
|
ECPGdump_a_struct(o, name, ind_name, 1, typ, ind_typ, NULL, prefix, ind_prefix);
|
||||||
break;
|
break;
|
||||||
|
case ECPGt_union: /* cannot dump a complete union */
|
||||||
|
yyerror("Type of union has to be specified");
|
||||||
|
break;
|
||||||
|
case ECPGt_char_variable:
|
||||||
|
ECPGdump_a_simple(o, name, typ->typ, 1, 1, NULL, prefix);
|
||||||
|
ECPGdump_a_simple(o, ind_name, ind_typ->typ, ind_typ->size, -1, NULL, ind_prefix);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
ECPGdump_a_simple(o, name, typ->typ, typ->size, -1, NULL, prefix);
|
ECPGdump_a_simple(o, name, typ->typ, typ->size, -1, NULL, prefix);
|
||||||
ECPGdump_a_simple(o, ind_name, ind_typ->typ, ind_typ->size, -1, NULL, ind_prefix);
|
ECPGdump_a_simple(o, ind_name, ind_typ->typ, ind_typ->size, -1, NULL, ind_prefix);
|
||||||
@ -259,7 +269,9 @@ ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype typ,
|
|||||||
char *variable = (char *) mm_alloc(strlen(name) + ((prefix == NULL) ? 0 : strlen(prefix)) + 4);
|
char *variable = (char *) mm_alloc(strlen(name) + ((prefix == NULL) ? 0 : strlen(prefix)) + 4);
|
||||||
char *offset = (char *) mm_alloc(strlen(name) + strlen("sizeof(struct varchar_)") + 1);
|
char *offset = (char *) mm_alloc(strlen(name) + strlen("sizeof(struct varchar_)") + 1);
|
||||||
|
|
||||||
if (varcharsize == 0 || arrsize >= 0)
|
/* if (varcharsize == 0 || arrsize >= 0)*/
|
||||||
|
/* we have to use the pointer except for arrays with given bounds */
|
||||||
|
if (arrsize > 0)
|
||||||
sprintf(variable, "(%s%s)", prefix ? prefix : "", name);
|
sprintf(variable, "(%s%s)", prefix ? prefix : "", name);
|
||||||
else
|
else
|
||||||
sprintf(variable, "&(%s%s)", prefix ? prefix : "", name);
|
sprintf(variable, "&(%s%s)", prefix ? prefix : "", name);
|
||||||
@ -272,7 +284,7 @@ ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype typ,
|
|||||||
case ECPGt_char:
|
case ECPGt_char:
|
||||||
case ECPGt_unsigned_char:
|
case ECPGt_unsigned_char:
|
||||||
case ECPGt_char_variable:
|
case ECPGt_char_variable:
|
||||||
sprintf(offset, "%ld*sizeof(char)", varcharsize);
|
sprintf(offset, "%ld*sizeof(char)", varcharsize == 0 ? 1 : varcharsize);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
sprintf(offset, "sizeof(%s)", ECPGtype_name(typ));
|
sprintf(offset, "sizeof(%s)", ECPGtype_name(typ));
|
||||||
@ -353,34 +365,36 @@ ECPGfree_type(struct ECPGtype * typ)
|
|||||||
{
|
{
|
||||||
if (!IS_SIMPLE_TYPE(typ->typ))
|
if (!IS_SIMPLE_TYPE(typ->typ))
|
||||||
{
|
{
|
||||||
if (typ->typ == ECPGt_array)
|
switch(typ->typ)
|
||||||
{
|
{
|
||||||
if (IS_SIMPLE_TYPE(typ->u.element->typ))
|
case ECPGt_array:
|
||||||
free(typ->u.element);
|
switch (typ->u.element->typ)
|
||||||
else if (typ->u.element->typ == ECPGt_array)
|
{
|
||||||
/* Array of array, */
|
case ECPGt_array:
|
||||||
yyerror("internal error, found multi-dimensional array\n");
|
yyerror("internal error, found multi-dimensional array\n");
|
||||||
else if (typ->u.element->typ == ECPGt_struct)
|
break;
|
||||||
{
|
case ECPGt_struct:
|
||||||
/* Array of structs. */
|
case ECPGt_union:
|
||||||
ECPGfree_struct_member(typ->u.element->u.members);
|
/* Array of structs. */
|
||||||
|
ECPGfree_struct_member(typ->u.element->u.members);
|
||||||
|
free(typ->u.members);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (!IS_SIMPLE_TYPE(typ->u.element->typ))
|
||||||
|
yyerror("Internal error: unknown datatype, please inform pgsql-bugs@postgresql.org");
|
||||||
|
|
||||||
|
free(typ->u.element);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ECPGt_struct:
|
||||||
|
case ECPGt_union:
|
||||||
|
ECPGfree_struct_member(typ->u.members);
|
||||||
free(typ->u.members);
|
free(typ->u.members);
|
||||||
}
|
break;
|
||||||
else
|
default:
|
||||||
{
|
sprintf(errortext, "illegal variable type %d\n", typ->typ);
|
||||||
sprintf(errortext, "illegal variable type %d\n", typ);
|
|
||||||
yyerror(errortext);
|
yyerror(errortext);
|
||||||
}
|
break;
|
||||||
}
|
|
||||||
else if (typ->typ == ECPGt_struct)
|
|
||||||
{
|
|
||||||
ECPGfree_struct_member(typ->u.members);
|
|
||||||
free(typ->u.members);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sprintf(errortext, "illegal variable type %d\n", typ);
|
|
||||||
yyerror(errortext);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(typ);
|
free(typ);
|
||||||
|
@ -29,7 +29,7 @@ void ECPGmake_struct_member(char *, struct ECPGtype *, struct ECPGstruct_member
|
|||||||
struct ECPGtype *ECPGmake_simple_type(enum ECPGttype, long);
|
struct ECPGtype *ECPGmake_simple_type(enum ECPGttype, long);
|
||||||
struct ECPGtype *ECPGmake_varchar_type(enum ECPGttype, long);
|
struct ECPGtype *ECPGmake_varchar_type(enum ECPGttype, long);
|
||||||
struct ECPGtype *ECPGmake_array_type(struct ECPGtype *, long);
|
struct ECPGtype *ECPGmake_array_type(struct ECPGtype *, long);
|
||||||
struct ECPGtype *ECPGmake_struct_type(struct ECPGstruct_member *);
|
struct ECPGtype *ECPGmake_struct_type(struct ECPGstruct_member *, enum ECPGttype type);
|
||||||
struct ECPGstruct_member * ECPGstruct_member_dup(struct ECPGstruct_member *);
|
struct ECPGstruct_member * ECPGstruct_member_dup(struct ECPGstruct_member *);
|
||||||
|
|
||||||
/* Frees a type. */
|
/* Frees a type. */
|
||||||
|
@ -5,8 +5,8 @@ exec sql include header_test;
|
|||||||
exec sql type c is char reference;
|
exec sql type c is char reference;
|
||||||
typedef char* c;
|
typedef char* c;
|
||||||
|
|
||||||
exec sql type ind is union { int integer; short smallinteger; };
|
exec sql type ind is union { int integer; short smallint; };
|
||||||
typedef union { int integer; short smallinteger; } ind;
|
typedef union { int integer; short smallint; } ind;
|
||||||
|
|
||||||
int
|
int
|
||||||
main ()
|
main ()
|
||||||
@ -23,7 +23,7 @@ exec sql begin declare section;
|
|||||||
int ind_married;
|
int ind_married;
|
||||||
ind children;
|
ind children;
|
||||||
ind ind_children;
|
ind ind_children;
|
||||||
char married[9];
|
char *married = NULL;
|
||||||
c testname="Petra";
|
c testname="Petra";
|
||||||
char *query="select name, born, age, married, children from meskes where name = :var1";
|
char *query="select name, born, age, married, children from meskes where name = :var1";
|
||||||
exec sql end declare section;
|
exec sql end declare section;
|
||||||
@ -43,7 +43,7 @@ exec sql end declare section;
|
|||||||
exec sql connect to unix:postgresql://localhost:5432/mm;
|
exec sql connect to unix:postgresql://localhost:5432/mm;
|
||||||
|
|
||||||
strcpy(msg, "create");
|
strcpy(msg, "create");
|
||||||
exec sql create table meskes(name char(8), born integer, age smallint, married char(8), children integer);
|
exec sql create table meskes(name char(8), born integer, age smallint, married date, children integer);
|
||||||
|
|
||||||
strcpy(msg, "insert");
|
strcpy(msg, "insert");
|
||||||
exec sql insert into meskes(name, married, children) values ('Petra', '19900404', 3);
|
exec sql insert into meskes(name, married, children) values ('Petra', '19900404', 3);
|
||||||
@ -62,17 +62,20 @@ exec sql end declare section;
|
|||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
strcpy(msg, "fetch");
|
strcpy(msg, "fetch");
|
||||||
exec sql fetch in cur into :personal:ind_personal, :married:ind_married, :children.integer:ind_children.smallinteger;
|
exec sql fetch in cur into :personal:ind_personal, :married:ind_married, :children.integer:ind_children.smallint;
|
||||||
printf("%8.8s", personal.name.arr);
|
printf("%8.8s", personal.name.arr);
|
||||||
if (!ind_personal.ind_birth.born)
|
if (ind_personal.ind_birth.born >= 0)
|
||||||
printf(", born %d", personal.birth.born);
|
printf(", born %d", personal.birth.born);
|
||||||
if (!ind_personal.ind_birth.age)
|
if (ind_personal.ind_birth.age >= 0)
|
||||||
printf(", age = %d", personal.birth.age);
|
printf(", age = %d", personal.birth.age);
|
||||||
if (!ind_married)
|
if (ind_married >= 0)
|
||||||
printf(", married %s", married);
|
printf(", married %10.10s", married);
|
||||||
if (!ind_children.smallinteger)
|
if (ind_children.smallint >= 0)
|
||||||
printf(", children = %d", children.integer);
|
printf(", children = %d", children.integer);
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
|
|
||||||
|
free(married);
|
||||||
|
married = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
strcpy(msg, "close");
|
strcpy(msg, "close");
|
||||||
@ -89,19 +92,21 @@ exec sql end declare section;
|
|||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
strcpy(msg, "fetch");
|
strcpy(msg, "fetch");
|
||||||
exec sql fetch in prep into :personal:ind_personal, :married:ind_married, :children.integer:ind_children.smallinteger;
|
exec sql fetch in prep into :personal:ind_personal, :married:ind_married, :children.integer:ind_children.smallint;
|
||||||
printf("%8.8s", personal.name.arr);
|
printf("%8.8s", personal.name.arr);
|
||||||
if (!ind_personal.ind_birth.born)
|
if (ind_personal.ind_birth.born >= 0)
|
||||||
printf(", born %d", personal.birth.born);
|
printf(", born %d", personal.birth.born);
|
||||||
if (!ind_personal.ind_birth.age)
|
if (ind_personal.ind_birth.age >= 0)
|
||||||
printf(", age = %d", personal.birth.age);
|
printf(", age = %d", personal.birth.age);
|
||||||
if (!ind_married)
|
if (ind_married >= 0)
|
||||||
printf(", married %s", married);
|
printf(", married %10.10s", married);
|
||||||
if (!ind_children.smallinteger)
|
if (ind_children.smallint >= 0)
|
||||||
printf(", children = %d", children.integer);
|
printf(", children = %d", children.integer);
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(married);
|
||||||
|
|
||||||
strcpy(msg, "close");
|
strcpy(msg, "close");
|
||||||
exec sql close prep;
|
exec sql close prep;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user