P8000/WEGA/contrib/ingres/dbs/src/parser/master.y

995 lines
18 KiB
Plaintext

/*
** This file contains the specification of QL recognized by the parser.
*/
/* COMMANDS */
%term APPEND COPY CREATE DELETE DESTROY HELP INDEX MODIFY
%term PRINT RANGE REPLACE RETRIEVE SAVE
%term DEFINE PERMIT VIEW INTEGRITY
/*DDD*/%term DISTRIBUTE
/* 'NOISE' WORDS */
%term ALL BY FROM IN INTO UNIQUE AT
%term IS OF ON TO UNTIL WHERE
/*DDD*/%term DISTRD
/* CONSTANTS */
%term NAME SCONST I2CONST I4CONST F4CONST F8CONST
/* PUNCTUATION */
%term COMMA LPAREN PERIOD RPAREN COLON BGNCMNT ENDCMNT
/* UNARY ARITHMETIC OPERATORS */
%term UAOP
/* BINARY ARITHMETIC OPERATORS */
%term BAOP BAOPH
/* BOUNDS OPERATORS */
%term BDOP
/* EQUALITY OPERATORS */
%term EOP
/* LOGICAL OPERATORS */
%term LBOP LUOP
/* FUNCTIONAL OPERATORS */
%term FOP FBOP
/* AGGREGATE OPERATORS */
%term AGOP
/* DEFINE ASCENDING PRECEDENCE FOR OPERATORS */
%left LBOP
%left LUOP
%left UAOP
%left BAOP
%left BAOPH
%binary unaryop
%{
/* SCANNER/PARSER GLOBALS & TABLES */
# include "gen.h"
# include "../h/dbs.h"
# include "../h/aux.h"
# include "../h/tree.h"
# include "../h/symbol.h"
# include "parser.h"
struct rngtab *Resrng; /* ptr to result reln entry */
QTREE *Lastree; /* pointer to root node of tree */
DESC Reldesc; /* descriptor for range table lookup */
short Rsdmno; /* result domain number */
int Opflag; /* operator flag contains query mode */
char *Indexname; /* ptr to name of index */
char *Trname; /* pointer to attribute name */
int Agflag; /* how many aggs in this qry */
int Patflag; /* signals a pattern match reduction */
int Qlflag; /* set when processing a qual */
int yyline; /* line counter */
short Permcomd;
static QTREE *Tidnode; /* pointer to tid node of targ list
for REPLACE, DELETE */
%}
%%
%{
register int i;
register struct atstash *aptr;
register char *p;
char permbuf[3];
extern char *AA_iocv();
extern char *AAztack();
extern QTREE *tree();
extern char *tlprepend();
extern char *addresdom();
extern char *xdot();
extern char *norml();
extern struct atstash *attlookup();
extern struct rngtab *rngent();
extern struct rngtab *rnglook();
/* space for two names, their null bytes and the seperator */
char modbuf[(2 * (MAXNAME + 1)) + 1];
static char hqmbuf[2];
%}
program: xprogram
| /* empty */
;
xprogram: xprogram stmnt =
{
endqlst(Opflag);
}
| stmnt =
{
endqlst(Opflag);
}
;
stmnt: append
| copy
| create
| delete
| destroy
/*DDD*/ | distribute
| help
| index
| integrity
| modify
| permit
| print
| range
| replace
| retrieve
| save
| view
;
range: rngvar
| rngprint =
{
rngprint();
}
;
rngprint: rngstmnt
;
rngvar: rngstmnt rngof NAME IS NAME =
{
if ((i = AArelopen(&Reldesc, -1, $5)) < 0)
AAsyserr(18012, i);
if (i > 0)
/* invalid relation name */
yyerror(RNGEXIST, $5, (char *) 0);
rngent(R_EXTERNAL, $3, $5, Reldesc.reldum.relowner,
Reldesc.reldum.relatts, Reldesc.reldum.relstat);
}
;
rngstmnt: RANGE =
{
Opflag = (int) mdRANGE;
}
;
rngof: OF
| /* empty */
;
append: apstmnt apto relation tlclause qualclause =
{
/* make root node */
Lastree = tree($4, $5, ROOT, 0);
}
;
apstmnt: APPEND =
{
Opflag = (int) mdAPP;
}
;
apto: TO
| /* empty */
;
delete: delstmnt relation qualclause =
{
/* make root node for delete, with a TIDNODE at leftmost */
Lastree = tree(tree((QTREE *) 0, Tidnode, RESDOM, RES_SIZ, (char *) 0), $3, ROOT, 0);
}
;
delstmnt: DELETE =
{
Opflag = (int) mdDEL;
}
;
replace: repstmnt relation tlclause qualclause =
{
/* make root node for replace */
Lastree = tree($3, $4, ROOT, 0);
}
;
repstmnt: REPLACE =
{
Opflag = (int) mdREPL;
}
;
retrieve: retstmnt retclause tlclause qualclause =
{
/* make root node for retrieve */
Lastree = tree($3, $4, ROOT, 0);
}
;
retstmnt: RETRIEVE =
{
Opflag = (int) mdRETR;
}
;
retclause: retkwd relation =
{
/* set up pipe block and save relname for create */
Rsdmno = 0;
setp("0"); /* relstat = nil */
setp(Resrng->relnm);
}
| /* empty */ =
{
/* no result relation, output to terminal */
Rsdmno = 0;
Resrng = 0;
}
| UNIQUE =
{
Opflag = (int) mdRET_UNI;
Rsdmno = 0;
Resrng = 0;
}
;
retkwd: INTO
| /* empty */
;
view: viewclause tlclause qualclause =
{
Lastree = tree($2, $3, ROOT, 0);
}
;
viewclause: viewstmnt relation =
{
Rsdmno = 0;
setp("0040"); /* relstat = S_VIEW */
setp(Resrng->relnm);
}
;
viewstmnt: DEFINE VIEW =
{
Opflag = (int) mdVIEW;
if (!Qrymod)
/* no qrymod in database */
yyerror(NOQRYMOD, (char *) 0);
}
;
permit: permstmnt permlist permrel permtarg permwho permplace permtd qualclause =
{
Lastree = tree($4, $8, ROOT, 0);
}
;
permstmnt: DEFINE PERMIT =
{
Opflag = (int) mdPROT;
if (!Qrymod)
/* no qrymod in database */
yyerror(NOQRYMOD, (char *) 0);
}
;
permlist: permxlist
| permlist COMMA permxlist
;
permxlist: ALL =
{
permcom(-1); /* means 'all' commands */
}
| RETRIEVE =
{
permcom((int) mdRETR);
}
| DELETE =
{
permcom((int) mdDEL);
}
| APPEND =
{
permcom((int) mdAPP);
}
| REPLACE =
{
permcom((int) mdREPL);
}
;
permrel: permword relation =
{
/* put command vector into list now since this always happens */
setp(AA_iocv(Permcomd));
Permcomd = 0; /* reset command map */
setp(Resrng->relnm);
AAbmove(Resrng->relnowner, permbuf, 2);
permbuf[2] = 0;
setp(permbuf);
}
;
permword: ON
| OF
| TO
;
permtarg: LPAREN permtlist RPAREN =
{
$$ = $2;
}
| /* empty */ =
{
$$ = (char *) 0;
}
;
permtlist: permtlelm
| permtlist COMMA permtlelm =
{
/* attach bulk of permit tl to leftmost node of new elem */
$$ = tlprepend($1, $3);
}
;
permtlelm: NAME =
{
/* Resrng is set by the AA_REL production */
Trname = $1;
aptr = attlookup(Resrng, Trname);
$$ = (char *) tree((QTREE *) 0, (QTREE *) 0, VAR, VAR_SIZ, CAST(Resrng->rentno), aptr);
$$ = (char *) addresdom((QTREE *) 0, $$);
}
;
permwho: TO NAME =
{
setp($2);
}
| TO ALL =
{
setp("all");
}
;
permplace: AT NAME =
{
setp($2);
}
| AT ALL =
{
setp("all");
}
| /* empty */ =
{
setp("all"); /* default is all */
}
;
permtd: permtime permday
| permdeftime permday
| permtime permdefday
| permdeftime permdefday
;
permdeftime: /* empty */ =
{
setp("0");
setp("1440");
}
;
permdefday: /* empty */ =
{
setp("sun");
setp("sat");
}
;
permtime: FROM I2CONST COLON I2CONST TO I2CONST COLON I2CONST =
{
setp(AA_iocv(timeofday($2, $4)));
setp(AA_iocv(timeofday($6, $8)));
}
;
permday: ON NAME TO NAME =
{
setp($2);
setp($4);
}
;
integrity: integstmnt integnoise relation integis qual =
{
Lastree = tree((QTREE *) 0, norml($5), ROOT, 0);
Qlflag--; /* turn off here */
}
;
integstmnt: DEFINE INTEGRITY =
{
Opflag = (int) mdINTEG;
Qlflag++; /* OK to turn on here because integrity doesn't have a targ list */
if (!Qrymod)
/* no qrymod in database */
yyerror(NOQRYMOD, (char *) 0);
}
;
integnoise: ON
| /* empty */
;
integis: IS
| /* empty */
;
/*DDD*/distribute: diststmnt relation AT distcrits =
/*DDD*/ {
/*DDD*/ $$ = (char *) tree((QTREE *) 0, (QTREE *) 0, QLEND, 0);
/*DDD*/ Lastree = tree($4, $$, ROOT, 0);
/*DDD*/ }
/*DDD*/;
/*DDD*/diststmnt: DISTRIBUTE =
/*DDD*/ Opflag = mdDISTRIB;
/*DDD*/;
/*DDD*/distcrits: dcriterion =
/*DDD*/ {
/*DDD*/ $$ = $1;
/*DDD*/ }
/*DDD*/ | distcrits dcriterion =
/*DDD*/ {
/*DDD*/ $$ = tlprepend($1, $2);
/*DDD*/ }
/*DDD*/;
/*DDD*/dcriterion: NAME where qual =
/*DDD*/ {
/*DDD*/ Qlflag--;
/*DDD*/ $$ = (char *) tree((QTREE *) 0, norml($3), SITE, OP_SIZ, $1);
/*DDD*/ }
/*DDD*/;
relation: NAME =
{
# ifdef xPTR2
AAtTfp(32, 0, "res rel name/var: '%s'\n", $1);
# endif
switch (Opflag)
{
case mdRETR:
case mdVIEW:
/* result better not be a rel name */
if ((i = AArelopen(&Reldesc, -1, $1)) < 0)
AAsyserr(18013, i);
if (i == 0)
{
/* reln exists */
if (AAbequal(Reldesc.reldum.relowner, AAusercode, 2))
{
/* same owner, can't duplicate name */
yyerror(RESEXIST, $1, (char *) 0);
}
else
{
/* owned by dba -- purge range table */
rngdel($1);
}
}
Resrng = rngent(R_INTERNAL, "", $1, AAusercode, 0, 0);
break;
case mdAPP:
/* result is a rel name */
Resrng = rnglook($1, LOOKREL);
if (Resrng == 0)
{
if ((i = AArelopen(&Reldesc, -1, $1)) < 0)
AAsyserr(18013, i);
if (i)
/* invalid relation name */
yyerror(RESAPPEX, $1, (char *) 0);
Resrng = rngent(R_INTERNAL, "", $1,
Reldesc.reldum.relowner,
Reldesc.reldum.relatts,
Reldesc.reldum.relstat);
}
checkupd(Resrng);
break;
case mdPROT:
case mdINTEG:
# ifdef DISTRIB
case mdDISTRIB:
# endif
/* the result is a tuple variable */
Resrng = rnglook($1, LOOKVAR);
if (Resrng == 0)
/* variable not declared */
yyerror(NOVBLE, $1, (char *) 0);
break;
case mdREPL:
case mdDEL:
/* the result is a tuple variable */
Resrng = rnglook($1, LOOKVAR);
if (Resrng == 0)
/* variable not declared */
yyerror(NOVBLE, $1, (char *) 0);
checkupd(Resrng);
Tidnode = tree((QTREE *) 0, (QTREE *) 0, VAR, VAR_SIZ, CAST(Resrng->rentno), &Faketid);
break;
}
}
;
tlclause: LPAREN tlist RPAREN =
{
if (Patflag)
/* no patt match in targ list */
yyerror(NOPATMAT, (char *) 0);
$$ = $2;
/*
** replace must have tid node as left branch
** (so does delete but it doesn't have a targ list)
*/
if (Opflag == (int) mdREPL)
{
$$ = tlprepend(tree((QTREE *) 0, Tidnode, RESDOM, RES_SIZ, (char *) 0), $$);
}
}
;
tlist: tlelm
| tlist COMMA tlelm =
{
/*
** attach bulk of targ list to leftmost node
** of new element
*/
$$ = tlprepend($1, $3);
}
;
tlelm: NAME is afcn =
{
Trname = $1;
/* make a new resdom entry for targ list */
$$ = (char *) addresdom((QTREE *) 0, $3);
}
| attrib =
{
/* makes a new resdom entry for targ list */
$$ = (char *) addresdom((QTREE *) 0, $1);
}
| var PERIOD ALL =
{
if (Opflag == (int) mdREPL)
/* ALL not defined for REPLACE */
yyerror(REPALL, ((struct rngtab *) $1)->varname, (char *) 0);
/* makes set of new resdom entries for targ list */
$$ = xdot($1);
}
;
is: IS
| BY
;
qualclause: where qual =
{
# ifdef xPTM
if (AAtTf(76, 2))
timtrace(25, 0);
# endif
$$ = norml($2);
Qlflag--;
# ifdef xPTM
if (AAtTf(76, 2))
timtrace(26, 0);
# endif
}
| /* empty */ =
{
/* null qualification */
$$ = norml((QTREE *) 0);
}
;
where: WHERE =
{
Qlflag++;
}
;
qual: LPAREN qual RPAREN =
{
$$ = $2;
}
| LUOP qual =
{
$$ = (char *) tree((QTREE *) 0, $2, UOP, OP_SIZ, $1);
}
| qual LBOP qual =
{
$$ = (char *) tree($1, $3, $2, 0, (char *) 0);
}
| clause
;
clause: afcn relop afcn =
{
$$ = (char *) tree($1, $3, BOP, OP_SIZ, $2);
}
;
relop: EOP
| IS
| BDOP
;
afcn: aggrfcn =
{
Agflag++;
}
| attribfcn
| afcn BAOPH afcn =
{
$$ = (char *) tree($1, $3, BOP, OP_SIZ, $2);
}
| afcn BAOP afcn =
{
$$ = (char *) tree($1, $3, BOP, OP_SIZ, $2);
}
| afcn UAOP afcn =
{
$$ = (char *) tree($1, $3, BOP, OP_SIZ, $2);
}
| LPAREN afcn RPAREN =
{
$$ = $2;
}
| uop afcn %prec unaryop =
{
$$ = (char *) tree((QTREE *) 0, $2, UOP, OP_SIZ, $1);
}
| FOP LPAREN afcn RPAREN =
{
$$ = (char *) tree($3, (QTREE *) 0, UOP, OP_SIZ, $1);
}
| FBOP LPAREN afcn COMMA afcn RPAREN =
{
$$ = (char *) tree($3, $5, BOP, OP_SIZ, $1);
}
;
aggrfcn: AGOP LPAREN afcn BY domseq qualclause RPAREN =
{
# ifdef xPTR2
AAtTfp(35, 0, "agg func\n");
# endif
windup($5);
$$ = (char *) tree(tree($5, tree((QTREE *) 0, $3, AOP, AOP_SIZ, $1), BYHEAD, 0, (char *) 0), $6, AGHEAD, 0, (char *) 0);
}
| AGOP LPAREN afcn qualclause RPAREN =
{
$$ = (char *) tree(tree((QTREE *) 0, $3, AOP, AOP_SIZ, $1), $4, AGHEAD, 0, (char *) 0);
}
;
domseq: targdom
| domseq COMMA targdom =
{
$$ = tlprepend($1, $3);
}
;
targdom: afcn =
{
$$ = (char *) tree((QTREE *) 0, $1, RESDOM, RES_SIZ, CAST(Rsdmno));
}
;
attrib: var PERIOD NAME =
{
# ifdef xPTR2
AAtTfp(37, 0, "attrib %s.%s found\n", ((struct rngtab *) $1)->varname, $3);
# endif
/* remember attribute name */
Trname = $3;
/* look up attribute */
aptr = attlookup($1, Trname);
$$ = (char *) tree((QTREE *) 0, (QTREE *) 0, VAR, VAR_SIZ, CAST(((struct rngtab *) $1)->rentno), aptr);
}
;
var: NAME =
{
$$ = (char *) rnglook($1, LOOKVAR);
if ($$ == 0)
/* variable not declared */
yyerror(NOVBLE, $1, (char *) 0);
}
;
attribfcn: I2CONST =
{
$$ = (char *) tree((QTREE *) 0, (QTREE *) 0, INT, sizeof (short), $1);
}
| I4CONST =
{
$$ = (char *) tree((QTREE *) 0, (QTREE *) 0, INT, sizeof (long), $1);
}
| F4CONST =
{
# ifdef NO_F4
goto f8_tree;
# else
$$ = (char *) tree((QTREE *) 0, (QTREE *) 0, FLOAT, sizeof (float), $1);
# endif
}
| F8CONST =
{
f8_tree:
$$ = (char *) tree((QTREE *) 0, (QTREE *) 0, FLOAT, sizeof (double), $1);
}
| SCONST =
{
if (patmat($1) && !Qlflag)
Patflag = 1;
$$ = (char *) tree((QTREE *) 0, (QTREE *) 0, CHAR, AAlength($1), $1);
}
| NAME =
{
$$ = (char *) tree((QTREE *) 0, (QTREE *) 0, COP, OP_SIZ, $1);
}
| attrib
;
uop: UAOP %prec unaryop =
{
if ($1 == (char *) ((int) opADD))
$$ = (char *) ((int) opPLUS);
else
if ($1 == (char *) ((int) opSUB))
$$ = (char *) ((int) opMINUS);
}
;
copy: copstmnt alias LPAREN coparam RPAREN keywd SCONST =
{
# ifdef xPTR2
AAtTfp(41, 0, "copy %s,%s\n", $2, $7);
# endif
setp($7);
}
;
copstmnt: COPY =
{
Opflag = (int) mdCOPY;
}
;
coparam: cospecs
| /* empty */
;
cospecs: alias is coent
| cospecs COMMA alias is coent
;
coent: alias
| SCONST =
{
setp($1);
}
;
alias: NAME =
{
setp($1);
if (Opflag == (int) mdDESTROY
# ifdef DISTRIB
|| Opflag == mdDCREATE
# endif
|| Opflag == (int) mdCREATE)
rngdel($1);
}
;
specs: alias is alias
| specs COMMA alias is alias
;
keywd: INTO =
{
setp("\0");
setp("i");
}
| FROM =
{
setp("\0");
setp("f");
}
;
create: crestmnt alias LPAREN specs RPAREN
;
crestmnt: CREATE =
{
Opflag = (int) mdCREATE;
/* set up parameters for regular create */
setp("0"); /* relstat = nil */
}
/*DDD*/ | CREATE DISTRD =
/*DDD*/ {
/*DDD*/ Opflag = mdDCREATE;
/*DDD*/
/*DDD*/ /* setup parameters for distributed create */
/*DDD*/ setp("U");
/*DDD*/ setp("");
/*DDD*/ setp("01000"); /* relstat = S_DISTRIBUTED */
/*DDD*/ }
;
destroy: destmnt keys
| destqm destlist
;
destmnt: DESTROY =
{
Opflag = (int) mdDESTROY;
}
;
destqm: destmnt INTEGRITY NAME =
{
Opflag = (int) mdREMQM;
if (!Qrymod)
/* no qrymod in database */
yyerror(NOQRYMOD, (char *) 0);
setp("6");
setp($3);
}
| destmnt PERMIT NAME =
{
Opflag = (int) mdREMQM;
if (!Qrymod)
/* no qrymod in database */
yyerror(NOQRYMOD, (char *) 0);
setp("5");
setp($3);
}
;
destlist: I2CONST =
{
setp(AA_iocv(((I2TYPE *) $1)->i2type));
}
| destlist COMMA I2CONST =
{
setp(AA_iocv(((I2TYPE *) $3)->i2type));
}
| ALL
;
help: helstmnt hlist
| helstmnt =
{
setp("2"); /* all relns */
}
| helqmstmnt hqmlist
;
helstmnt: HELP =
{
Opflag = (int) mdHELP;
}
;
helqmstmnt: HELP VIEW =
{
Opflag = (int) mdDISPLAY;
if (!Qrymod)
/* no qrymod in database */
yyerror(NOQRYMOD, (char *) 0);
AAsmove("4", hqmbuf);
}
| HELP PERMIT =
{
Opflag = (int) mdDISPLAY;
if (!Qrymod)
/* no qrymod in database */
yyerror(NOQRYMOD, (char *) 0);
AAsmove("5", hqmbuf);
}
| HELP INTEGRITY =
{
Opflag = (int) mdDISPLAY;
if (!Qrymod) /* no qrymod in database */
yyerror(NOQRYMOD, (char *) 0);
AAsmove("6", hqmbuf);
}
;
hlist: hparam
| hlist COMMA hparam
| ALL =
{
setp("3");
}
;
hparam: NAME =
{
/* relation */
setp("0");
setp($1);
}
| SCONST =
{
/* manual page */
setp("1");
setp($1);
}
;
hqmlist: NAME =
{
setp(hqmbuf);
setp($1);
}
| hqmlist COMMA NAME =
{
setp(hqmbuf);
setp($3);
}
;
index: instmnt LPAREN keys RPAREN =
{
if (Rsdmno > MAXKEYS)
/* too many attributes in key */
yyerror(INDEXTRA, (char *) 0);
}
;
instmnt: INDEX ON NAME IS NAME =
{
/* init INDEX command */
Opflag = (int) mdINDEX;
Rsdmno = 0;
setp($3);
setp($5);
Indexname = $5;
}
;
modify: modstmnt alias modstorage modkeys modqual
;
modstmnt: MODIFY =
{
Opflag = (int) mdMODIFY;
Rsdmno = 0;
}
;
modstorage: TO NAME =
{
setp($2);
}
| /* empty */ =
{
setp("same");
}
;
modkeys: modstkey modrptkey
| /* empty */
;
modstkey: ON =
{
setp("name");
}
;
modrptkey: modbasekey
| modrptkey COMMA modbasekey
;
modbasekey: NAME =
{
setp($1);
}
| NAME COLON NAME =
{
AAconcat($1, AAztack(":", $3), modbuf);
setp(modbuf);
}
;
modqual: modcond modfill
| /* empty */
;
modcond: WHERE =
{
setp("\0");
}
;
modfill: modfillnum
| modfill COMMA modfillnum
;
modfillnum: NAME IS I2CONST =
{
setp($1);
setp(AA_iocv(((I2TYPE *) $3)->i2type));
}
;
keys: alias =
{
Rsdmno++;
}
| keys COMMA alias =
{
Rsdmno++;
}
;
print: prinstmnt keys
;
prinstmnt: PRINT =
{
Opflag = (int) mdPRINT;
}
;
save: savstmnt alias UNTIL date
;
savstmnt: SAVE =
{
Opflag = (int) mdSAVE;
}
;
date: month day_year day_year
;
month: alias
| day_year
;
day_year: I2CONST =
{
p = AA_iocv(((I2TYPE *) $1)->i2type);
# ifdef xPTR3
AAtTfp(57, 1, "day_year: %s\n", p);
# endif
setp(p);
}
;
%%
# include "../h/scanner.h"
# include "../h/bs.h"
# include "tables.y"
# include "yyerror.y"