ING_DB
This commit is contained in:
parent
ed38854e0b
commit
7733d3fe88
|
|
@ -0,0 +1,621 @@
|
|||
# include <stdio.h>
|
||||
# include "gen.h"
|
||||
# include "../h/dbs.h"
|
||||
# include "../h/symbol.h"
|
||||
# include "../h/tree.h"
|
||||
# include "../h/aux.h"
|
||||
|
||||
extern FILE *Dbs_out;
|
||||
extern char *pr_trim();
|
||||
extern char *resultres();
|
||||
|
||||
/* This structure must be IDENTICAL to that in readtree.c */
|
||||
struct rngtab
|
||||
{
|
||||
char relid[MAXNAME];
|
||||
char rowner[2];
|
||||
char rused;
|
||||
};
|
||||
|
||||
extern struct rngtab Rangev[];
|
||||
int Resultvar;
|
||||
DESC Attdes;
|
||||
static int Tl_elm;
|
||||
static int Dom_num;
|
||||
extern char *Resrel;
|
||||
|
||||
struct tab
|
||||
{
|
||||
int t_opcode;
|
||||
char *t_string;
|
||||
};
|
||||
|
||||
static struct tab Uop_tab[] =
|
||||
{
|
||||
(int) opPLUS, "+ ",
|
||||
(int) opMINUS, "- ",
|
||||
(int) opNOT, "not[ERROR]",
|
||||
(int) opATAN, "atan",
|
||||
(int) opCOS, "cos",
|
||||
(int) opGAMMA, "gamma",
|
||||
(int) opLOG, "log",
|
||||
(int) opASCII, "ascii",
|
||||
(int) opSIN, "sin",
|
||||
(int) opSQRT, "sqrt",
|
||||
(int) opABS, "abs",
|
||||
(int) opEXP, "exp",
|
||||
(int) opINT1, "int1",
|
||||
(int) opINT2, "int2",
|
||||
(int) opINT4, "int4",
|
||||
(int) opFLT4, "float4",
|
||||
(int) opFLT8, "float8",
|
||||
};
|
||||
|
||||
static struct tab Bop_tab[] =
|
||||
{
|
||||
(int) opADD, "+",
|
||||
(int) opSUB, "-",
|
||||
(int) opMUL, "*",
|
||||
(int) opDIV, "/",
|
||||
(int) opPOW, "**",
|
||||
(int) opEQ, "=",
|
||||
(int) opNE, "!=",
|
||||
(int) opLT, "<",
|
||||
(int) opLE, "<=",
|
||||
(int) opGT, ">",
|
||||
(int) opGE, ">=",
|
||||
(int) opMOD, "%",
|
||||
};
|
||||
|
||||
static struct tab Cop_tab[] =
|
||||
{
|
||||
(int) opDBA, "dba",
|
||||
(int) opUSERCODE, "usercode",
|
||||
(int) opDATE, "date",
|
||||
(int) opTIME, "time",
|
||||
};
|
||||
|
||||
static struct tab Aop_tab[] =
|
||||
{
|
||||
(int) opCNT, "count",
|
||||
(int) opCNTU, "countu",
|
||||
(int) opSUM, "sum",
|
||||
(int) opSUMU, "sumu",
|
||||
(int) opAVG, "avg",
|
||||
(int) opAVGU, "avgu",
|
||||
(int) opMIN, "min",
|
||||
(int) opMAX, "max",
|
||||
(int) opANY, "any",
|
||||
};
|
||||
|
||||
/*
|
||||
** PR_TREE.C -- Query tree printing routines
|
||||
**
|
||||
** Defines:
|
||||
** pr_tree() -- print out query tree
|
||||
** pr_qual() -- print out qualofocation tree
|
||||
** pr_attname() -- print out attribute name of domain
|
||||
**
|
||||
**
|
||||
**
|
||||
** PR_TREE: tl_clause ROOT tl_clause
|
||||
**
|
||||
** prints out a tree assuming a mdVIEW-like mode
|
||||
*/
|
||||
pr_tree(root)
|
||||
QTREE *root;
|
||||
{
|
||||
|
||||
# ifdef xZTR1
|
||||
AAtTfp(10, -1, "PR_TREE: root 0%o Resultvar %d Resrel %s\n",
|
||||
root, Resultvar, Resrel);
|
||||
# endif
|
||||
|
||||
fprintf(Dbs_out, "%s ", pr_trim(resultres(), MAXNAME));
|
||||
|
||||
pr_dom_init();
|
||||
Tl_elm = 0;
|
||||
|
||||
/* print target list */
|
||||
fprintf(Dbs_out, "\n(\n");
|
||||
pr_tl_clause(root->left, TRUE);
|
||||
fprintf(Dbs_out, "\n)\n");
|
||||
|
||||
/* print qualification */
|
||||
if (root->right->sym.type != QLEND)
|
||||
{
|
||||
fprintf(Dbs_out, "where ");
|
||||
pr_qual(root->right);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** tl_clause: TREE
|
||||
** | tl_clause RESDOM expr
|
||||
**
|
||||
** target_flag = "in a target list (as opposed to in a by list)"
|
||||
*/
|
||||
pr_tl_clause(t_l, target_flag)
|
||||
QTREE *t_l;
|
||||
int target_flag;
|
||||
{
|
||||
register int fl;
|
||||
|
||||
fl = target_flag;
|
||||
|
||||
# ifdef xZTR1
|
||||
AAtTfp(10, 1, "tl_clause target %d Tl_elm %d\n", fl, Tl_elm);
|
||||
# endif
|
||||
|
||||
if (t_l->sym.type != TREE)
|
||||
{
|
||||
pr_tl_clause(t_l->left, fl);
|
||||
if (Tl_elm)
|
||||
{
|
||||
fprintf(Dbs_out, ", ");
|
||||
if (fl)
|
||||
putc('\n', Dbs_out);
|
||||
}
|
||||
/* print out info on result variable */
|
||||
pr_resdom(t_l, fl);
|
||||
pr_expr(t_l->right);
|
||||
Tl_elm++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** print out info on a result attribute.
|
||||
** this will be done only if the RESDOM node
|
||||
** is inside a target_list and if the Resultvar >= 0.
|
||||
** Resultvar == -1 inside a target list indicates that this is
|
||||
** a retrieve to terminal.
|
||||
*/
|
||||
pr_resdom(resdom, target_flag)
|
||||
QTREE *resdom;
|
||||
int target_flag;
|
||||
{
|
||||
|
||||
# ifdef xZTR1
|
||||
AAtTfp(10, 2, "PR_RESDOM: target_flag %d\n", target_flag);
|
||||
# endif
|
||||
|
||||
if (target_flag)
|
||||
{
|
||||
fprintf(Dbs_out, "\t");
|
||||
pr_attname(resultres(), ((RES_NODE *) resdom)->resno);
|
||||
fprintf(Dbs_out, " = ");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** give a relation name, and the attribute number of that
|
||||
** relation, looks in the attribute relation for the name of the
|
||||
** attribute.
|
||||
*/
|
||||
pr_attname(rel, attno)
|
||||
char *rel;
|
||||
short attno;
|
||||
{
|
||||
struct tup_id tid;
|
||||
struct attribute key;
|
||||
struct attribute tuple;
|
||||
register int i;
|
||||
|
||||
# ifdef xZTR1
|
||||
AAtTfp(10, 3, "PR_ATTNAME: rel %s attno %d\n", rel, attno);
|
||||
# endif
|
||||
|
||||
if (!attno)
|
||||
{
|
||||
fprintf(Dbs_out, "tid");
|
||||
return;
|
||||
}
|
||||
opencatalog(AA_ATT, 0);
|
||||
AAam_clearkeys(&Attdes);
|
||||
AAam_setkey(&Attdes, &key, rel, ATTRELID);
|
||||
AAam_setkey(&Attdes, &key, &attno, ATTID);
|
||||
i = AAgetequal(&Attdes, &key, &tuple, &tid);
|
||||
if (i)
|
||||
AAsyserr(11111, i, rel, attno);
|
||||
fprintf(Dbs_out, "%s", pr_trim(tuple.attname, MAXNAME));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** expr: VAR
|
||||
** | expr BOP expr
|
||||
** | expr UOP
|
||||
** | AOP AGHEAD qual
|
||||
** \
|
||||
** expr
|
||||
** | BYHEAD AGHEAD qual
|
||||
** / \
|
||||
** tl_clause AOP
|
||||
** \
|
||||
** expr
|
||||
** | INT
|
||||
** | FLOAT
|
||||
** | CHAR
|
||||
** | COP
|
||||
**
|
||||
*/
|
||||
pr_expr(ex)
|
||||
QTREE *ex;
|
||||
{
|
||||
register int op;
|
||||
register int tl_elm;
|
||||
register QTREE *e;
|
||||
|
||||
e = ex;
|
||||
switch (e->sym.type)
|
||||
{
|
||||
case VAR:
|
||||
pr_var(e);
|
||||
break;
|
||||
|
||||
case BOP:
|
||||
if (((OP_NODE *) e)->opno == (int) opCONCAT)
|
||||
{
|
||||
fprintf(Dbs_out, "AAconcat(");
|
||||
pr_expr(e->left);
|
||||
fprintf(Dbs_out, ", ");
|
||||
pr_expr(e->right);
|
||||
putc(')', Dbs_out);
|
||||
}
|
||||
else
|
||||
{
|
||||
putc('(', Dbs_out);
|
||||
pr_expr(e->left);
|
||||
pr_op(BOP, ((OP_NODE *) e)->opno);
|
||||
pr_expr(e->right);
|
||||
putc(')', Dbs_out);
|
||||
}
|
||||
break;
|
||||
|
||||
case UOP:
|
||||
if ((op = ((OP_NODE *) e)->opno) == ((int) opMINUS) || op == ((int) opPLUS) || op == ((int) opNOT))
|
||||
{
|
||||
pr_op(UOP, ((OP_NODE *) e)->opno);
|
||||
pr_expr(e->left);
|
||||
putc(')', Dbs_out);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* functional operators */
|
||||
pr_op(UOP, ((OP_NODE *) e)->opno);
|
||||
pr_expr(e->left);
|
||||
putc(')', Dbs_out);
|
||||
}
|
||||
break;
|
||||
|
||||
case AGHEAD:
|
||||
if (e->left->sym.type == AOP)
|
||||
{
|
||||
/* simple aggregate */
|
||||
pr_op(AOP, ((OP_NODE *) e->left)->opno);
|
||||
pr_expr(e->left->right);
|
||||
if (e->right->sym.type != QLEND)
|
||||
{
|
||||
fprintf(Dbs_out, "\where ");
|
||||
pr_qual(e->right);
|
||||
}
|
||||
putc(')', Dbs_out);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* aggregate function */
|
||||
pr_op(AOP, ((OP_NODE *) e->left->right)->opno);
|
||||
pr_expr(e->left->right->right);
|
||||
fprintf(Dbs_out, " by ");
|
||||
/* avoid counting target list elements
|
||||
* in determining wether to put out
|
||||
* commas after list's elements
|
||||
*/
|
||||
tl_elm = Tl_elm;
|
||||
Tl_elm = 0;
|
||||
pr_tl_clause(e->left->left, FALSE);
|
||||
Tl_elm = tl_elm;
|
||||
if (e->right->sym.type != QLEND)
|
||||
{
|
||||
fprintf(Dbs_out, "\n\t\twhere ");
|
||||
pr_qual(e->right);
|
||||
}
|
||||
putc(')', Dbs_out);
|
||||
}
|
||||
break;
|
||||
|
||||
case INT:
|
||||
case FLOAT:
|
||||
case CHAR:
|
||||
pr_const(e);
|
||||
break;
|
||||
|
||||
case COP:
|
||||
pr_op(COP, ((OP_NODE *) e)->opno);
|
||||
break;
|
||||
|
||||
default:
|
||||
AAsyserr(11112, e->sym.type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pr_const(ct)
|
||||
QTREE *ct;
|
||||
{
|
||||
register QTREE *c;
|
||||
register char *cp;
|
||||
register int i;
|
||||
char ch;
|
||||
double d;
|
||||
|
||||
c = ct;
|
||||
switch (c->sym.type)
|
||||
{
|
||||
case INT:
|
||||
if (c->sym.len == sizeof (char))
|
||||
fprintf(Dbs_out, "%d", ctoi(((I1TYPE *) c->sym.value)->i1type));
|
||||
else if (c->sym.len == sizeof (short))
|
||||
fprintf(Dbs_out, "%d", c->sym.value[0]);
|
||||
else /* i4 */
|
||||
fprintf(Dbs_out, "%d", ((I4TYPE *) c->sym.value)->i4type);
|
||||
break;
|
||||
|
||||
case FLOAT:
|
||||
# ifndef NO_F4
|
||||
if (c->sym.len == sizeof (float))
|
||||
d = ((F4TYPE *) c->sym.value)->f4type;
|
||||
else
|
||||
# endif
|
||||
d = ((F8TYPE *) c->sym.value)->f8type;
|
||||
fprintf(Dbs_out, "%-10.3f", d);
|
||||
break;
|
||||
|
||||
case CHAR:
|
||||
fprintf(Dbs_out, "\"");
|
||||
cp = (char *) c->sym.value;
|
||||
for (i = c->sym.len; i--; cp++)
|
||||
{
|
||||
if (any(*cp, "\"\\[]*?") == TRUE)
|
||||
putc('\\', Dbs_out);
|
||||
|
||||
if (*cp >= ' ')
|
||||
{
|
||||
putc(*cp, Dbs_out);
|
||||
continue;
|
||||
}
|
||||
/* perform pattern matching character replacement */
|
||||
switch (*cp)
|
||||
{
|
||||
case PAT_ANY:
|
||||
ch = '*';
|
||||
break;
|
||||
|
||||
case PAT_ONE:
|
||||
ch = '?';
|
||||
break;
|
||||
|
||||
case PAT_LBRAC:
|
||||
ch = '[';
|
||||
break;
|
||||
|
||||
case PAT_RBRAC:
|
||||
ch = ']';
|
||||
break;
|
||||
|
||||
default:
|
||||
ch = *cp;
|
||||
}
|
||||
putc(ch, Dbs_out);
|
||||
}
|
||||
putc('"', Dbs_out);
|
||||
break;
|
||||
|
||||
default:
|
||||
AAsyserr(11113, c->sym.type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** PR_OP: print out operator of a certain type
|
||||
*/
|
||||
pr_op(op_type, op_code)
|
||||
int op_type;
|
||||
int op_code;
|
||||
{
|
||||
register struct tab *s;
|
||||
register int opc;
|
||||
|
||||
opc = op_code;
|
||||
switch (op_type)
|
||||
{
|
||||
case UOP:
|
||||
s = &Uop_tab[opc];
|
||||
fprintf(Dbs_out, "%s(", s->t_string);
|
||||
break;
|
||||
|
||||
case BOP:
|
||||
s = &Bop_tab[opc];
|
||||
fprintf(Dbs_out, " %s ", s->t_string);
|
||||
break;
|
||||
|
||||
case AOP:
|
||||
s = &Aop_tab[opc];
|
||||
fprintf(Dbs_out, "%s(", s->t_string);
|
||||
break;
|
||||
|
||||
case COP:
|
||||
s = &Cop_tab[opc];
|
||||
fprintf(Dbs_out, "%s", s->t_string);
|
||||
break;
|
||||
}
|
||||
if (opc != s->t_opcode)
|
||||
AAsyserr(11114, op_type,
|
||||
s->t_opcode);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** print a VAR node: that is, a var.attno pair
|
||||
** at present the var part is the relation name over which var
|
||||
** ranges.
|
||||
*/
|
||||
pr_var(v)
|
||||
register QTREE *v;
|
||||
{
|
||||
register int i;
|
||||
|
||||
# ifdef xZTR1
|
||||
AAtTfp(10, 4, "pr_var(var=%d)\n", v);
|
||||
# endif
|
||||
|
||||
pr_rv(((VAR_NODE *) v)->varno);
|
||||
putc('.', Dbs_out);
|
||||
i = ((VAR_NODE *) v)->varno;
|
||||
pr_attname(Rangev[i].relid, ((VAR_NODE *) v)->attno);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** qual: QLEND
|
||||
** | q_clause AND qual
|
||||
**
|
||||
*/
|
||||
pr_qual(q)
|
||||
QTREE *q;
|
||||
{
|
||||
pr_q_clause(q->left);
|
||||
putc('\n', Dbs_out);
|
||||
if (q->right->sym.type != QLEND)
|
||||
{
|
||||
fprintf(Dbs_out, "and ");
|
||||
pr_qual(q->right);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** q_clause: q_clause OR q_clause
|
||||
** | expr
|
||||
*/
|
||||
pr_q_clause(qc)
|
||||
QTREE *qc;
|
||||
{
|
||||
register QTREE *q;
|
||||
|
||||
|
||||
q = qc;
|
||||
if (q->sym.type == OR)
|
||||
{
|
||||
pr_q_clause(q->left);
|
||||
fprintf(Dbs_out, " or ");
|
||||
pr_q_clause(q->right);
|
||||
}
|
||||
else
|
||||
pr_expr(q);
|
||||
}
|
||||
|
||||
|
||||
char *pr_trim(string, len)
|
||||
char *string;
|
||||
int len;
|
||||
{
|
||||
static char buf[30];
|
||||
register int l;
|
||||
register char *s;
|
||||
|
||||
s = string;
|
||||
l = len;
|
||||
AAbmove(s, buf, l);
|
||||
for (s = buf; l && *s != ' ' && *s; --l)
|
||||
s++;
|
||||
*s = '\0';
|
||||
return (buf);
|
||||
}
|
||||
|
||||
|
||||
pr_dom_init()
|
||||
{
|
||||
Dom_num = 0;
|
||||
}
|
||||
|
||||
|
||||
pr_ddom()
|
||||
{
|
||||
fprintf(Dbs_out, "d%d = ", Dom_num++);
|
||||
}
|
||||
|
||||
|
||||
pr_range()
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; i <= MAXVAR; i++)
|
||||
{
|
||||
if (Rangev[i].rused)
|
||||
{
|
||||
fprintf(Dbs_out, "range of ");
|
||||
pr_rv(i);
|
||||
fprintf(Dbs_out, " is %s\n",
|
||||
pr_trim(Rangev[i].relid, MAXNAME));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pr_rv(re)
|
||||
int re;
|
||||
{
|
||||
register int i;
|
||||
register int j;
|
||||
register int ch;
|
||||
|
||||
i = re;
|
||||
ch = Rangev[i].relid[0];
|
||||
|
||||
# ifdef xZTR1
|
||||
AAtTfp(10, 6, "pr_rv(%d) ch '%c'\n", i, ch);
|
||||
# endif
|
||||
|
||||
for (j = 0; j <= MAXVAR; j++)
|
||||
{
|
||||
if (!Rangev[j].rused)
|
||||
continue;
|
||||
if (ch == Rangev[j].relid[0])
|
||||
break;
|
||||
}
|
||||
if (j < i)
|
||||
fprintf(Dbs_out, "rv%d", i);
|
||||
else
|
||||
fprintf(Dbs_out, "%c", ch);
|
||||
}
|
||||
|
||||
|
||||
char *resultres()
|
||||
{
|
||||
# ifdef xZTR1
|
||||
AAtTfp(10, 5, "RESULTRES: Resultvar %d, Resrel %s\n", Resultvar, Resrel);
|
||||
# endif
|
||||
if (Resultvar > 0)
|
||||
return (Rangev[Resultvar].relid);
|
||||
if (!Resrel)
|
||||
AAsyserr(11115);
|
||||
|
||||
return (Resrel);
|
||||
}
|
||||
|
||||
|
||||
any(c, s)
|
||||
register int c;
|
||||
register char *s;
|
||||
{
|
||||
for ( ; *s; )
|
||||
if (*s++ == c)
|
||||
return (TRUE);
|
||||
|
||||
return (FALSE);
|
||||
}
|
||||
Loading…
Reference in New Issue