I.
Wprowadzenie do  języków zapytań (1)
II.
Wprowadzenie do  języków zapytań (2)
III.
Pojęcia obiektowości w bazach danych (1)
IV.
Pojęcia obiektowości w bazach danych (2)
V.
Podstawy semantyczne języków zapytań
VI.
Modele składu obiektów
VII.
Stos środowisk, rezultaty zapytań, funkcja nested
  Wstęp
  1. Stos środowisk
  2. Rezultaty zwracane przez zapytania
  3. Funkcja nested
  Podsumowanie
  Zadania
VIII.
Język SBQL (Stack-Based Query Language) (1)
IX.
X.
Dalsze własności SBQL
XI.
Operatory order by i group by
XII.
Przetwarzanie struktur nieregularnych
XIII.
Rozszerzenie języków zapytań o konstrukcje imperatywne
XIV.
Procedury, procedury funkcyjne, metody, reguły zakresu
XV.
Parametry procedur i metod, procedury rekurencyjne, optymalizacja poprzez modyfikację zapytań

 

2. Rezultaty zwracane przez zapytania

Jak dyskutowaliśmy przy okazji omawiania własności domkniętości, w naszym podejściu zapytania nigdy nie będą zwracać obiektów, lecz referencje do obiektów. Referencje do obiektów nie zamykają oczywiście kwestii rezultatów zwracanych przez zapytania, gdyż uwzględnimy także zapytania zwracające liczby, stringi, struktury, kolekcje itd. Istotną własnością naszego modelu rezultatów zapytań (nie spotykaną explicite w innych podejściach) jest to, że wyniki zapytań mogą być opatrzone nazwami. Wprawdzie fakt ten jest oczywisty wtedy, gdy zapytania zwracają struktury (w sensie języków C i C++), gdyż elementy tych struktur są nazwane, ale jest to raczej wyjątek. W naszym podejściu ten wyjątek podniesiemy do zasady: mianowicie oprócz referencji i wartości atomowych nasze zapytania mogą zwrócić omawiane wcześniej bindery.


Uogólnienie podanych wyżej założeń prowadzi do następującej rekurencyjnej definicji wprowadzonej uprzednio dziedziny Rezultat:

  • Każda atomowa wartość należąca do V (np. 3, "Kowalski", TRUE itd.) należy do dziedziny Rezultat.

  • Każda referencja do obiektu (inaczej identyfikator obiektu) dowolnego typu należąca do I należy do dziedziny Rezultat. W szczególności, do dziedziny Rezultat należą referencje do metod, procedur, funkcji, perspektyw itd.

  • Jeżeli x Î Rezultat, zaś n Î N jest dowolną nazwą, wówczas para n(x) należy do dziedziny Rezultat. Taki rezultat (będący nazwaną wartością) będziemy jak poprzednio nazywać binder.

  • Jeżeli x1, x2, x3, ... Î Rezultat, wówczas struct{ x1, x2, x3, ...} Î Rezultat. struct jest konstruktorem struktury, czyli pewnym dodatkowym atrybutem (flagą) rezultatu. Kolejność elementów w strukturze może mieć znaczenie. W odróżnieniu od znanych definicji struktur (rekordów itd.) nie wymagamy, aby xi były nazwanymi wartościami (binderami). Będziemy także uważać, że dla pojedynczego x Î Rezultat konstrukcja struct{x} jest równoważna x, zaś struct{} (konstruktor struct zastosowany do pustego zestawu elementów) jest konstrukcją niepoprawną. Powyższa konstrukcja uogólnia pojęcie krotki znane z modelu relacyjnego.

  • Jeżeli x1, x2, x3, ... Î Rezultat, wówczas bag{ x1, x2, x3, ...} Î Rezultat oraz sequence{ x1, x2, x3, ...} Î Rezultat. bag i sequence są konstruktorami kolekcji (flagami), na podobnej zasadzie jak konstruktor struct.

  • Zbiór Rezultat nie zawiera innych elementów.


