/********************************************************************************* * * Testing the OQL optimizer * Copyright (c) 1999-2003 by Leonidas Fegaras, the University of Texas at * Arlington. All rights reserved. * Programmer: Leonidas Fegaras * Date: 1/10/99 * ********************************************************************************/ #include %module School; %define Instr64 as select * from Persons where name = "I64"; %define ECourses(s) as flatten( select e.teaches from e in Instructors where e.name = s ); %define EC(i,s) as flatten( select e.teaches from e in i where e.name = s ); %define factorial ( n: integer ) : integer as if n=0 then 1 else n*factorial(n-1); int MAIN ( int argc, char* argv[] ) { %initialize; /* initialize ODMG */ %begin; /* begin transaction */ // integers { %n := 2; n = n*2; %m := n*3+5; cout << "17 = " << m << endl; %fn := factorial(8); cout << "8! = " << fn << endl; }; // reals { %x := 5.6; %y := x*2; cout << "11.2 = " << y << endl; }; // strings { %s := "XX"; %r := s + "YY"; cout << "XXYY = " << r << "\n1 = "; %n := 'a nice string' like '%nice%str_ng'; cout << n << endl; }; // structures { %r := struct ( a: 1, b: "a" ); %s := struct ( x: struct( w: 1.7, a: r ), y: r ); cout << "1a1.7a = " << r.a << r.b << s.x.w << s.y.b << endl; }; // objects if (0) { %d := Department( name: "cse", dno: 1289 ); %e := Instructor( name: "Jones", ssn: 2345, salary: 8000, dept: d, degrees: set("a","b") ); cout << "Jones8000cse = " << e->name << e->salary; cout << Ref(e->dept)->name << endl << "abab = "; %for each v in e.degrees do cout << v; %n := e.degrees; %for each v in select * from n do cout << v; cout << endl; }; // constant sets, bags, and lists { %r := set(1,2,1); cout << "2 = " << r.cardinality() << endl << "123 = "; %for each x in list(1,2,3) do cout << x; cout << endl << "12 = "; %for each x in set(1,2,1) do cout << x; cout << endl; %s := set(set(1,2),set(2,1)); cout << "1 = " << s.cardinality() << endl << "11 = "; %for each v in set(set(1),set(1)) do cout << v.cardinality(); cout << endl << "1 = "; %x := set(1,1); %for each v in x do cout << v; cout << "\n3 = "; %w := element(set(3)); cout << w << endl << "3 = "; %n := list(list(1,2),list(3,4))[1][0]; cout << n << endl << "3 = "; %m := last(list(1,2,3)); cout << m << endl; }; // simple queries { int n = 0; cout << "query 1:\n"; %for each e in Persons do n++; cout << n << "\nquery 2:\n"; %for each v in select ssn, salary from Instructors where name = "I10" do cout << v.ssn << v.salary; cout << "\nquery 3:\n"; %for each v in select struct(x:ssn, y:salary) from Instructors where name = "I10" do cout << v.x << v.y; cout << "\nquery 4:\n"; %for each v in select * from Instructors where ssn>10 and ssn<12 do cout << v->ssn; cout << "\nquery 5:\n"; %for each v in select c.code from e in Instructors, c in e.teaches where e.name = "I51" do cout << v; cout << "\nquery 6:\n"; %for each v in select c from e in Instructors, c in e.degrees where e.name = "I51" do cout << v; cout << "\nquery 7:\n"; %for each v in select c.name from c in Courses, d in c.is_prerequisite_for where d.name = "Fundamentals9" do cout << v << " "; cout << "\nquery 8:\n"; %for each v in select x:c.name, y:d.name from Courses c, c.is_prerequisite_for d where d.code = "C9" do cout << v.x << v.y; cout << "\nquery 9:\n"; %for each v in select e from e in Instructors where e.ssn > 10 and e.ssn < 15 order by e.name do cout << v->name; cout << "\nquery 10:\n"; %u := (select e from e in Instructors order by e.name)[10]; cout << u->name << "\nquery 11:\n"; %i := count(Instructors); cout << i << "\nquery 12:\n"; %b := for all x in Instructors: x.salary >= 10000; cout << b << "\nquery 13:\n"; %c := exists x in Instructors: x.salary >= 50000; cout << c << "\nquery 14:\n"; %b := exists e in Instructors: for all c in e.teaches: e.ssn > 10 and c.name = "Fundamentals39"; cout << b << "\nquery 15:\n"; %k := element(select * from Instructors where ssn=78).teaches; cout << k.cardinality() << "\nquery 16:\n"; %for each v in select x: e.name from e in Instructors where e.name like "I1%8" do cout << v.x << " "; }; // materialization of path expressions { cout << "\nquery 17:\n"; %for each v in select e.dept.name from Instructors e where name = "I10" do cout << v << " "; cout << "\nquery 18:\n"; %s := select distinct e.dept.name from Instructors e where e.dept.head.name = "I79"; cout << s.cardinality() << "\nquery 19:\n"; %for each v in select x: e.name, y: e.dept.name from e in Instructors, s in e.dept.instructors, c in e.teaches where s.name = "I54" and c.name = "Fundamentals24" do cout << v.x << v.y << " "; }; // basic query unnesting { cout << "\nquery 20:\n"; %for each v in select e.ssn, e.salary from (select n from n in Instructors where n.name = "I10") as e do cout << v.ssn << v.salary; cout << "\nquery 21:\n"; %for each v in select e.ssn from e in Instructors where exists c in e.teaches: c.offered_by.name = e.dept.name and e.name = "I68" do cout << v; cout << "\nquery 22:\n"; %for each v in flatten(select e.teaches from e in Instructors where e.name = "I68") do cout << v->name; }; // more query unnesting { cout << "\nquery 23:\n"; %for each v in select count(c.has_prerequisites) from c in Courses where c.name = "Fundamentals39" do cout << v << " "; cout << "\nquery 24:\n"; %for each v in select x: e.name, y: (select c.name from c in e.teaches) from e in Instructors where e.ssn = 56 do cout << v.y.cardinality() << " "; cout << "\nquery 25:\n"; %for each v in select x: e.name, y: count(e.teaches) from e in Instructors where e.ssn = 56 do cout << v.y << " "; cout << "\nquery 26:\n"; %for each v in select x: e.name, y: count(e.dept.instructors) from e in Instructors where e.ssn = 50 do cout << v.x << v.y << " "; cout << "\nquery 27:\n"; %for each v in select x: e.name, y: (select x: c.name, y: count(c.has_prerequisites) from c in e.teaches) from e in Instructors where e.ssn = 56 do cout << v.y.cardinality() << " "; cout << "\nquery 28:\n"; %for each v in select distinct x: dn, y: count(partition) from e in Instructors group by dn: e.dept.dno having dn = 6 do cout << v.x << v.y << " "; cout << "\nquery 29:\n"; %for each v in select distinct x: dn, y: count(partition) from e in Instructors group by dn: e.rank do cout << v.x << v.y << " "; cout << "\nquery 30:\n"; %for each v in select distinct x: dn, z: count(partition) from e in Instructors group by dn: e.dept.name having dn = "D8" do cout << v.x << v.z << " "; cout << "\nquery 31:\n"; %for each v in select d.name, c: count(select * from e in d.instructors where e.rank = "professor") from d in Departments order by count(select * from e in d.instructors where e.rank = "professor") do cout << v.name << "/" << v.c << " "; cout << "\nquery 32:\n"; %for each v in select e.name, c: count(e.teaches) from e in Instructors where count(e.teaches) >= 3 do cout << v.name << "/" << v.c << " "; cout << "\nquery 33:\n"; %for each v in select x, y, c: count(c) from e in Instructors, c in e.teaches group by x: e.ssn, y: c.name having x > 60 and y > "Fundamentals39" do cout << v.x << v.y << v.c << " "; cout << "\nquery 34:\n"; %for each v in select distinct x: x, y: count(e) from e in Instructors group by x: count(e.teaches) having x>0 do cout << v.x << "/" << v.y << " "; cout << "\nquery 35:\n"; %for each v in select distinct x, y, c: count(e) from e in Instructors group by x: count(e.teaches), y: (exists c in e.teaches: c.name="Fundamentals39") having x>0 do cout << v.x << "-" << v.y << "/" << v.c << " "; cout << "\nquery 36:\n"; %for each v in select distinct x: x, y: count(e) from d in Departments, e in d.instructors where d.name = "D8" group by x: count(e.teaches) having x>0 do cout << v.x << "/" << v.y << " "; cout << "\nquery 37:\n"; %k := sum(select sum(select e.salary from e in d.instructors) from d in Departments); cout << k << "\nquery 38:\n"; %for each v in select e.name, X: (select x, count(*) from c in e.teaches group by x: count(c.has_prerequisites)) from d in Departments, e in d.instructors where d.name = "D8" do cout << v.name << v.X.cardinality() << " "; cout << "\nquery 39:\n"; %for each v in select e from e in Instructors where e.ssn > 30 and e.ssn < 78 and for all c in e.teaches: exists d in c.is_prerequisite_for: d.name = "Fundamentals12" do cout << v->name << " "; }; // miscellaneous { %abort; %begin; cout << "\nquery 40:\n"; %for each v in select * from x in Instructors where x.courses("D8") = 1 do cout << v->name; cout << "\nquery 41:\n"; %x := Instructors != Instructors; cout << x << "\nquery 42:\n"; %p := Instructors <= Instructors; cout << p << "\nquery 43:\n"; %m := max(select e.salary from e in Instructors); cout << m << "\nquery 44:\n"; %for each e in Instructors do %for each c in e.teaches do if (sm_string(c->name) == sm_string("Fundamentals39")) cout << sm_string(e->name) << " " << sm_string(c->name) << endl; cout << "query 45:\n"; %for each v in select name: c.name, prereq: p.name from c in Courses, p in c.all_prereqs() where c.name = "Fundamentals47" do cout << v.prereq << " "; cout << "\nquery 46\n"; %for each v in select name: e.name, courses: (select c.name from c in e.teaches) from e in Instructors where e.name = "I94" do cout << v.name << " " << v.courses.cardinality(); cout << "\nquery 47\n"; %n := 0; %for each v in select e from e in Instructors where e.ssn = 50 do { %v.name := "leo"; %v.teaches += persistent Course(name:"aa",code:"xx"); %n := n + 1; }; }; %abort; %begin; ifstream qf; qf.open("queries.txt"); char line[400]; for(int i=1; qf.good(); i++) { qf.getline(line,400); if (line[0]!='\0') { cout << "Interpreted Query " << i << ": " << line << endl; try { plan p = plan(line,0); p.print_value(p.evaluate(),2); cout << endl; } catch (odmg_error_class(m)) { cerr << m.message; }; }; }; %commit; %cleanup; };