1 / 161

Obiektowe języki zapytań

Obiektowe języki zapytań. Wykładowca : Kazimierz Subieta Polsko-Japońska Wyższa Szkoła Technik Komputerowych, Warszawa subieta@pjwstk.edu.pl Instytut Podstaw Informatyki PAN, Warszawa subieta@ipipan.waw.pl. Wykłady 6..10. Plan wykładów 6..10. SBQL - składnia SBQL - stos rezultatów

hester
Download Presentation

Obiektowe języki zapytań

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Obiektowe języki zapytań Wykładowca: Kazimierz Subieta Polsko-Japońska Wyższa Szkoła Technik Komputerowych, Warszawa subieta@pjwstk.edu.pl Instytut Podstaw Informatyki PAN, Warszawa subieta@ipipan.waw.pl Wykłady 6..10

  2. Plan wykładów 6..10 • SBQL - składnia • SBQL - stos rezultatów • SBQL - procedura eval, zapytania elementarne i operatory algebraiczne • SBQL - operatory nie-algebraiczne • Rozszerzenie SBQL dla modeli M1, M2 i M3 (klas i dziedziczenia, dynamicznych ról, list eksportowych) • Konstrukcje imperatywne bazujące na SBQL • Perspektywy bazujące na SBQL

  3. Wykład 6

  4. Język SBQL (Stack-Based Query Language)

  5. Generalne własności SBQL • Język SBQL jest sformalizowanym obiektowym językiem zapytań w stylu SQL lub OQL. Posiada semantyczne odpowiedniki podstawowych konstrukcji tych języków. Może być zdefiniowany (uściślony) dla wielu modeli składu, w szczególności dla modeli M0 - M3. • W odróżnieniu od relacyjnych i obiektowych algebr, rachunków, logik i innych tego rodzaju koncepcji, definicja SBQL bazuje na pojęciu stanu, którego składnikami są skład obiektów oraz stos środowisk. • SBQL będziemy uważać za wzorzec teoretyczny podobny do algebry relacji (stanowiącej podstawę wielu rozważań dotyczących modelu relacyjnego). SBQL jest jednak nieporównywalnie bardziej uniwersalny i konsekwentny niż dowolna tego rodzaju algebra, włączając tzw. algebry obiektowe. Będziemy starali się wykazać, że: • Języki zapytań mogą zawierać operatory nie-algebraiczne, których odwzorowanie w dowolną algebrę jest niemożliwe bez wprowadzenia poważnych ograniczeń koncepcyjnych.

  6. Składnia SBQL (1) • Przyjmiemy, że niektóre elementy wprowadzonego poprzednio zbioru V mają reprezentację „zewnętrzną”, która pozwala zapisać ten element w zapytaniu w postaci ciągu bajtów. • Wiele elementów zbioru V, takich jak grafika, skompilowane procedury, itd. nie posiada reprezentacji zewnętrznej. • Zwykle zewnętrzny reprezentant elementu zbioru V jest zwany w językach programowania literalem; nazwa ta została użyta w niewłaściwym znaczeniu w standardzie ODMG. • Niedobrym terminem jest stała, gdyż następuje tu kolizja znaczeniowa z niemodyfikowalnym elementem składu obiektów. • Wracamy do właściwych znaczeń terminów literal i stała. • Terminologię ODMG odrzucamy. • Zbiór literali będziemy oznaczać L. Będziemy zakładać, że istnieje prosta i jednoznaczna funkcja odwzorowująca element zbioru L w element zbioru V. • Identyfikatory należące do zbioru I nie mają odpowiadających im literali.

  7. Składnia SBQL (2) • Jedyną możliwością odwołania się do obiektów znajdujących się w składzie obiektów będzie użycie ich zewnętrznej nazwy należącej do zbioru N. Przyjmiemy, że każdy element zbioru N może być użyty w zapytaniu. • Dowolny literal jest zapytaniem; np. 2, 3.14, ”Kowalski” • Dowolny element zbioru N jest zapytaniem; np. Osoba, Student, zarobek, wiek. • Zapytania można łączyć w większe zapytania przy pomocy operatorów. • Wykorzystamy tu typowy zestaw operatorów występujących w znanych językach zapytań, np. w SQL. • Musimy przy tym rozróżniać leksykalną reprezentację operatora i sam operator, podobnie jak w przypadku rozróżnienia pomiędzy zbiorami L i V. Np. element leksykalny sum jest ciągiem trzech znaków, który oznacza sumującą funkcję zagregowaną. • Operatory będą podzielone na unarne i binarne, oraz algebraiczne i nie-algebraiczne.

  8. Składnia SBQL (3) • Jeżeli  jest oznaczeniem operatora algebraicznego unarnego, zaś q jest zapytaniem, wówczas ( q ) jest zapytaniem. • Przykładami operatorów algebraicznych unarnych są: count, sum, avg, log, -, sin, sqrt, not, itd. W niektórych sytuacjach, np. dla operatorów - oraz not, będziemy pomijać nawiasy, o ile nie doprowadzi to do niejednoznaczności. • Jeżeli  jest oznaczeniem operatora algebraicznego binarnego, zaś q1 i q2 są zapytaniami, wówczas q1 q2 jest zapytaniem. • Przykładami operatorów algebraicznych binarnych są: =, +, -, *, /, <. >, and, or, union, itd. Przecinek jest operatorem algebraicznym - konstruktorem struktur i kolekcji. • Jeżeli jest oznaczeniem operatora nie-algebraicznego, zaś q1 i q2 są zapytaniami, wówczas q1 q2 jest zapytaniem. • Przykładami operatorów nie-algebraicznych są: selekcja (where), projekcja lub nawigacja (.), zależne złączenie (), kwantyfikatory, itd. Dla kwantyfikatorów zastosujemy tradycyjną składnię q1( q2) oraz q1( q2); jest ona równoważna podanej wyżej uniwersalnej składni q1q2 i q1q2

  9. Składnia SBQL (4) • Jeżeli q jest zapytaniem, zaś nN, wówczas qasn jest zapytaniem. • Operator as jest unarnym operatorem algebraicznym parametryzowanym nazwą n. Operator ten będziemy wykorzystywać w większości sytuacji wymagających zdefiniowania pomocniczej nazwy. • Jeżeli q jest zapytaniem, zaś nN, wówczas qgroup asn jest zapytaniem. Operator group as jest podobny do as, o nieco innej semantyce. • Jeżeli q jest zapytaniem, to (q) jest zapytaniem. • Jeżeli nN jest nazwą procedury, funkcji, lub metody posiadającej k parametrów, zaś q1, q2, ... , qk są zapytaniami, wówczas n(q1; q2; ... , qk) jest zapytaniem. • Jeżeli nN jest nazwą procedury, funkcji, lub metody nie posiadającej parametrów, wówczas n() oraz n są zapytaniami. • Zapytania będą podlegać ograniczeniom typologicznym, które najczęściej będą tutaj zakładane implicite.

  10. Przykładowe zapytania 2000 "Kowalski" zarobek Osoba 2+2 zarobek > 2000 Osoba where (zarobek > 2000) (Osoba where (wiek() > 30)) . (zarobek + x + 2000/y) ((Osoba asp)  (p.pracuje_w.Działasd)) . (p.nazwisko, d.nazwa)  Osoba (wiek < 65) Działwhere ((zatrudnia.Osoba) asp (p.wiek() < 17)) (((Osoba asp)  (p.pracuje_w.Działasd)) where (p.Nazwisko = "Nowak" andd.Nazwa = "Kontrola")) . (p.nazwisko, d.nazwa)

  11. Podsumowanie składni SBQL LV jest zbiorem literali N jest zbiorem nazw operUna jest operatorem algebraicznym unarnym operBin jest operatorem algebraicznym binarnym operNieAlg jest operatorem nie-algebraicznym Możliwe są dalsze operatory nie-algebraiczne Meta-nawiasy {} oznaczają iterację od 0 zapytanie ::= L zapytanie ::= N zapytanie ::= operUnazapytanie zapytanie ::= operUna (zapytanie ) zapytanie ::= zapytanieoperBinzapytanie zapytanie ::= zapytanie operNieAlgzapytanie operNieAlg ::=where | .|  |  |  zapytanie ::= zapytanie ( zapytanie ) zapytanie ::=  zapytanie ( zapytanie ) zapytanie ::= zapytanie asN zapytanie ::= zapytanie groupasN zapytanie ::= ( zapytanie ) zapytanie ::= N ( ) zapytanie ::= N ( parametr {; parametr} ) parametr ::= zapytanie

  12. Drzewa syntaktyczne zapytań • Jest to struktura danych, która powstaje jako rezultat rozbioru gramatycznego zapytania. • Jest podstawą działania procedury eval wyznaczania rezultatu zapytania. • Może być przedtem poddane przekształceniom mającym na celu optymalizację zapytania. • Np. drzewo syntaktyczne zapytania: OsobawhereNazwisko = ”Nowak” Zapytanie Operator nie-algebraiczny where Zapytanie Zapytanie Nazwa Osoba Operator algebraiczny = Zapytanie Zapytanie Nazwa Nazwisko Reprezentant ”Nowak”

  13. Stos rezultatów zapytań (QRES) • Wszelkie pośrednie i końcowe rezultaty zapytań (wyrażeń) będą odkładane na stosie rezultatów QRES (Query REsult Stack). • Stos rezultatów jest uogólnieniem stosu arytmetycznego spotykanego w implementacji języków programowania. • Dość często osoby mało wyrobione w semantyce języków programowania plączą stos środowisk ze stosem rezultatów. Są to różne stosy, o odmiennej budowie, operacjach i przeznaczeniu. W SBA zajmujemy się obydwoma stosami. • Elementami stosu będą rezultaty zapytań (elementy zbioru Rezultat) zdefiniowane poprzednio; • Stos będzie przechowywał także wszelkie pomocnicze elementy niezbędne do obliczania zapytań; w szczególności, liczniki pętli iteracyjnych implikowanych przez operatory działające na kolekcjach. Elementy te nie będą uwzględniane w opisie formalnej semantyki. • Stos rezultatów jest strukturą danych przechowywaną w pamięci operacyjnej. Zmienia się w trakcie obliczeń.

  14. Przykład działania stosu rezultatów 3 4 - 5 5 8 8 2 1 2 2 2 2 2 4 pusty Wyrażenie Odwrotna notacja polska (2 *((5 + 3 ) / 4)) - 1 2 5 3 + 4 / * 1 - / + * 2 4 3

  15. Dlaczego wprowadzamy stos QRES? • QRES nie będzie przez nas uważany za składową pojęcia stanu. • Dla sformułowania semantyki stos QRES ma znaczenie drugorzędne. • W niektórych sformułowaniach tej semantyki (np. w semantyce denotacyjnej) QRES jest w ogóle zbędny. • Jest również zbędny, jeżeli semantykę zaimplementujemy poprzez zestaw rekurencyjnych procedur. • Stos QRES jest wygodny przy podejściu operacyjnym do semantyki. • Doświadczenie pokazuje, że inne podejścia (np. denotacyjne) są za trudne; • Stos ten uzupełnia koncepcję abstrakcyjnej implementacji, która jest zaletą podejścia stosowego. Dzięki temu nasze rozważania teoretyczne można dość łatwo zaimplementować; • Stos rezultatów jest skojarzony z jego statycznym odpowiednikiem funkcjonującym podczas statycznej analizy zapytania (kompilacji). Statyczny stos rezultatów jest niezbędnym elementem optymalizatora zapytań.

  16. Operatory działające na stosie QRES • Stos QRES jest abstrakcyjną strukturą danych obsługiwaną przez cztery operatory: • push (włóż nowy element na wierzchołek stosu), • pop (zdejmij jeden element z wierzchołka stosu), • top (odczytaj wierzchołek stosu), • empty (sprawdź czy stos jest pusty). • Operacje na stosie odbywają się zawsze na jego wierzchołku (uwzględniają jeden lub dwa wierzchołkowe elementy). • Pozostałe elementy stosu staną się widoczne dopiero wtedy, gdy zdejmiemy odpowiednią liczbę elementów z jego wierzchołka.

  17. Przykład zawartości stosu QRES wierzchołek stosu - jedyny widoczny element 15 i17 struct{ x(i61), y(i93) } bag{ struct{ n("Nowak"), s(i9)}, struct{ n("Stec"), s(i14)}, struct{ n("Mikuła" ), s(i18)}} niewidoczne elementy stosu dół stosu

  18. Ogólna architektura elementów semantyki Stos rezultatów QRES Stos środowisk ENVS Skład obiektów Obiekty trwałe Obiekty ulotne Operatory niealgebraiczne Ewaluacja zapytań referencje do obiektów referencje do obiektów

  19. Procedura ewaluacji zapytań eval (evaluation) • Semantyka SBQL będzie zdefiniowana poprzez procedurę eval. • Argumentem procedury eval jest dowolne zapytanie, zaś wynikiem procedury jest rezultat tego zapytania włożony na wierzchołek QRES. • Procedura eval jest realizacją omawianej wcześniej zasady modularności lub kompozycyjności języka. Jest rekurencyjna, wywołuje sama siebie dla podzapytań danego zapytania. • Procedura eval będzie korzystać ze składu obiektów, ENVS oraz QRES. Dla zapytań bez efektów ubocznych przyjmiemy następujące założenia: • Procedura eval nie zmienia stanu składu obiektów; • Procedura eval w trakcie ewaluacji zapytania q może zmieniać stan ENVS, ale po zakończeniu ewaluacji q stan ten będzie taki sam, jak na początku. • Procedura eval w trakcie ewaluacji zapytania q nie zmienia tej części QRES, którą zastała w momencie rozpoczęcia ewaluacji. • Semantyka będzie sterowana abstrakcyjną składnią. • Procedura eval jest wspomagana przez analizator gramatyczny (parser).

  20. Działanie procedury eval poprzedni stan QRES poprzedni stan QRES • Rezultaty zapytań zapisane na QRES są „konsumowane” przez operatory języka, dla których zapytania były parametrami. • Takim operatorem może być print lub operator SQL delete oznaczający usunięcie danych, np.: deleteOsobawhereNazwisko = ”Nowak”; • Wykonanie tego polecenia oznacza ewaluację przez procedurę eval zapytania OsobawhereNazwisko = ”Nowak” , w wyniku czego na wierzchołku QRES pojawi się referencja do obiektu Nowaka. • Ten rezultat zostanie „skonsumowany” przez operator delete, który następnie usunie go ze stosu QRES. • Po zakończeniu kompletu operacji QRES pozostanie taki sam, jak na początku. Na koniec wszystkich obliczeń QRES będzie pusty. rezultat zapytania q eval( q )

  21. Wynik procedury eval dla elementarnych zapytań • Jeżeli zapytanie jest literalem lL, to procedura eval wkłada odpowiadającą mu wartość atomową lV na wierzchołek QRES. • Jeżeli zapytanie jest nazwą nN, to procedura eval dokonuje wiązania tej nazwy na ENVS (funkcja bind), a następnie wynik tego wiązania wkłada na wierzchołek stosu QRES. procedureeval( q : zapytanie ) begin parse( q ); (* rozbiór gramatyczny *) caseq jest rozpoznane jako lL : push( QRES, l); caseq jest rozpoznane jako nN : push( QRES, bind( n ) ); case ..... ..... end;

  22. Operatory algebraiczne i nie-algebraiczne • Operatory łączące zapytania będziemy dzielić na algebraiczne i nie-algebraiczne. • Istotą podejścia stosowego są operatory nie-algebraiczne. • Fundamentalna różnica pomiędzy operatorami algebraicznymi i nie-algebraicznymi polega na ich stosunku do stosu środowisk ENVS. • Operatory algebraiczne nie używają ENVS: działanie takiego operatora dotyczy wyłącznie stosu QRES (z reguły jednego lub dwóch wierzchołkowych elementów). • Operatory nie-algebraiczne, oprócz działań na QRES, bezpośrednio odwołują się do konstrukcji i operacji zachodzących na ENVS.

  23. SBQL - operatory algebraiczne

  24. Operatory algebraiczne • Cechą dowolnej algebry jest m.in. to, że w wyrażeniu x1 x2 (gdzie  jest operatorem algebry) kolejność ewaluacji argumentów x1 oraz x2 tego operatora nie ma znaczenia. Jest to zasadnicza różnica w stosunku do operatorów nie-algebraicznych. • W matematycznym (denotacyjnym) sformułowaniu wynik zapytań( q1 ) oraz q1 q2 można zapisać jako: wynik( ( q1 ) ) =  ( wynik( q1 ) )  jest implementacją  wynik( q1q2 ) = wynik( q1) wynik( q2 ) • Funkcja wynik jest parametryzowana stanem, ale jej definicja nie odwołuje się do tego stanu bezpośrednio.

  25. Funkcja eval dla operatorów algebraicznych procedureeval( q : zapytanie ) begin ..... caseq jest rozpoznane jako ( q1 ) lub  q1: begin wynik_q1: Rezultat; (* lokalna zmienna typu Rezultat *) eval( q1 ); (* rezultat q1 na wierzchołku stosu QRES *) wynik_q1 :=top( QRES ); pop( QRES ); push( QRES, D ( wynik_q1 ); end; caseq jest rozpoznane jako q1 q2 : begin wynik_q1, wynik_q2: Rezultat; (* lokalne zmienne *) eval( q1); (* rezultat q1 na wierzchołku stosu QRES *) eval( q2 ); (* rezultat q2 na wierzchołku stosu QRES *) wynik_q2 :=top( QRES ); pop( QRES ); wynik_q1 := top( QRES ); pop( QRES ); push( QRES, wynik_q1 Dwynik_q2 ); end; case ..... ..... end;

  26. Rodzaje operatorów algebraicznych - ogólnie • Języki zapytań wprowadzają wiele operatorów algebraicznych. • Granica pomiędzy operatorami „wbudowanymi” w dany język, a operatorami „dobudowanymi” na wierzchołku języka jest rozmyta. • Liczba operatorów „wbudowanych” powinna być minimalna. Prawie wszystkie powinny wchodzić w skład bibliotek, które nie należą do definicji języka, ale raczej uzupełniają pewien jego aspekt lub dziedzinę zastosowań. • Może być duża liczba operatorów bibliotecznych przywiązanych do specyficznych dziedzin zastosowań, np. operatory obsługujące hurtownie danych, systemy geograficzne, systemy temporalne, systemy przestrzenne, systemy oparte o XML, systemy przetwarzania języka naturalnego, itd. • Nas będą interesować głównie operatory generyczne, niezależne od dziedziny zastosowań. • Nie będziemy jednak przesądzać, które operatory algebraiczne należą do SBQL, a które nie należą. Przyjmiemy, że do SBQL teoretycznie należy dowolny operator algebraiczny, który jest potrzebny i implementowalny. • Jeżeli zaimplementowano 100 operatorów algebraicznych, to implementacja 101-szego jest zazwyczaj bardzo prosta.

  27. Rodzaje operatorów algebraicznych (1) • Generyczny operator porównania na równość, oznaczany zwykle =, i operator odwrotny oznaczany  . Np. Nazwisko = ”Kowalski” , x = y , Zarobek 2000 , itd. Operatory te są zwykle zdefiniowane dla wszystkich typów wprowadzanych w danym języku. • Porównania i operatory dotyczące liczba całkowitych i rzeczywistych: <, , >, , +, - , *, /. Np. Zarobek < 3000 , 2+2 , -(głebokosc + x) , itd. • Funkcje liczbowe: część całkowita liczby, zaokrąglenie liczby, wartość bezwzględna liczby, sinus, kosinus, tangens, cotangens, logarytm dziesiętny, logarytm naturalny, funkcja wykładnicza, pierwiastek kwadratowy, itd.; Np. sqrt( x2 + y2) , sin(x+45) , itd; • Porównania, operatory i funkcje na stringach znaków: porównanie na porządek leksykograficzny stringów, zawieranie się stringów, obcięcie stringów, konkatenacja stringów, zamiana wszystkich liter na wersaliki i odwrotnie, określenie długości stringu, itd. • Porównanie, operatory i funkcje na datach i czasie godzinowym: porównanie dat, porównanie czasu, zmiana czasu na liczbę sekund, itd.

  28. Rodzaje operatorów algebraicznych (2) • Funkcje arytmetyczne zagregowane: sum (suma liczb), avg (średnia), min (liczba minimalna), max (liczba maksymalna), itd. Argumentem takiej funkcji jest kolekcja liczb, zaś wynikiem - pojedyncza liczba. W SQL funkcje te nie są ortogonalne (niezależne), gdyż są związane z operatorem group by. Jest to konsekwencja wadliwej koncepcji. W naszym ujęcie takie związanie jest zbędne. Przykłady: sum( Pracownik.zarobek ) , avg( bag(25, 43, 47, 11) ) . • Funkcja zliczająca liczbę elementów w kolekcji (w SQL - count), funkcja usuwająca duplikaty z kolekcji (w SQL - distinct), funkcja sprawdzająca, czy kolekcja nie jest pusta (w SQL - exists). W SQL funkcje te nie są składniowo ortogonalne. Będziemy tego unikać. Przykłady: count(Pracownik) , distinct(Pracownik.zawód) , exists(Pracownikwherezawód = ”analityk”) . • Funkcja dereferencji; zwykle występuje implicite. Jest wywoływana wtedy, gdy pewną referencję trzeba zamienić na wartość. Np. w zapytaniu PracownikwhereZarobek > 2000 nazwa Zarobek zwróci referencję do danej Zarobek. Funkcja dereferencji jest wymuszona przez operator >. Funkcję dereferencji będziemy oznaczać dereferencja i przyjmować, że dla wartości v nie będącej referencją zwróci v.

  29. Rodzaje operatorów algebraicznych (3) • Operatory działające na multizbiorach: suma, przecięcie, iloczyn kartezjański, różnica, równość, zawieranie się, itd. Przykłady: (Prac.Nazwisko)(Emeryt.Nazwisko) (Pracownik.Zawód) bag(”analityk”) • Analogiczne do powyższych, operatory na sekwencjach: konkatenacja sekwencji, obcięcie sekwencji poprzez usunięcie elementów z przodu lub z tyłu, porównanie sekwencji na równość, zawieranie się sekwencji, pobranie i-tego elementu sekwencji itd. • Operatory zmiany typu i/lub reprezentacji, czyli tzw. koercje: zmiana liczby rzeczywistej na string (i odwrotnie), zmiana liczby całkowitej na rzeczywistą (i odwrotnie), zmiana sekwencji na wielozbiór (i odwrotnie), itd. W zależności od liczby typów wprowadzonych do języka liczba tych operatorów może być znaczna. • Konstruktory wartość złożonych: zmiana wartości na strukturę z etykietowanymi polami, zmiana wartości na wielozbiór lub sekwencję, itd. • ...... itd.

  30. Konstruktor struktur • Składnia: ( q1, q2, q3,...) • gdzie q1, q2, q3,... są zapytaniami zwracającymi pojedyncze elementy - wartości atomowe, referencje lub bindery. • Jeżeli qi zwraca ri, to wyrażenie ( q1, q2, q3,...) zwraca struct{ r1, r2, r3,...} • Np.: (2, 3, 5) , (Nazwisko, Zar) , (Nazwiskoasn, (Zar+100) asz, "p" asr) • Konstruktor ten uogólnimy do specyficznego "iloczynu Kartezjańskiego": • Jeżeli dowolny argument konstruktora struktury jest wielozbiorem, to pozostałe też muszą być wielozbiorami. • Jeżeli wśród nich są pojedyncze elementy to automatycznie są one traktowane jako jedno-elementowe wielozbiory. • Np. jeżeli Prac zwraca bag{i1, i5, i9}, Dział zwraca bag{i17, i22}, to (Prac, Dział, 3) zwraca bag{ struct{i1, i17, 3}, struct{i5, i17, 3}, struct{i9, i17, 3}, struct{i1, i22, 3}, struct{i5, i22, 3}, struct{i9, i22, 3} } • Możliwe jest uogólnienie typu "outer join": jeżeli w (.., qi-1, qi, qi+1,..) qi zwraca pusty wynik, to zapytanie jest równoważne (..., qi-1, qi+1,...) .

  31. Konstruktor wielozbiorów • Składnia: bag( q1, q2, q3,...) • gdzie q1, q2, q3,... są zapytaniami zwracającymi pojedyncze elementy - wartości atomowe, referencje lub bindery. • Jeżeli qi zwraca ri, to wyrażenie bag( q1, q2, q3,...) zwraca bag{ r1, r2, r3,...} • Np.: bag(2, 3, 5) , bag(Nazwisko, Nazwa) , bag("x" asr, "y" asr, "z" as r) • Konstruktor ten uogólnimy dla argumentów będących wielozbiorami: • Jeżeli wśród argumentów konstruktora są pojedyncze elementy to automatycznie są one traktowane jako jedno-elementowe wielozbiory. • Np. jeżeli zapytanie Lokacja zwraca bag{ "Kielce", "Krosno" }, to zapytanie bag(Lokacja, "Radom", "Płock" ) zwraca bag{"Kielce", "Krosno", "Radom", "Płock" } • W innej terminologii konstruktor bag jest sumą wielozbiorów: bag( q1, q2, q3,...) jest równoważne q1 union q2 union q3 union ... • przy czym jeżeli qi zwraca element ri , to jest on traktowany jak bag{ri}.

  32. Operator definiowania pomocniczej nazwy • Wiele zapytań wymaga zdefiniowania pomocniczych nazw. • Są one istotnym środkiem konceptualizacji zapytań lub programów. • Zwiększają moc języka: bez nich niektóre zapytania nie dadzą się wyrazić. • Występują również jako "zmienne związane kwantyfikatorami", lub "jako zmienne iteracyjne" w konstrukcjach for each ... do ... • W SBA występują również jako etykiety struktur. • SBQL, podobnie jak SQL, i w odróżnieniu od OQL, nie zmusza do używania pomocniczych nazw. • Generalnie, inne podejścia nie radzą sobie z tym pojęciem, w związku z tym rozwiązania są niespójne. • W SBA i SBQL semantyka pomocniczych nazw jest potraktowana ogólnie i precyzyjnie, dzięki temu że: • Każda nazwa występująca w zapytaniu lub programie podlega tym samym regułom zakresu i wiązania, które zostały zrealizowane w postaci mechanizmu stosu środowisk. Dotyczy to także wszelkich pomocniczych nazw definiowanych wewnątrz zapytań.

  33. Definicja nazwy jako operator algebraiczny • Operator definiowania pomocniczej nazwy as jest unarnym operatorem algebraicznym parametryzowanym nazwą. • Niech q będzie zapytaniem, które zwraca kolekcję bag{x1, x2, x3, ...}. Wówczas zapytanie qasn zwróci kolekcję binderów bag{ n(x1), n(x2), n(x3), ...}. • Operator as etykietuje określoną nazwą każdą wartość zwróconą przez zapytanie będące jego argumentem. • Operator ten nie zmienia charakteru kolekcji: w szczególności, jeżeli q zwraca sequence{x1, x2,...}, to qasn zwraca sequence{ n(x1), n(x2),...}. • Operator as może być zagnieżdżany: np. jeżeli q zwraca bag{x1, x2, x3, ...}, to (qasn1) asn2 zwraca bag{ n2( n1(x1) ), n2( n1(x2) ), n2( n1(x3) ), ...} • Powyższa definicja wydaje się banalna, ale okazuje się uniwersalna i precyzyjna, zwiększająca znacznie potencjał dla optymalizacji zapytań.

  34. Przykład działania operatora as Zapytanie Wynik Prac Prac as p i1 i6 i11 p( i1 ) p( i6 ) p( i11 )

  35. Zastosowania operatora as • „Zmienne” (krotkowe, dziedzinowe, itd.) definiowane w ramach klauzulami from w językach takich jak SQL i OQL; np. Pracasp. • Pokażemy, że operator zależnego złączenia znany z OQL i SQL3 jest ortogonalny w stosunku do operatora as, wobec czego nie zachodzi potrzeba definiowania go w tym szczególnym kontekście; • Zmienna związana kwantyfikatorem, np. Pracasp (p.Zar > 10000); • Etykiety składników struktur zwracanych przez zapytanie, np. Prac.( Nazwiskoasn, Zarasz ) ; • Kursor w zdaniu for each; np. for eachPracaspdop.Zar := p.Zar +100; • Definicja nowych nazw atrybutów dla wirtualnej perspektywy (view); np: create viewBogatyProjektant { return (PracwhereStan = ”projektant” andZar > 10000). (NazwiskoasN, PracujeWasNrD) };

  36. Operator group as Zapytanie Prac Prac groupas p p( bag{ i1, i6, i11 } ) Wynik bag{ i1, i6, i11 } • Podobny do operatora as. • Jeżeli q zwraca pewną wartość r (w szczególności, kolekcję), to qgroup asn zwraca pojedynczy binder n( r ). • W odróżnieniu od operatora as, operator group as przypisuje nazwę n do rezultatu całości zapytania, a nie do poszczególnych elementów kolekcji zwracanej przez to zapytanie. • Operator group as powstał w wyniku prób sformalizowania mętnej semantycznie klauzuli group by języka OQL. • Głównym motywem była "ortogonalizacja" tej klauzuli. I to się udało.

  37. Wykład 7

  38. SBQL - operatory nie-algebraiczne

  39. Dlaczego "nie-algebraiczne"? (1) • Do nich należą operator where, operator kropki, kwantyfikatory, zależne złączenie, sortowanie (order by), i inne. Wszystkie są binarne. • Mimo podobieństwa do operatorów algebraicznych, semantyka operatorów nie-algebraicznych nie da się prosto sprowadzić do algebry. • To zdanie może wydawać się niejasne. W modelu relacyjnym operatory selekcji (operator where), projekcji (operator kropki) oraz złączenia są przecież traktowane jako operatory algebraiczne algebry relacji. • Tu właśnie jest nieporozumienie. Takie traktowanie jest możliwe wyłącznie przy ograniczonej funkcjonalności, oraz po przyjęciu triku formalnego. • Trik polega na tym, że część semantyki jest przenoszona na poziom metajęzykowy. Operatory te są dodatkowo kwalifikowane wyrażeniem metajęzykowym. Np. w wyrażeniu algebry relacyjnej: Zar>1000( Prac ) operator selekcji  jest kwalifikowany wyrażeniem metajęzykowym Zar >1000. Operator selekcji nie jest pojedynczym operatorem, lecz nieskończoną rodziną zawierającą tyle operatorów, ile jest warunków selekcji.

  40. Dlaczego "nie-algebraiczne"? (2) • Powyższy trik można uważać za uzasadniony w przypadku, gdy wyrażenie metajęzykowe parametryzujące operator jest proste, a jego semantyka jest oczywista. Nie zawsze to jest prawda. Operator selekcji może mieć bardziej złożony warunek selekcji, np. ZarobekNetto( Zar + 100 )>1000( Prac ) • Warunek selekcji zawiera operator + oraz wywołuje pewną funkcję ZarobekNetto. Wyrażenie metajęzykowe posiada nietrywialną wewnętrzną semantykę, która jest nieformalna. • Jeżeli jakikolwiek składnik języka nie ma formalnej semantyki, to cały język również nie ma formalnej semantyki. • Mimo podobieństwa wizualnego, w powyższych wyrażeniach nazwy Prac oraz Zar są ulokowane w dwóch różnych światach. • Pierwsza nazwa należy do języka algebry relacji, jest „pierwszej kategorii”, podlega formalnemu traktowaniu. • Natomiast druga nazwa należy do metajęzyka algebry relacji, jest „drugiej kategorii”, nie podlega formalnemu traktowaniu.

  41. Dlaczego "nie-algebraiczne"? (3) • W ten sposób złamana została zasada relatywizmu, zgodnie z którą nazwy nie mogą posiadać fundamentalnie różnej semantyki w zależności od tego, jakiego rodzaju dane oznaczają. • Ta zasada staje się szczególnie istotna dla języków obiektowych, gdyż obiekty mogą mieć strukturę hierarchiczną, zaś nazwy mogą oznaczać dane na dowolnym poziomie hierarchii obiektów. • Podobny problem dotyczy operatorów. Operator selekcji  jest elementem języka tej algebry, należy do „pierwszej kategorii”, podczas gdy operator < występuje w metajęzyku, jest „drugiej kategorii”. • Powyższa językowo-meta-językowa schizofrenia podważa poprawność definicji semantyki. • Podane argumenty są wystarczające aby twierdzić, że tzw.algebry obiektowe są pseudo-matematyczną bzdurą (włączając algebry dla XML). • Paradoksalnie, są one motywowane koniecznością zbudowania „solidnych podstaw matematycznych” obiektowych języków zapytań.

  42. Dlaczego "nie-algebraiczne"? (4) • W podejściu stosowym dowolne operatory nie są indeksowane wyrażeniami meta-językowymi. • Nie występuje więc semantyczna schizofrenia nazw dzieląca je na „językowe” i „meta-językowe”. • Nie ma podziału na nazwy „pierwszej kategorii” i „drugiej kategorii”. Każda nazwa ma dokładnie taką samą semantykę i podlega dokładnie tym samym regułom wiązania i zakresu • Podobnie z operatorami: nie występuje semantyczne zróżnicowanie operatorów: operator < występuje na tym samym poziomie semantycznym jak operator selekcji where. • Koncepcja operatorów nie-algebraicznych jest bardzo prosta oraz ma dobrze ugruntowane korzenie w semantyce języków programowania. • Definicja operatorów nie-algebraicznych będzie się nieco różniła w zależności od tego, który modelu składu (M0 - M3) będzie rozpatrywany. Wszystkie te definicje będą bazowały na podanej niżej podstawowej definicji dla modelu M0.

  43. Opis procedury eval dla operatora nie-algebr.  • Aby dokonać ewaluacji zapytania q1 q2 wykonaj następujące czynności: • Dokonaj ewaluacji zapytania q1. Zapytanie to zwraca wielozbiór elementów. • Dla każdego elementu e należącego do wyniku q1 wykonaj następujące czynności: • Oblicz wartość funkcji nested( e ). Wynik jest zbiorem binderów. • Włóż obliczony zbiór binderów jako nową sekcje na wierzchołek stosu ENVS. • Dokonaj ewaluacji zapytania q2 w tym nowym środowisku. • Oblicz wynik cząstkowy dla danego elementu e poprzez połączenie e z wynikiem zwróconym przez q2. Funkcja łącząca zależy od operatora . • Usuń nowo wstawioną górną sekcję ze stosu ENVS. • Zsumuj wszystkie wyniki cząstkowe w wynik końcowy. Sposób sumowania sumuj ( U ) zależy od rodzaju operatora . • Stan stosu środowisk ENVS po zakończeniu ewaluacji jest taki sam, jak przez rozpoczęciem ewaluacji.

  44. Formalny zapis procedury eval dla oper. niealgebr. procedureeval( q : zapytanie ) begin ...... caseq jest rozpoznane jako q1 q2 : (* q1 , q2 są zapytaniami,  jest operatorem nie-algebraicznym *) begin wyniki_pośr: bag ofRezultat; (* lokalna kolekcja wyników pośrednich *) wynik_pośredni: Rezultat; (* lokalna zmienna na wynik pośredni *) wynik_końcowy: Rezultat; (* lokalna zmienna na wynik końcowy *) e: Rezultat; (* lokalna zmienna na element kolekcji zwracanej przez q1 *) wyniki_pośr := ; (* zerowanie kolekcji wyników pośrednich *) eval( q1); (*q1 zwraca kolekcję elementów; wynik q1na czubku stosu QRES *) for eachein top( QRES ) do (* iteracja po wszystkich elementach wyniku q1 *) begin push( ENVS, nested( e ) ); (* nowa sekcja na stosie środowisk *) eval( q2 ); (* wynik q2 na czubku stosu QRES *) wynik_pośredni := połącz( e, top( QRES ) ); (* połączenie e z wynikiem q2; zależne od  *) wyniki_pośr := wyniki_pośr U { wynik_pośredni }; (* akumulacja wyniku pośredniego *) pop( QRES ); (* usuniecie z QRES wyniku q2 *) pop( ENVS ); (* usuniecie z ENVS nowej sekcji *) end; wynik_końcowy := sumuj( wyniki_pośr ); (* zsumowanie wyników pośrednich; zależne od  *) pop( QRES ); (* usuniecie z QRES wyniku q1 *) push( QRES, wynik_końcowy ); (* włożenie na QRES końcowego wyniku *) end; ....... end;

  45. Poglądowy obraz małej bazy danych i1Prac i5Prac i9Prac i2 Nazwisko ”Nowak” i6 Nazwisko ”Kowalski” i10 Nazwisko ”Barski” i3 Zar 2500 i7 Zar 2000 i11 Zar 900 i4 PracujeW i12 Adres i8 PracujeW i13 Miasto ”Radom” i14 Ulica ”Wolska” i15 NrDomu 12 i16 PracujeW i17Dział i22Dział i18 Nazwa ”Produkcja” i23 Nazwa ”Sprzedaż” i19 Lokacja ”Kielce” i24 Lokacja ”Radom” i25 Zatrudnia i20 Lokacja ”Kraków” i26 Zatrudnia i21 Zatrudnia

  46. Operatorwhere (selekcja) • Składnia: q1whereq2 • Ograniczenie: podzapytanie q2 zwraca wartość prawda lub fałsz. • Semantyka • Dla każdego elementu e zwróconego przez q1, ENVS jest podwyższany o nested(e) • Następnie ewaluowane jest q2 • Po ewaluacji q2 stos ENVS wraca do poprzedniego stanu • e należy do ostatecznego wyniku wyłącznie wtedy, gdy q2 zwróciło prawda. • Objaśnienie funkcji eval • Funkcja połącz: dla danego e należącego do wyniku q1zwraca jednoelementowy wielozbiór { e } w przypadku, gdy dla tego e podzapytanie q2 zwróciło prawda, lub pusty wielozbiór { }, jeżeli podzapytanie q2 zwróciło fałsz. • Funkcja sumuj: sumuje (mnogościowo) wszystkie wyniki pośrednie. • Przykład: Pracwhere ( Zar > 1000 )

  47. Operatorwhere - ilustracja działania 1000 prawda i3 2500 prawda i7 2000 1000 i11 900 1000 fałsz Nazwisko(i6) Zar(i7) PracujeW(i8) Nazwisko(i10) Zar(i11) Adres(i12) PracujeW(i16) Nazwisko(i2) Zar(i3) PracujeW(i4) Prac(i1) Prac(i5) Prac(i9) Dział(i17) Dział(i22) Prac(i1) Prac(i5) Prac(i9) Dział(i17) Dział(i22) Prac(i1) Prac(i5) Prac(i9) Dział(i17) Dział(i22) Rezultat zwracany przez zapytanie Prac (wiązanie Prac) Iteracja po elementach e poprzedniego rezultatu: na ENVS wkłada się nested(e) Rezultat zwracany przez zapytanie Zar (wiązanie Zar) Rezultat dereferencji wymuszanej przez operator > Rezultat zwracany przez zapytanie 1000 Rezultat zwracany przez zapytanie Zar>1000 Końcowy rezultat zapytania i1 i5 i9 i1 i5 Stan stosu ENVS przed ewaluacją Prac(i1) Prac(i5) Prac(i9) Dział(i17) Dział(i22) Prac where ( Zar > 1000 )

  48. Operator kropki (projekcja, nawigacja) • Składnia: q1. q2 • Semantyka • Dla każdego elementu e zwróconego przez q1, ENVS jest podwyższany o nested(e) • Następnie ewaluowane jest q2 • Po ewaluacji q2 stos ENVS wraca do poprzedniego stanu • Ostateczny wynik jest sumą mnogościową wyników q2 • Objaśnienie funkcji eval • Funkcja połącz: ignoruje e; zwraca wynik podzapytania q2. • Funkcja sumuj: sumuje (mnogościowo) wszystkie wyniki pośrednie. • Przykład: Prac .Zar • Operator kropki przykrywa tzw. wyrażenia ścieżkowe (path expressions) w najbardziej uniwersalnej postaci, pozwalając je jednocześnie dowolnie kombinować z innymi operatorami.

  49. Operator kropki - ilustracja działania i3 i7 i11 Nazwisko(i6) Zar(i7) PracujeW(i8) Nazwisko(i2) Zar(i3) PracujeW(i4) Nazwisko(i10) Zar(i11) Adres(i12) PracujeW(i16) Prac(i1) Prac(i5) Prac(i9) Dział(i17) Dział(i22) Prac(i1) Prac(i5) Prac(i9) Dział(i17) Dział(i22) Prac(i1) Prac(i5) Prac(i9) Dział(i17) Dział(i22) Rezultat zwracany przez zapytanie Prac (wiązanie Prac) Iteracja po elementach e poprzedniego rezultatu: na ENVS wkłada się nested(e) Rezultat zwracany przez zapytanie Zar (wiązanie Zar) Końcowy rezultat zapytania i1 i5 i9 i3 i7 i11 Stan stosu ENVS przed ewaluacją Prac(i1) Prac(i5) Prac(i9) Dział(i17) Dział(i22) Prac . Zar

  50. Operator zależnego złączenia • Składnia: q1q2 • Semantyka • Dla każdego e zwróconego przez q1, ENVS jest podwyższany o nested(e) • Następnie ewaluowane jest q2 • Po ewaluacji q2 stos ENVS wraca do poprzedniego stanu • Ostateczny wynik jest sumą mnogościową wszystkich struktur, w których na początku jest e, zaś dalej jest element wyniku q2 zwrócony dla tego e. • Objaśnienie funkcji eval • Funkcja połącz: zarówno e jak i każdy element e2 zwracany przez q2 traktuje jako struktury (jednoelementowe lub wieloelementowe). Dla każdego e2 zwracanego przez q2 tworzy strukturę poprzez połączenie e oraz e2. Wynikiem pośrednim jest kolekcja wszystkich takich struktur. • Funkcja sumuj: sumuje (mnogościowo) wszystkie wyniki pośrednie. • Przykład: Prac Zar • Zależne złączenie jest zdefiniowane w ODMG OQL (klauzula from) w znacznie ograniczonej postaci w stosunku do powyższej definicji.

More Related