Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Przetwarzanie symbolu _

Indeks [_] jest cukrem syntaktycznym powielającym wyrażenie pola. Jedno wyrażenie zapisane w SELECT rozwija się podczas kompilacji do wielu pól wynikowych, po jednym dla każdego zgodnego slotu wskazanych strumieni.

Liczba kopii nie wynika wyłącznie z własnego schematu strumienia. x[_] oznacza wszystkie sloty, które x wnosi do rekordu czytanego przez dane zapytanie z całej klauzuli FROM. Ma to znaczenie, gdy operator strumieniowy zmienia szerokość schematu, na przykład tworząc okno.

Przykład używa kanonicznych deklaracji z całego rozdziału — core0 ma dwa pola (BYTE, INTEGER), core1 ma dwa pola (INTEGER, FLOAT), schematy są równoliczne:

DECLARE a BYTE, b INTEGER   STREAM core0, 0.1 FILE ‘sensor_a.txt’
DECLARE c INTEGER, d FLOAT  STREAM core1, 0.2 FILE ‘sensor_b.txt’

SELECT core0[_] * core1[_] \
STREAM scaled \
FROM core0 + core1

Po przeprowadzeniu kompilacji:

$ xretractor -c query.rql
core0(1/10)	sensor_a.txt
	a: BYTE
	b: INTEGER
core1(1/5)	sensor_b.txt
	c: INTEGER
	d: FLOAT
scaled(1/10)	tail=1
	:- PUSH_STREAM(core0)
	:- PUSH_STREAM(core1)
	:- STREAM_ADD
	scaled_0: INTEGER
		PUSH_ID(scaled[0])
		PUSH_ID(scaled[2])
		MULTIPLY
	scaled_1: FLOAT
		PUSH_ID(scaled[1])
		PUSH_ID(scaled[3])
		MULTIPLY

Symbol _ rozwinął się w dwa pola: scaled[0] * scaled[2] (czyli a * c) i scaled[1] * scaled[3] (czyli b * d). Odwołania do core0 i core1 zostały przetłumaczone przez aliasowanie na absolutne pozycje w schemacie złączonym. Typy wynikowe to INTEGER (BYTE * INTEGER) i FLOAT (INTEGER * FLOAT) — wynik równania typów w górę, opisanego w osobnym podrozdziale.

Szerokość liczona w klauzuli FROM

Jednopolowy strumień src wnosi pięć slotów, gdy w FROM znajduje się jego okno src@(1,5). Dzięki temu splot FIR można zapisać bez osobnego, nazwanego strumienia okna:

DECLARE value INTEGER STREAM src, 1/500 FILE 'data.txt'
DECLARE coef INTEGER[5] STREAM filter, 1 FILE 'coef.txt'

SELECT src[_] * filter[_] STREAM products FROM src@(1,5)+filter
SELECT products[0] STREAM output FROM SUMC(products)

Pierwsze zapytanie rozwija się do pięciu iloczynów. Jest równoważne dłuższej postaci:

SELECT * STREAM window FROM src@(1,5)
SELECT window[_] * filter[_] STREAM products FROM window+filter
SELECT products[0] STREAM output FROM SUMC(products)

W krótszej postaci kompilator sam wydziela okno z FROM jako substrat. Taki substrat jest przezroczysty podczas ustalania szerokości wkładu src. Nazwany przez użytkownika strumień window stanowi natomiast granicę schematu, dlatego dłuższa postać odwołuje się do window[_], a nie do src[_].

Operator stojący w FROM może także zmniejszyć szerokość. Reduktor zwija okno do jednego slotu, więc poniższe src[_] rozwija się tylko raz:

SELECT src[_] STREAM total FROM SUMC(src@(1,5))

Jeżeli jedno wyrażenie zawiera kilka indeksów [_], kompilator tworzy tyle kopii, ile wynosi najmniejsza z ustalonych szerokości ich wkładów. W typowym splocie okno i strumień współczynników mają tę samą szerokość.

Kompilator odrzuca odwołanie, gdy wskazany strumień nie występuje w FROM albo jego pola nie tworzą tam spójnego bloku. Przykładem drugiego przypadku jest src[_] pod oknem zbudowanym nad konkatenacją (src+other)@(1,5): pola obu źródeł są powtarzane wspólnie i nie da się przypisać src jednej szerokości bez zgadywania. Należy wtedy nadać podwyrażeniu własną nazwę i użyć [_] na tym nazwanym wyniku.

Symbol _ a przeplot

Aliasowanie składowych przez A[_] jest poprawne dla sumy +, ponieważ suma zachowuje osobne fragmenty schematów obu argumentów. Nie wolno stosować tej postaci do składowej osiąganej przez przeplot #:

SELECT A[_] - B[_] STREAM roznica FROM A#B

Po przeplocie pozycje A[k] i B[k] są tą samą pozycją wspólnego schematu, więc powyższe wyrażenie nie identyfikuje dwóch różnych wartości. Kompilator kończy taki plan błędem zamiast po cichu obliczyć wynik[k]-wynik[k].

Jeżeli _ ma przetwarzać rekord przeplotu, należy najpierw nadać wynikowi nazwę, a potem odwołać się do tego wyniku:

SELECT * STREAM przeplot FROM A#B
SELECT przeplot[_] * 2 STREAM przeskalowany FROM przeplot

Odzyskanie konkretnej składowej wymaga operatora rozplotu & albo %.

Ta funkcjonalność ma główne zastosowanie w algorytmach filtrów sygnałowych, w których wykonuje się wiele takich samych operacji na odpowiadających sobie elementach okna i wektora współczynników. Nie jest konieczna do osiągnięcia pełnej funkcjonalności RetractorDB, ale znacząco skraca takie zapytania. Kompletny przykład przedstawia rozdział Implementacja filtru sygnałowego.