Flagi struct, bag i sequence nie są konstruktorami typów, lecz konstruktorami wartości, czyli struktur danych zwracanych przez zapytania. W implementacji zestaw rezultatów { x1, x2, x3, ...} musi być opatrzony taką flagą, stając się w ten sposób strukturą, bagiem lub sekwencją. Ta unifikacja struktur, bagów i sekwencji ma istotne znaczenie z punktu widzenia zwartości definicji języka, jego elastyczności i łatwości implementacji. Flaga pociąga za sobą oczywiście różnicę w operatorach, które mogą działać na takim zestawie rezultatów.

Nazwy użyte w nazwanych wartościach nie muszą być nazwami obiektów ze składu. W szczególności, mogą to być dowolne nazwy użyte przez twórcę zapytania, np. nazwy występujące po słowie kluczowym as w OQL, nazwy "zmiennych" związanych kwantyfikatorami, nazwa "zmiennej" użytej w iteratorze for each itd. Jak wynika z podanej definicji, rezultaty mogą być dowolnie zagnieżdżane za pomocą binderów oraz konstruktorów struct, bag i sequence. Przykłady elementów zbioru Rezultat są następujące:

Atomowe:

P7.2.

25
"Kowalski"
i11

Złożone:

P7.3.

struct{i1, i56}
sequence{ i1, i6, i11}
bag{ struct{i1, i56}, struct{i6, i72}, struct{i11, i72}}
bag{struct{n("Kowalski"), Zarobek(2500), d(i56)}}
bag{struct{Dział(i56), Prac( bag{ struct{ n("Nowak"), s(i9) },
    struct{ n("Stec"), s(i14) }})}


Jak widać, za pomocą podanych konstruktorów można tworzyć byty przypominające obiekty. Nie są one jednak obiektami, ponieważ nie można im przypisać własnych identyfikatorów i nie można ich związać z istniejącą lub nową klasą. Oczywiście, jeżeli referencja w pewnym rezultacie zapytania jest identyfikatorem obiektu należącego do pewnej klasy, wówczas można użyć wszelkich własności tej klasy przy zachowaniu podanych dalej reguł. Używając terminologii ODMG, rezultaty zapytań są literałami. Takiej terminologii nie będziemy stosować, gdyż tego terminu użyjemy do innych celów, a ponadto nasza definicja jest bardziej ogólna i ma inny cel oraz intencję.

37
Rys.37. Rezultaty zapytań zapisane jako tablice

Niekiedy w przykładach będzie dla nas wygodnie posługiwać się tablicowym zapisem rezultatów zwracanych przez zapytanie. Sekwencje i bagi będziemy zapisywać jako tablice z elementami umieszczonymi od góry do dołu. Jeżeli wartości w krotkach tych tablic są nazwane tak samo, to nazwy te mogą być "wyciągnięte przed nawias" stając się nazwami kolumn. Rys.37 przedstawia rezultaty i odpowiadające im tablice.

Zwrócimy uwagę, że w definicji konstruktorów bagsequence nie wymagamy, aby wszystkie elementy należące do kolekcji posiadały ten sam typ. Jakkolwiek tak będzie najczęściej, rezerwujemy sobie możliwość bardziej luźnego typowania, m.in. w związku z danymi półstrukturalnymi. Przykładowo, jeżeli podobiekt zarobek jest opcyjny, wówczas możliwe jest utworzenie następującego bagu dwóch struktur:

P7.4.

bag{struct{ nazwisko("Abacki") zarobek(1900) }
struct{ nazwisko("Nowak")} }


Generalnie, nie tworzymy na tym etapie jakichkolwiek ograniczeń - kolekcja może zawierać dowolny heterogeniczny zestaw elementów.

Podane założenia dotyczące rezultatów zwracanych przez zapytania są niezależne od konkretnego języka zapytań. Mogą być w szczególności użyte do zdefiniowania języka SQL lub OQL. Dalej zastosujemy je dokładnie w przedstawionej wyżej formie do definicji języka SBQL.

Copyrights © 2006 PJWSTK
Materiały zostały opracowane w PJWSTK w projekcie współfinansowanym ze środków EFS.