ˇ – Technicka´ univerzita Ostrava VSB Fakulta elektrotechniky a informatiky Katedra informatiky
XQuery algebra XQuery Algebra
2012
´s Bc. Petr Lukaˇ
Chtˇel bych podˇekovat sv´emu vedouc´ımu diplomov´e pr´ace, panu Ing. Radimu Baˇcovi, Ph.D za poskytnut´ı velmi zaj´ımav´eho t´ematu a za prubˇ ˚ ezˇ nou ochotnou odbornou pomoc.
Abstrakt Tato diplomov´a pr´ace se zabyv´ ´ a n´avrhem a implementac´ı procesoru dotazovac´ıho jazyka XQuery, ktery´ slouˇz´ı k prohled´av´an´ı stromovˇe organizovanych XML dokumentu˚ a datab´az´ı. C´ılem je ´ navrhnout a vytvoˇrit procesor pracuj´ıc´ı na principu algebraickych oper´atoru, ´ ˚ kter´e umoˇznuj´ ˇ ı efektivnˇejˇs´ı vyhodnocov´an´ı vstupn´ıch dotazu˚ neˇz pˇr´ım´a interpretace. V uvodu pr´ace je pod´an struˇcny´ pˇrehled aktu´alnˇe pouˇz´ıvanych ´ ´ technologi´ı, kter´e se k dotazov´an´ı nad XML uzce v´azˇ ou, vˇcetnˇe kr´atk´eho popisu samotn´eho jazyka XQuery. N´asleduje n´avrh ´ algebraickych ´ oper´atoru˚ a n´avrh pˇrekladovych ´ pravidel pro transformaci dotazu˚ na tyto oper´atory zahrnuj´ıc´ı tak´e optimalizaˇcn´ı postupy, kter´e umoˇznuj´ ˇ ı v pˇreloˇzen´em dotazu prov´est urˇcit´e upravy ´ tak, aby vysledek zustal zachov´an, ale vypoˇ ´ ˚ ´ cet probˇehl efektivnˇeji. Teoretick´e n´avrhy jsou d´ale pˇrevedeny do skuteˇcn´e podoby ve formˇe implementace procesoru. V z´avˇeru pr´ace je vysledn y´ ´ procesor porovn´an s jinymi existuj´ıc´ımi a bˇezˇ nˇe pouˇz´ıvanymi implementacemi. ´ ´ Kl´ıcˇ ov´a slova: XML, XQuery, XPath, dotazov´an´ı nad XML, dotazovac´ı jazyky, procesor, algebra, optimalizace, oper´ator, pl´an dotazu, pˇrekladaˇc
Abstract This diploma thesis deals with design and implementation of a processor of the XQuery computer language used for searching data in tree organized XML documents and databases. The goal of this work is to design and create a processor based on algebraic operators which can give better performance in evaluation of the input queries than direct interpretation. At the beginning of this work a breaf overview of currently used technologies for querying XML including a short description of the XQuery language is given. It is followed by a proposal of algebraic operators and proposal of compilation rules transforming queries into those operators. There are also included optimization techniques enabling to make such modifications in the compiled query as the result is preserved, but the evaluation is more effective. Those proposals are subsequently transformed into the real form of processor implementation. The final part of this work compares the implemented processor to other existing and commonly used implementations. Keywords: XML, XQuery, XPath, querying XML, data query languages, processor, algebra, optimization, operator, query plan, compiler
Seznam pouˇzitych ´ zkratek a symbolu˚ DOM DQL EBNF HTML PDF PI SOAP SQL TPNF TPQ XML XSLT
– – – – – – – – – – – –
Document Object Model Data Query Languages Extended Backus–Naur Form HyperText Markup Language Portable File Format Processing Instruction Simple Object Access Protocol Structured Query Language Tree Pattern Normal Form Tree Pattern Query eXtensible Markup Language eXtensible Stylesheet Language Transformation
Obsah 1
´ Uvod
2
Dotazov´an´ı nad XML 2.1 Zamyˇslen´ı na uvod . . . . . ´ 2.2 XML . . . . . . . . . . . . . 2.3 Dotazovac´ı jazyky nad XML 2.3.1 XPath . . . . . . . . . 2.3.2 XQuery . . . . . . . . 2.3.3 XQuery Core . . . . 2.3.4 XSLT . . . . . . . . .
3
4
1
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
2 2 2 4 4 5 8 9
XQuery algebra 3.1 Datovy´ model . . . . . . . . . . . . . . . . . . 3.1.1 Poloˇzka (item) . . . . . . . . . . . . . . 3.1.2 Sekvence (sequence) . . . . . . . . . . 3.1.3 N-tice (tuple) . . . . . . . . . . . . . . 3.1.4 Sch´ema n-tice . . . . . . . . . . . . . . 3.1.5 Tabulka (table) . . . . . . . . . . . . . 3.2 Oper´atory . . . . . . . . . . . . . . . . . . . . 3.2.1 Strom oper´atoru˚ . . . . . . . . . . . . 3.2.2 Vypoˇ ´ cet . . . . . . . . . . . . . . . . . 3.2.3 Oper´ator IN . . . . . . . . . . . . . . . 3.3 Kompilaˇcn´ı pravidla . . . . . . . . . . . . . . 3.3.1 Kompilace element´arn´ıch konstrukc´ı 3.3.2 FLWOR vyrazy . . . . . . . . . . . . . ´ 3.3.3 XPath vyrazy . . . . . . . . . . . . . . ´ 3.3.4 Kompilace dalˇs´ıch konstrukc´ı . . . . . 3.4 Optimalizace . . . . . . . . . . . . . . . . . . . 3.4.1 Odstranˇen´ı MapConcat . . . . . . . . 3.4.2 Odstranˇen´ı MapToItem . . . . . . . . 3.4.3 Vloˇzen´ı Product . . . . . . . . . . . . . 3.4.4 Vloˇzen´ı Join . . . . . . . . . . . . . . . 3.4.5 Spojen´ı kroku˚ XPath . . . . . . . . . . 3.4.6 Dalˇs´ı moˇznosti optimalizace . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
10 10 10 10 10 10 11 11 11 12 12 13 15 18 23 28 28 29 30 31 31 31 33
Implementace XQuery procesoru 4.1 Standard W3C a zjednoduˇsen´ı . . . . . . . . . . . . . . . . . . . . 4.1.1 Podporovan´e konstrukce . . . . . . . . . . . . . . . . . . 4.1.2 Nepodporovan´e nebo cˇ a´ steˇcnˇe podporovan´e konstrukce 4.2 Implementaˇcn´ı prostˇred´ı . . . . . . . . . . . . . . . . . . . . . . . 4.3 Univerz´aln´ı datov´e struktury . . . . . . . . . . . . . . . . . . . . 4.3.1 MyList . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.3.2 MyStack . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.3.3 MyQueue . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
35 35 35 37 37 37 37 38 38
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
38 38 39 39 41 42 43 43 43 44 45 46 47 49 49 52 53 54 55 55 56 60 60 61
5
Experiment´aln´ı vyhodnocov´an´ı 5.1 Srovn´an´ı jinych ´ implementac´ı . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.1.1 Shrnut´ı cˇ asovych ´ srovn´an´ı . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.2 Vliv optimalizac´ı na d´elku bˇehu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
63 63 70 70
6
Z´avˇer 6.1 Vlastn´ı pˇr´ınos a moˇznosti rozˇs´ırˇ en´ı . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.2 Osobn´ı zhodnocen´ı . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
72 72 72
4.4
4.5
4.6
4.7 4.8
4.3.4 MyHashSet . . . . . . . . . . . . . . . . . 4.3.5 MyIterator . . . . . . . . . . . . . . . . . . Datovy´ model . . . . . . . . . . . . . . . . . . . . 4.4.1 Typovy´ syst´em . . . . . . . . . . . . . . . 4.4.2 Spr´ava datovych ´ objektu˚ . . . . . . . . . 4.4.3 Implementace DataSequence a DataTable 4.4.4 DOM . . . . . . . . . . . . . . . . . . . . . 4.4.5 Symbolick´e n´azvy promˇennych ´ . . . . . . Parser . . . . . . . . . . . . . . . . . . . . . . . . . 4.5.1 Termin´aln´ı symboly . . . . . . . . . . . . 4.5.2 Syntakticky´ strom . . . . . . . . . . . . . 4.5.3 Scanner . . . . . . . . . . . . . . . . . . . 4.5.4 Syntaktick´a analyza . . . . . . . . . . . . ´ Kompiler . . . . . . . . . . . . . . . . . . . . . . . 4.6.1 Kompilace . . . . . . . . . . . . . . . . . . 4.6.2 Kompilace sloˇzitˇejˇs´ıch konstrukc´ı . . . . Optimalizace . . . . . . . . . . . . . . . . . . . . . Vyhodnocov´an´ı . . . . . . . . . . . . . . . . . . . 4.8.1 Vyhodnocen´ı statickych ´ sloˇzek oper´atoru˚ 4.8.2 Oper´ator Select . . . . . . . . . . . . . . . 4.8.3 Oper´ator TreeJoin . . . . . . . . . . . . . . 4.8.4 Oper´ator IN . . . . . . . . . . . . . . . . . 4.8.5 Oper´ator Call . . . . . . . . . . . . . . . . 4.8.6 Dalˇs´ı oper´atory . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
A Vestavˇen´e funkce
75
B Kompatibilita datovych ´ typu˚
83
C Spustitelny´ procesor
84
Seznam obr´azku˚ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
Osy XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Uk´azka stromu oper´atoru˚ . . . . . . . . . . . . . . . . . . . . . . . . . . Kompilace sekvence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Kompilace XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ˇ Cinnost oper´atoru MapConcat . . . . . . . . . . . . . . . . . . . . . . . Blokov´e sch´ema kompilace FLWOR . . . . . . . . . . . . . . . . . . . . Kompilace FLWOR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Struktura XPath vyrazu . . . . . . . . . . . . . . . . . . . . . . . . . . . ´ Pˇreklad uk´azkov´eho XPath vyrazu . . . . . . . . . . . . . . . . . . . . . ´ Mezivysledky uk´azkov´eho pˇrekladu XPath . . . . . . . . . . . . . . . . ´ Kompilace skal´arn´ı hodnoty bez optimalizace . . . . . . . . . . . . . . Kompilace skal´arn´ı hodnoty po optimalizaci odstranˇen´ım MapConcat Pl´an dotazu a//b . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Rozbor optimalizace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Blokov´a struktura procesoru . . . . . . . . . . . . . . . . . . . . . . . . . Tˇr´ıdn´ı diagram datov´eho modelu . . . . . . . . . . . . . . . . . . . . . . Tˇr´ıdn´ı diagram datov´e poloˇzky . . . . . . . . . . . . . . . . . . . . . . . Tˇr´ıdn´ı diagram spr´avy datovych ´ objektu˚ . . . . . . . . . . . . . . . . . Lexik´aln´ı a syntaktick´a analyza ´ (viz [8]) . . . . . . . . . . . . . . . . . . Tˇr´ıdn´ı diagram scanneru . . . . . . . . . . . . . . . . . . . . . . . . . . . Tˇr´ıdn´ı diagram parseru . . . . . . . . . . . . . . . . . . . . . . . . . . . . Princip parsov´an´ı XML elementu . . . . . . . . . . . . . . . . . . . . . . Tˇr´ıdn´ı diagram pˇrekladaˇce . . . . . . . . . . . . . . . . . . . . . . . . . . Princip substituce promˇennych . . . . . . . . . . . . . . . . . . . . . . . ´ Tˇr´ıdn´ı diagram optimalizace . . . . . . . . . . . . . . . . . . . . . . . . . Postorder seznam . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Preorder seznam . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Tˇr´ıdn´ı diagram modul´arn´ı stavby funkc´ı . . . . . . . . . . . . . . . . . . Srovn´an´ı cˇ asu˚ jednotlivych ´ procesoru˚ . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5 12 16 17 19 21 22 23 26 27 29 30 31 32 35 39 40 42 44 46 47 49 50 52 53 58 58 61 70
Seznam tabulek 1 2 3 4 5 6 7 8 9 10 11 12
Oper´atory algebry . . . . . . . . . . . . . . . . . . . . . . . Mezivysledky vyhodnocov´an´ı . . . . . . . . . . . . . . . . ´ Mezivysledek MapFromItem . . . . . . . . . . . . . . . . ´ Mezivysledek MapConcat . . . . . . . . . . . . . . . . . . ´ Podporovan´e vestavˇen´e funkce . . . . . . . . . . . . . . . Prvoˇc´ısla pro volbu velikosti tabulky hash . . . . . . . . . Datov´e typy procesoru . . . . . . . . . . . . . . . . . . . . Pˇr´ıklady termin´aln´ıch symbolu˚ bez obsahu a s obsahem . Srovn´an´ı algoritmu˚ pro navigaci na osu descendant . . . . Konfigurace testovac´ıho PC . . . . . . . . . . . . . . . . . Parametry testovac´ıho XML dokumentu . . . . . . . . . . Kompatibilita datovych ´ typu˚ . . . . . . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
14 22 29 30 37 38 41 44 57 63 63 83
Seznam algoritmu˚ 1 2 3 4 5 6 7
ˇ ast metody expandExpr pro pˇreklad podm´ınky . C´ Transformace oper´atoru Select . . . . . . . . . . . . Transformace vloˇzen´ı Product . . . . . . . . . . . . Vyhodnocen´ı oper´atoru Select . . . . . . . . . . . . Implementace TreeJoin . . . . . . . . . . . . . . . . . Implementace IN . . . . . . . . . . . . . . . . . . . . Puvodn´ ı implementace Call . . . . . . . . . . . . . . ˚
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
51 54 55 56 59 60 60
´ 1 Uvod Jedn´ım z nejv´ıce prakticky uplatnovan ych oboru˚ dneˇsn´ıch informaˇcn´ıch technologi´ı je tvorba ˇ ´ informaˇcn´ıch syst´emu. ˚ Zejm´ena v souˇcasn´e dobˇe nut´ı politick´a situace pˇrech´azet menˇs´ı cˇ i vˇetˇs´ı firmy na komplexn´ı informaˇcn´ı syst´emy obvykle z duvodu zefektivnˇen´ı vyroby nebo sluˇzeb. ˚ ´ Je duleˇ ˚ zit´e umˇet shrom´azˇ dit potˇrebn´a data, naj´ıt mezi nimi patˇriˇcn´e vztahy a co je hlavn´ı, je nutn´e v nich umˇet rychle vyhled´avat. Dotazovac´ı jazyky (DQL - Data Query Languages) jsou vyv´ıjeny jiˇz celou rˇ adu let a zamˇerˇ uj´ı se pˇredevˇs´ım na relaˇcn´ı datab´aze, kde jsou data organizov´any v tzv. relac´ıch nebo zjednoduˇsenˇe rˇ eˇceno v tabulk´ach. Jednoznaˇcnˇe nejpouˇz´ıvanˇejˇs´ım pˇredstavitelem tˇechto jazyku˚ je SQL (Structured Query Language). Relace ale nejsou jedinou moˇznost´ı jak organizovat data. Trendem modern´ı doby je st´ale v´ıce se uplatnuj´ ˇ ıc´ı stromov´a struktura v pod´an´ı XML, kter´a je v mnoha pˇr´ıpadech schopna l´epe a pruˇznˇeji reprezentovat urˇcitou re´alnou situaci. S t´ım roste potˇreba umˇet v takovychto stromovych ´ ´ organizac´ıch efektivnˇe a hlavnˇe snadno vyhled´avat. Zat´ımco v relaˇcn´ıch datab´az´ıch m´a jazyk SQL sv´e m´ısto v´ıce neohroziteln´e a vyvoj´ ´ arˇ i informaˇcn´ıch syst´emu˚ se bez nˇej neobejdou, v pˇr´ıpadˇe XML datab´az´ı jsou vznikl´e standardy pomˇernˇe cˇ erstv´e a do podvˇedom´ı veˇrejnosti teprve postupnˇe pronikaj´ı. Uˇz v tuto chv´ıli lze ale rˇ´ıci, zˇ e nejvˇetˇs´ımi kandid´aty na sˇ irok´e uplatnˇen´ı jsou XPath a XQuery. Je vhodn´e pˇredeslat, zˇ e XQuery je v uvozovk´ach pouze rozˇs´ırˇ en´ım jazyka XPath, cˇ ili zˇ e se nejedn´a o dva naprosto odliˇsn´e jazyky. C´ılem pr´ace je naimplementovat zjednoduˇseny´ procesor pomˇernˇe n´aroˇcn´eho deklarativn´ıho jazyka XQuery za pouˇzit´ı algebraickych ´ oper´atoru. ˚ Pr´ace se bude skl´adat ze cˇ tyˇr hlavn´ıch kapitol. Prvn´ı z nich, Dotazov´an´ı nad XML, bude vˇenov´ana pˇredstaven´ı souˇcasnˇe nejpouˇz´ıvanˇejˇs´ıch technologi´ı pro dotazov´an´ı nad XML. V dalˇs´ı kapitole, XQuery algebra, budou prezentov´any principy pˇrekladu dotazu˚ na algebraick´e oper´atory. Pujde o teoreticky´ z´aklad pro nadefinov´an´ı funkˇcnosti ˚ procesoru. Kapitola Implementace XQuery procesoru bude tento teoreticky´ z´aklad pˇrev´adˇet do praktick´e podoby. Posledn´ı kapitola, Experiment´aln´ı vyhodnocov´an´ı, pˇredstav´ı naimplementovany´ procesor a provede srovn´an´ı s jinymi existuj´ıc´ımi. ´
1
2
Dotazov´an´ı nad XML
Tato uvodn´ ı kapitola m´a nast´ınit z´akladn´ı principy spojen´e s XML a podat struˇcny´ pˇrehled technik, ´ kter´e souvis´ı s dotazov´an´ım.
2.1
Zamyˇslen´ı na uvod ´
V dneˇsn´ı dobˇe se lze setkat s XML t´emˇerˇ ve vˇsech oblastech informaˇcn´ıch technologi´ı. Nab´ız´ı se menˇs´ı zamyˇslen´ı, co je duvodem tak velk´e popularity tak jednoduch´eho jazyka. Pokud se ˚ zamˇerˇ´ıme na vyvoj moˇznost´ı poˇc´ıtaˇcov´eho hardwaru v prubˇ ´ ˚ ehu posledn´ıch 20-ti let a v´ıce, muˇ ˚ zeme pozorovat obvykle exponenci´aln´ı rust ˚ hodnot mnoha parametru. ˚ Jedn´a se pˇredevˇs´ım o velikost pamˇet´ı, rychlost procesoru, ˚ pˇrenosovou rychlost komunikaˇcn´ıch technologi´ı a dalˇs´ı. Takov´eto podm´ınky umoˇznuj´ ˇ ı odprostit se od uvaˇzov´an´ı nad kaˇzdym ´ bajtem zvl´asˇ t’ a vyuˇz´ıvat vyˇssˇ´ı urovnˇ e abstrakce. ´ Pohledem napˇr. na souborov´e form´aty pouˇz´ıvan´e 15 let zpˇet zjist´ıme, zˇ e se obvykle vˇse ukl´adalo v bin´arn´ı podobˇe. Kaˇzdy´ aplikaˇcn´ı software mˇel definovany´ svuj ˚ vlastn´ı form´at, jehoˇz specifikace byla v mnoha pˇr´ıpadech z obchodn´ıch duvod u˚ utajen´a. Modern´ı informaˇcn´ı tech˚ nologie vˇsak kladou duraz na modul´arn´ı stavbu, schopnost komunikace, dodrˇzov´an´ı standardu˚ ˚ a informaˇcn´ı dostupnost. Individualisticky´ pˇr´ıstup k rˇ eˇsen´ı probl´emu˚ sice muˇ ˚ ze byt ´ v uzk ´ ych ´ oblastech pouˇzit´ı efektivnˇejˇs´ı, avˇsak z principu pak zabranuje sˇ irˇs´ımu uplatnˇen´ı. ˇ Mezi nejduleˇ XML patˇr´ı jednoduch´a, striktn´ı, ale pˇresto velmi pruˇzn´a syn˚ zitˇejˇs´ı vyhody ´ taxe. D´ale bezesporu bezplatn´e vyuˇz´ıv´an´ı tohoto standardu a stromov´a organizace, kter´a dok´azˇ e naprosto pˇrirozenym popsat stavbu a okamˇzitych ´ zpusobem ˚ ´ stav re´alnych ´ objektu. ˚ V pˇr´ıpadˇe rozumn´e volby n´azvu˚ znaˇcek pro konkr´etn´ı pouˇzit´ı, je nav´ıc XML samopopisn´e, coˇz ve vˇetˇsinˇe pˇr´ıpadu˚ umoˇznuje spr´avnou interpretaci jeho obsahu i bez dostupnosti nˇejak´e ofici´aln´ı specifikace. ˇ Konkr´etnˇe tedy XML nach´az´ı uplatnˇen´ı od oblasti konfiguraˇcn´ıch souboru, ˚ pˇres internetov´e technologie (XHTML, SOAP), souborov´e form´aty (Open Document, Office Open XML) aˇz po cel´e stromov´e XML datab´aze. Mimo to lze tento jazyk pouˇz´ıt samozˇrejmˇe kdykoli pˇri potˇrebˇe serializace programovych ´ objektu. ˚
2.2
XML
eXtensible Markup Language, cˇ ili cˇ esky rozˇsiˇritelny´ znaˇckovac´ı jazyk, je vyv´ıjen a standardizov´an organizac´ı W3C moment´alnˇe ve verzi 1.1 [3]. Element tvoˇr´ı z´akladn´ı stavebn´ı stvaben´ı jednotku XML dokumentu. Zaˇca´ tek a konec elementu tvoˇr´ı znaˇcky
a , kde a pˇredstavuje jeho n´azev. Obsah mezi poˇca´ teˇcn´ı a koncovou znaˇckou je tvoˇren dalˇs´ımi elementy, koment´arˇ i, textem, procesn´ımi instrukcemi nebo odkazy na entity. Souˇca´ st´ı elementu mohou byt ´ atributy, kter´e se uv´ad´ı pˇr´ımo do uvozovac´ı znaˇcky. Je-li obsah mezi znaˇckami pr´azdny, ´ je moˇzn´e vynechat ukonˇcovac´ı znaˇcku s t´ım, zˇ e je uvozovac´ı znaˇcka doplnˇena o jednoduch´e lom´ıtko pˇred pravou z´avorkou (
). Atribut je tvoˇren vˇzdy dvojic´ı kl´ıcˇ ="hodnota". Hodnota mus´ı byt ´ uvedena v uvozovk´ach, mezi sebou jsou atributy navz´ajem oddˇelov´any mezerou. Atributy jsou vˇzdy souˇca´ st´ı elementu˚ nebo procesn´ıch instrukc´ı.
2
Textovy´ obsah pˇredstavuje jakykoli obecny´ text bez dalˇs´ı struktury. Je nutn´e vyvarovat se ´ znakum, kter´e mohou souviset se z´apisem znaˇcky, tzn. minim´alnˇe ,,<“ a ,,>“. Pro jejich ˚ vyj´adˇren´ı slouˇz´ı tzv. znakov´e entity ,,<“ a ,,>“. Koment´arˇ je zaps´an mezi dvojici znaˇcek ,,“. Jak bude pozdˇeji uvedeno, XQuery je schopen dotazovat se i na obsah koment´arˇ u, ˚ takˇze z hlediska zpracov´av´an´ı nen´ı moˇzn´e koment´arˇ e jednoduˇse zanedbat napˇr. preprocesorem. Procesn´ı instrukce (PI) si lze pˇredstavit jako speci´aln´ı elementy ohraniˇcen´e mezi ,,“ a ,,?>“. Kaˇzd´a PI m´a podobnˇe jako element svuj ˚ n´azev. Obsah PI je tvoˇren pouze atributy. Procesn´ı instrukce se obvykle pouˇz´ıvaj´ı ke specifikov´an´ı duleˇ ˚ zitych ´ pokynu˚ pro aplikaci, kter´a dan´e XML zpracov´av´a. Entity umoˇznuj´ textu. Pozdˇeji se na tyto entity ˇ ı pˇreddefinovat nˇejak´e delˇs´ı opakuj´ıc´ı se useky ´ muˇ tak do jist´e m´ıry eliminovat nadbyteˇcnost ˚ zeme jednoduˇse odkazovat a svym ´ zpusobem ˚ dat v XML. Pˇresn´e informace o entit´ach je moˇzn´e nal´ezt v [3]. Sekce CDATA slouˇz´ı pro z´apis surov´eho textu. Typickym zdrojov´eho ´ vyuˇzit´ım je z´apis useku ´ kodu. Obsah CDATA se uv´ad´ı mezi znaˇcky ,,“ ´ XML dokument je dobˇre formovany´ (well-formed), jestliˇze jsou splnˇena vˇsechna pravidla pro z´apis vyˇ cˇ a´ st´ı. Kaˇzdy´ XML dokument mus´ı obsahovat pˇresnˇe jeden ´ se definovanych ´ koˇrenovy´ element. D´ale by se v dokumentu mˇela objevit procesn´ı instrukce ud´avaj´ıc´ı verzi XML a pouˇzit´e kodov´ an´ı (viz uk´azka 1). ´ Vˇsechny vyˇ ´ se uveden´e cˇ a´ sti XML kromˇe atributu˚ byvaj´ ´ ı zobecnov´ ˇ any na pojem XML uzel. <section id="1"> Uˇ cebnice XQuery John Black Uˇ cebnice XPath Jack White Uˇ cebnice XML Jimm Green
Uk´azka 1: Uk´azka XML dokumentu
3
2.3
Dotazovac´ı jazyky nad XML
Dotazovac´ıch jazyku˚ pro XML existuje v souˇcasnosti cel´a rˇ ada. Jednotliv´e jazyky jsou v´ıce cˇ i m´enˇe pouˇz´ıvan´e, liˇs´ı se v principech, v syntaxi, ale vˇsechny se op´ıraj´ı o stromovou strukturu XML. 2.3.1
XPath
Jedn´a se o jednoho z prakticky nejpouˇz´ıvanˇejˇs´ıch z´astupcu˚ jazyku˚ pro dotazov´an´ı nad XML. Syntaxe tohoto jazyka je velmi snadn´a a intuitivn´ı, takˇze je ho moˇzn´e plnˇe vyuˇz´ıvat uˇz po kr´atk´em sezn´amen´ı. XPath je podobnˇe jako vˇse okolo XML standardizov´an organizac´ı W3C moment´alnˇe ve verzi 2.0 [4]. Filter vyrazy a axis kroky ´ Cely´ XPath vyraz se skl´ad´a z nˇekolika kroku˚ dvoj´ıho typu – axis steps a filter v´yrazu˚ (nepl´est s pre´ dik´aty). Jeho vyhodnocov´an´ı prob´ıh´a zleva doprava 1 . Vysledkem kaˇzd´eho kroku je uspoˇra´ dan´a ´ mnoˇzina XML uzlu. ˚ Pro kaˇzdy´ z uzlu˚ t´eto mnoˇziny pak probˇehne zpracov´an´ı kroku n´asleduj´ıc´ıho, kde dany´ uzel figuruje jako kontextov´y. Axis step vyjadˇruje pohyb po urˇcen´e ose (viz obr. 1), filter v´yraz pˇredstavuje operaci na z´akladˇe kontextov´eho XML uzlu, napˇr. vypoˇ ´ cet aritmetick´eho vyrazu. ´ Vysledn´ a mnoˇzina kaˇzd´eho kroku muˇ ´ ˚ ze byt ´ d´ale filtrov´ana pomoc´ı predik´atu˚ v hranatych ´ z´avork´ach. /library//book[@isbn="978-3-16-148410-0"]/author
Uk´azka 2: Demonstraˇcn´ı XPath dotaz
Na uk´azce 2 je zachycen jednoduchy´ XPath dotaz, jehoˇz ukolem je navr´atit jm´eno autora knihy ´ s urˇcitym ´ ISBN. Dotaz bude prov´adˇen nad dokumentem z uk´azky 1. Z´apis /library vybere ze zdrojov´eho dokumentu koˇrenovy´ element. Pomoc´ı //book dojde k vyhled´an´ı vˇsech elementu˚ – potomku˚ s n´azvem ,,book“. D´ale n´asleduje z´apis predik´atu [@isbn="978-3-16-148410-0"], ktery´ zajist´ı filtrov´an´ı vˇsech uzlu˚ – knih s hodnotou atributu isbn rovnou ,,978-3-16-148410-0“. Z takto vznikl´e mnoˇziny (obsahuj´ıc´ı vzhledem k dotazovan´emu dokumentu pouze jeden element) jsou nakonec vybr´ani vˇsichni pˇr´ım´ı potomci – uzly s n´azvem ,,author“. Uvedeny´ vyraz je ve skuteˇcnosti zjednoduˇsen´ım dotazu z uk´azky 3. ´ /child::library/descendant-or-self::node()/book [attribute::isbn="978-3-16-148410-0"]/child::author
Uk´azka 3: XPath dotaz bez zkratkovych ´ z´apisu˚
1 Vyhodnocov´ an´ı zleva doprava m´a symbolicky´ vyznam pro uˇzivatele, ve skuteˇcnosti muˇ ´ ˚ ze procesor pohl´ızˇ et na vyraz ´ jako na celek a vyhodnotit jej tak efektivnˇeji.
4
Osy XML Je vidˇet, zˇ e zjednoduˇseny´ (zkratkovy) ´ z´apis na uk´azce 2 neobsahoval kl´ıcˇ ov´a slova child, descendant-or-self a attribute. Jedn´a se o specifikaci tzv. os. Uveden´e 3 osy jsou totiˇz prakticky nejpouˇz´ıvanˇejˇs´ı, a tak by byl jejich plny´ z´apis zbyteˇcnˇe zdlouhavy. ´ Osy pˇredstavuj´ı urˇcen´ı prohled´avan´e cˇ a´ sti XML dokumentu vzhledem k uzlu, na kter´em se aktu´alnˇe nach´az´ıme, tj. kontextov´emu uzlu. Z´apis node() pˇredstavuje na uk´azce 3 vybˇ ´ er libovoln´eho XML uzlu. Pˇrehled os je ilustrov´an na obr´azku 1. Aktu´aln´ı kontextovy´ uzel je zvyraznˇ en. ´ ancestor preceding
following ancestor-or-self
parent
self
preceding-sibling
following-sibling
child
descendant descendant-or-self
Obr´azek 1: Osy XML
Zbyv´ ´ a podotknout, zˇ e XPath je case-sensitive, tzn. rozliˇsuje velikost znaku˚ a to nejen vzhledem ke kl´ıcˇ ovym ale tak´e vzhledem k n´azvum ´ slovum, ˚ ˚ XML uzlu. ˚ 2.3.2
XQuery
Jazyk XQuery je pˇredstavitelem deklarativn´ıch programovac´ıch jazyku. ˚ To znamen´a, zˇ e program, resp. v tomto pˇr´ıpadˇe dotaz specifikuje, co je poˇzadov´ano na vystupu bez pˇresn´eho ud´an´ı ele´ ment´arn´ıch kroku, povedou. Jedn´a se o pomˇernˇe mlady´ jazyk, ktery´ vznikl ˚ kter´e k vysledku ´ na z´akladˇe dotazovac´ıho jazyka Quilt [15]. Snahou XQuery je poskytnout podobny´ komfort pˇri dotazov´an´ı nad XML datab´azemi jako poskytuje SQL nad datab´azemi relaˇcn´ımi. XQuery je opˇet standardizov´an W3C, moment´alnˇe ve verzi 1.0 (od roku 2007). Standard definuje tento jazyk nejen pro tvorbu dotazu, ˚ ale tak´e pro tvorbu celych ´ funkc´ı a modulu. ˚ Souˇca´ st´ı XQuery je moˇznost pouˇz´ıv´an´ı dotazu˚ XPath. XQuery k tˇemto dotazum ˚ pˇrid´av´a nˇekter´e velmi uˇziteˇcn´e sloˇzitˇejˇs´ı konstrukce. Aktu´alnˇe platn´e standardy obou jazyku˚ – XPath a XQuery pracuj´ı se spoleˇcnym ´ datovym ´ modelem [6]. Stejnˇe jako XPath je tento jazyk case-sensitive. FLWOR vyrazy ´ FLWOR vyrazy [ˇcteno jako flower] pˇredstavuj´ı z´akladn´ı a nejv´ıce pouˇz´ıvanou konstrukc´ı XQuery. ´ N´azev FLWOR vych´az´ı z prvn´ıch p´ısmen jednotlivych ´ klauzul´ı, tj. cˇ a´ st´ı t´eto konstrukce. Jedn´a se 5
o klauzule for, let, where, order by a return. Pro uˇ ´ cely t´eto pr´ace budou vysvˇetleny pouze z´akladn´ı principy tˇechto vyraz u, ´ ˚ pro detailnˇejˇs´ı a n´azornˇejˇs´ı studium lze vyuˇz´ıt napˇr. [1]. for $b at $i in /library//book let $a := $b/author where $s = "John Smith" and $i > 1 order by $b/isbn return $b
Uk´azka 4: Demonstraˇcn´ı FLWOR vyraz ´
Vyznam jednotlivych ´ ´ klauzul´ı bude vysvˇetlen na uk´azkov´em dotazu 4. Jako dotazovany´ dokument opˇet poslouˇz´ı XML z uk´azky 1. Klauzule for rˇ´ık´a, zˇ e bude cely´ zbytek vyrazu iterov´an pro promˇennou b na pozici i pˇres nˇejakou ´ uspoˇra´ danou mnoˇzinu XML uzlu, ˚ kter´e obdrˇz´ıme XPath dotazem /library//book. Ve zbytku vyrazu bude promˇenn´a b postupnˇe nabyvat hodnot jednotlivych XML uzlu. ´ ´ ´ ˚ Promˇenn´a i (tzv. poziˇcn´ı promˇenn´a) bude pˇredstavovat cˇ ´ıtaˇc jednotlivych u. ´ pruchod ˚ ˚ Klauzul´ı for se ve FLWOR muˇ z hlediska uˇzivatele o zanoˇren´e ˚ ze objevit v´ıce, v tom pˇr´ıpadˇe pujde ˚ iterace. Specifikace poziˇcn´ı promˇenn´e at $i nen´ı povinn´a. Klauzule let slouˇz´ı pro zaveden´ı pomocn´e promˇenn´e a, do kter´e bude v kaˇzd´e iteraci for pˇriˇrazena hodnota XPath vyrazem $b/author. Kromˇe XPath se zde mohou objevovat ´ napˇr. aritmetick´e vyrazy, vol´an´ı vestavˇenych nebo uˇzivatelskych funkc´ı. Klauzul´ı for a ´ ´ ´ let se ve FLWOR muˇ ˚ ze zopakovat libovolnˇe mnoho minim´alnˇe vˇsak vˇzdy alesponˇ jedna z nich. Klauzule where n´asleduje aˇz po vˇsech for a let. Tato klauzule specifikuje podm´ınku, za jakych ´ okolnost´ı dojde skuteˇcnˇe k vyhodnocen´ı d´ılˇc´ıho vysledku n´asleduj´ıc´ı klauzule return. ´ V uk´azkov´em dotazu si lze vˇsimnout pouˇzit´ı vyraz u˚ pro porovn´av´an´ı a jejich spojen´ı lo´ gickym ´ souˇcinem. V pˇr´ıpadˇe, zˇ e podm´ınku specifikovat nepotˇrebujeme, je moˇzn´e celou klauzuli where vynechat. Klauzule order by umoˇznuje prov´est setˇr´ızen´ı dle specifikovanych ˇ ´ krit´eri´ı. V tomto pˇr´ıpadˇe jde o vzestupn´e abecedn´ı tˇr´ızen´ı podle ISBN jednotlivych ´ knih, kter´e vyhovˇely podm´ınce z klauzule where. XQuery umoˇznuje prov´adˇet i sestupn´e tˇr´ızen´ı kl´ıcˇ ovym ˇ ´ slovem descending, kter´e pˇrid´ame za tˇr´ıd´ıc´ı krit´erium. Krit´eri´ı pro tˇr´ızen´ı muˇ ˚ ze byt ´ v´ıce, v tom pˇr´ıpadˇe jsou mezi sebou oddˇeleny cˇ a´ rkou. Cel´a klauzule order by stejnˇe jako where nen´ı povinn´a. Klauzule return je povinnou posledn´ı klauzul´ı kaˇzd´eho FLWOR vyrazu. Ud´av´ame zde, co ´ nakonec poˇzadujeme na vystupu. Pomoc´ı XPath je zde moˇzn´e vracet existuj´ıc´ı XML uzly, ´ popˇr. s nimi prov´adˇet nˇejak´e rˇ etˇezcov´e nebo aritmetick´e operace. Velmi cˇ asto se zde objevuj´ı konstrukce novych ´ XML uzlu. ˚ XML konstruktory Duleˇ ˚ zitou souˇca´ st´ı XQuery jazyka je moˇznost vytv´arˇ et vlastn´ı XML uzly, popˇr. cel´e XML stromy, jejichˇz obsah muˇ u. ˚ ze byt ´ vytv´arˇ en napˇr. pomoc´ı FLWOR vyraz ´ ˚ Existuj´ı dva typy XML konstruk6
toru˚ – pˇr´ım´e (direct) a vypoˇcten´e (computed). Z praktickych duvod u˚ se obvykle pouˇz´ıvaj´ı pouze ´ ˚ konstruktory pˇr´ım´e. V pˇr´ıpadˇe vypoˇcten´ych konstruktoru˚ se XML strom vytv´arˇ´ı pomoc´ı speci´aln´ıch kl´ıcˇ ovych ´ slov jako element, attribute, text, comment a processing-instruction. Na uk´azce 5 je pˇr´ıklad konstrukce XML elementu s n´azvem ,,a“ a textovym obsahem tvoˇrenym obsahem ´ ´ promˇenn´e x a textem ,,test“. Konstrukce XML prob´ıh´a tak, zˇ e kl´ıcˇ ovym ´ slovem specifikujeme typ XML uzlu (element, atribut, textovy´ uzel atd.), za nˇej (pokud to dany´ typ vyˇzaduje – elementy, atributy, procesn´ı instrukce) um´ıst´ıme jeho n´azev a nakonec do sloˇzenych ´ z´avorek obsah, ktery´ se v pˇr´ıpadˇe elementu˚ muˇ ˚ ze skl´adat z dalˇs´ıch XML uzlu, ˚ v pˇr´ıpadˇe atributu˚ z rˇ etˇezcov´e hodnoty. Jednotliv´e cˇ a´ sti obsahu oddˇelujeme cˇ a´ rkou. element a { text { $x }, text { "test" } }
Uk´azka 5: Pouˇzit´ı vypoˇctenych ´ konstruktoru˚
Pˇr´ım´e konstruktory jsou na pouˇzit´ı mnohem intuitivnˇejˇs´ı. Nov´e XML uzly konstruujeme velmi jednoduˇse tak, zˇ e je zap´ısˇ eme v jejich XML podobˇe, tzn. podle pravidel uvedenych ´ v kapitole 2.2. Pokud nastane situace, zˇ e v obsahu elementu nebo hodnoty atributu potˇrebujeme z´ıskat hodnotu nˇejak´e promˇenn´e napˇr. z let klauzule FLWOR vyrazu, um´ıst´ıme do XML konstruktoru vnoˇreny´ ´ vyraz do sloˇzenych z´avorek. Stejn´eho vysledku jako u konstruktoru z uk´azky 5 dos´ahneme ´ ´ ´ vyrazem na uk´azce 6. ´ Pˇrestoˇze se muˇ ˚ ze pˇr´ıtomnost vypoˇctenych ´ konstruktoru˚ jevit jako zbyteˇcn´a, nen´ı tomu tak. Vypoˇcten´e konstruktory totiˇz na rozd´ıl od pˇr´ımych ´ neumoˇznuj´ ˇ ı specifikovat n´azvy uzlu˚ pomoc´ı promˇennych ´ ve vyrazu. ´ { $x } test
Uk´azka 6: Pouˇzit´ı pˇr´ımych ´ konstruktoru˚
Na XQuery nelze pohl´ızˇ et pouze jako na filtr vstupn´ıho dokumentu. Na uk´azce 7 je pˇr´ıklad dotazu, jehoˇz vnitˇrn´ı cˇ a´ st pomoc´ı pˇr´ımych ´ konstruktoru˚ vytvoˇr´ı sekvenci XML uzlu, ˚ nad kterou probˇehne jednoduchy´ XPath. U kaˇzd´eho vyrazu, ktery´ pracuje nad XML, nez´aleˇz´ı na tom, zda ´ jsou XML uzly pouze vysledkem filtrov´an´ı vstupn´ıho dokumentu nebo byly vytvoˇreny bˇehem ´ vyhodnocov´an´ı dotazu. (for $n in (
, , , ) return $n)/@id
Uk´azka 7: XQuery s konstrukc´ı XML
7
Dalˇs´ı konstrukce XQuery FLWOR vyrazy nejsou zdaleka jedinou konstrukc´ı, kterou XQuery obohacuje syntaxi XPath. ´ Minim´alnˇe za zm´ınku zde stoj´ı pouˇz´ıv´an´ı alternativy, pˇrep´ınaˇce typeswitch nebo kvantifikovanych u. tvorbu vlastn´ıch uˇzivatelskych ´ vyraz ´ ˚ Specifikace d´ale umoˇznuje ˇ ´ datovych ´ typu, ˚ modulu˚ a funkc´ı. Lze uk´azat [11], zˇ e XQuery je Turing-kompletn´ı jazyk. 2.3.3
XQuery Core
XQuery poskytuje velkou sadu pravidel, kter´e umoˇznuj´ ˇ ı jeho pohodln´e pouˇz´ıv´an´ı bez nutnosti dlouhodob´eho studia. Z hlediska vyhodnocov´an´ı dotazu˚ je vˇsak vydefinov´ana podmnoˇzina tohoto jazyka zn´am´a jako XQuery core obsahuj´ıc´ı pouze omezen´e mnoˇzstv´ı konstrukc´ı, na kter´e lze kaˇzdy´ XQuery dotaz pˇrepsat. Proces pˇrepisu dotazu XQuery na XQuery Core byv´ ´ a nazyv´ ´ an jako tzv. normalizace. Normalizace vstupn´ıho dotazu je bˇezˇ nym ´ poˇca´ teˇcn´ım krokem vyhodnocov´an´ı u vˇetˇsiny procesoru. ˚ Uk´azka 8 pˇredstavuje normalizovanou podobu jednoduch´eho XPath vyrazu $a/book/isbn. ´ Z uveden´e uk´azky je patrn´e, zˇ e z relativnˇe jednoduch´eho vyrazu vznikla pomˇernˇe sloˇzit´a kon´ strukce skl´adaj´ıc´ı se ze dvou FLWOR a pomocn´e funkce ddo, kter´a eliminuje duplicitn´ı vyskyty ´ uzlu˚ a rˇ ad´ı uzly podle puvodn´ ıho poˇrad´ı v dokumentu. ˚ ddo( let $seq := ddo($a) let $last := fn:count($seq) for $dot at $position in $seq return let $seq := ddo(child::book) let $last := fn:count($seq) for $dot at $position in $seq return child::isbn)
Uk´azka 8: Normalizace XPath vyrazu $a/book/isbn ´
XQuery Core napˇr. nepodporuje aritmetick´e vyrazy, vyrazy pro porovn´av´an´ı, logick´e spojky ´ ´ – to vˇse se obvykle nahrazuje vol´an´ım vestavˇenych funkc´ı, d´ale nejsou definov´any vyrazy ´ ´ XPath, pˇr´ım´e konstruktory nebo klauzule order by FLWOR vyraz u. ym ´ ˚ Normalizace je vyborn ´ ´ n´astrojem pro specifikaci s´emantiky XQuery [7], avˇsak ne vˇzdy je vhodn´e prov´est normalizaci pˇresnˇe dle doporuˇcen´ı W3C, jelikoˇz se tak v urˇcitych ´ pˇr´ıpadech muˇ ˚ zeme pˇripravit o efektivnˇejˇs´ı variantu vyhodnocov´an´ı. Puvodn´ ı zad´an´ı pr´ace se omezuje pouze na pˇreklad normalizovanych XQuery dotazu. ˚ ´ ˚ Vysledkem je vˇsak procesor, ktery´ si porad´ı i s mnoha dotazy, kter´e normalizac´ı neproˇsly. Jsou tedy ´ podporov´any pˇr´ım´e konstruktory, XPath vyrazy a dalˇs´ı konstrukce, kter´e XQuery Core nedefinuje ´ (viz kapitola 4.1).
8
2.3.4
XSLT
Posledn´ım jazykem, ktery´ zde bude sp´ısˇ e pro uplnost zm´ınˇen je XSLT (eXtensible Stylesheet ´ Language Transformation). Nejedn´a se o dotazovac´ı jazyk v prav´em slova smyslu, XSLT je prim´arnˇe navrˇzen k prov´adˇen´ı transformac´ı XML dokumentu˚ napˇr. do prezentovateln´e podoby ve formˇe HTML. V kombinaci s jazykem XSL Formatting Objects je pak moˇzn´e prov´adˇet napˇr. exporty do form´atu PDF. Podobnˇe jako u XQuery tvoˇr´ı XPath souˇca´ st jazyka tohoto jazyka. Je zde opˇet pouˇzity´ stejny´ datovy´ model [6]. Podrobnˇejˇs´ı informace o XSLT vˇcetnˇe uk´azkovych ´ tutori´alu˚ lze nal´ezt v [1]. Vzhledem k tomu, zˇ e se vˇsechny tˇri uveden´e jazyky (XPath, XQuery a XSLT) cˇ asto pˇrekryvaj´ ´ ı (minim´alnˇe v datov´em modelu), je bˇezˇ nou prax´ı, zˇ e dostupn´e implementace (napˇr. Saxon [10] nebo XML Prime [2]) nejsou zamˇerˇ en´e pouze na jeden jediny´ jazyk, ale poskytuj´ı komplexn´ı rˇ eˇsen´ı od zpracov´an´ı XML pˇres v´ıce ruzn u˚ dotazov´an´ı. ˚ ych ´ zpusob ˚
9
3
XQuery algebra
Nejen v pˇr´ıpadˇe XQuery, ale tak´e napˇr. jazyka SQL, neprob´ıh´a vyhodnocov´an´ı vstupn´ıho dotazu interpretac´ı. Dotaz je obvykle nejprve zkompilov´an na strom oper´atoru, ˚ kter´e jsou pozdˇeji v pˇresnˇe urˇcen´em poˇrad´ı vyhodnocov´any. Co to oper´atory jsou a jakym pracuj´ı popi´ zpusobem ˚ suje pr´avˇe algebra. Algeber existuje cel´a rˇ ada, liˇs´ı se jak svym ´ uˇ ´ celem (relaˇcn´ı datab´aze, stromov´e datab´aze), tak mnoˇzinou definovanych ´ oper´atoru˚ a datovym ´ modelem. V souvislosti s XQuery se obvykle pouˇz´ıv´a algebra zaloˇzen´a na n-ticov´em datov´em modelu. Algebra zde popsan´a a pozdˇeji implementovan´a vych´az´ı z cˇ l´anku [16] a kombinuje vyhodnocov´an´ı na z´akladˇe toku n-tic s vyhodnocov´an´ım na z´akladˇe toku datovych ´ poloˇzek.
3.1
Datovy´ model
Pˇred vysvˇetlen´ım samotn´e algebry je nutn´e nejprve ustanovit datovy´ model a nadefinovat vhodn´e form´aln´ı znaˇcen´ı, kter´e pak bude pouˇz´ıv´ano k popisu funkˇcnosti jednotlivych ´ oper´atoru. ˚ Pozdˇeji v implementaˇcn´ıch detailech bude tento model pˇresnˇeji specifikov´an na tˇr´ıdn´ım diagramu, ktery´ vymez´ı z´akladn´ı datov´e typy cel´eho procesoru (viz kapitola 4.4). 3.1.1
Poloˇzka (item)
Poloˇzkou muˇ ˚ ze byt ´ libovoln´a atomick´a hodnota, tzn. cˇ ´ıslo, textovy´ rˇ etˇezec nebo hodnota typu boolean (true / false). Za poloˇzku se rovnˇezˇ povaˇzuje jakykoli XML uzel, tzn. element, atribut, ´ textovy´ uzel nebo koment´arˇ . Entity, sekce CDATA a procesn´ı instrukce jsou zde pro zjednoduˇsen´ı vynech´any. Poloˇzky budou form´alnˇe znaˇceny jako ik . Ve speci´aln´ım pˇr´ıpadˇe, pokud pujde o ato˚ mick´e hodnoty pak ak . 3.1.2
Sekvence (sequence)
Sekvenc´ı se rozum´ı uspoˇra´ dan´a multimnoˇzina poloˇzek. Form´alnˇe bude sekvence znaˇcena jako S = ⟨i1 , i2 , . . . , in ⟩, kde ik (1 ≤ k ≤ n) je poloˇzka sekvence S a n znaˇc´ı d´elku t´eto sekvence. Pr´azdn´a sekvence, tj. sekvence bez poloˇzek, je znaˇcena jednoduˇse ⟨⟩. V dalˇs´ı cˇ a´ sti textu bude moˇzn´e pohl´ızˇ et na jednoprvkov´e sekvence jako na poloˇzky a naopak. 3.1.3
N-tice (tuple)
N-tice pˇredstavuje n-rozmˇerny´ vektor s jednoznaˇcnˇe pojmenovanymi ´ sloˇzkami, kter´e jsou tvoˇreny vyˇ sekvencemi. V terminologii relaˇcn´ıch datab´az´ı je ekvivalentem n-tice z´aznam. ´ se definovanymi ´ Form´aln´ı z´apis n-tice bude vypadat jako τ = [q1 : S1 , q2 : S2 , . . . , qn : Sn ], kde q1 , q2 , . . . , qn pˇredstavuj´ı oznaˇcen´ı (n´azvy) sloˇzek a S1 , S2 , . . . , Sn jednotliv´e sekvence. Opˇet v n´avaznosti na relaˇcn´ı datab´aze bychom mohli rˇ´ıci, zˇ e q1 , q2 , . . . , qn pˇredstavuj´ı n´azvy atributu. ˚ V pˇr´ıpadˇe, zˇ e n = 0 obsahuje n-tice nulovy´ poˇcet sloˇzek a jde o tzv. pr´azdnou n-tici, kterou zapisujeme pˇrirozenˇe jako []. 3.1.4
Sch´ema n-tice
Z pˇredchoz´ı definice vyplyv´ strukturou, tzn. s ruzn ´ a nutnost rozliˇsovat n-tice s ruznou ˚ ˚ ym ´ znaˇcen´ım q1 , q2 , . . . , qn . Takov´e znaˇcen´ı bude nazyv´ ´ ano sch´ematem Q = ⟨q1 , q2 , . . . , qn ⟩. 10
3.1.5
Tabulka (table)
Stejnˇe tak jako poloˇzky mohly vytv´arˇ et sekvence, mohou n-tice vytv´arˇ et tabulky. Tabulka tedy pˇredstavuje uspoˇra´ danou multimnoˇzinu n-tic a form´alnˇe ji znaˇc´ıme jako σ = ⟨τ1 , τ2 , . . . , τn ⟩. Uveden´a definice tabulky obecnˇe umoˇznuje sdruˇzovat libovoln´e n-tice, tzn. i s ruzn ˇ ˚ ym ´ sch´ematem. N´as ale budou zaj´ımat pˇredevˇs´ım tzv. homogenn´ı tabulky, kde budou m´ıt vˇsechny n-tice stejn´e sch´ema.
3.2
Oper´atory
Oper´atorem se obecnˇe rozum´ı nˇejak´a funkce, kter´a transformuje jeden nebo v´ıce vstupu˚ podle urˇcitych V pˇr´ıpadˇe napˇr. z´akladn´ıch aritmetickych ´ pravidel na vystup. ´ ´ oper´atoru˚ (+, −, ∗, :) je situace pomˇernˇe snadn´a – m´ame dva nez´avisl´e vstupy (levy´ a pravy´ operand), na z´akladˇe kterych ´ oper´ator spoˇc´ıt´a vystup. ´ V pˇr´ıpadˇe XQuery (a nejen XQuery) je ale situace trochu komplikovanˇejˇs´ı. Koneˇcny´ vysledek ´ totiˇz muˇ vstupech, ale tak´e na nˇejak´em pˇredem nezn´am´em ˚ ze z´aviset nejen na nez´avislych ´ vysledku mezivypoˇ ´ ´ ctu. Typickym ´ pˇr´ıkladem je bˇezˇ ny´ oper´ator relaˇcn´ı algebry – selekce, kter´emu je potˇreba kromˇe nez´avisl´e vstupn´ı mnoˇziny z´aznamu˚ specifikovat tak´e podm´ınku, za jakych ´ okolnost´ı bude zpracov´avany´ z´aznam souˇca´ st´ı vystupu. ´ Obecn´a struktura oper´atoru vypad´a n´asledovnˇe: Op[q1 , . . . , qk ]{DOp1 , . . . , DOpl }(Op1 , . . . , Opm ) q1 , . . . , qk jsou statick´e sloˇzky oper´atoru. Muˇ specifikaci ˚ ze se jednat napˇr. o n´azvy promˇennych, ´ datov´eho typu nebo specifikaci n´azvu XML elementu. Podm´ınkou je, aby byly tyto hodnoty zn´am´e jeˇstˇe pˇred zaˇca´ tkem vyhodnocov´an´ı. DOp1 , . . . , DOpl jsou tzv. z´avisl´e oper´atory (dependent). Jedn´a se pr´avˇe o ty oper´atory, kter´e slouˇz´ı pro vypoˇ ´ cet mezivysledku. ´ Op1 , . . . , Opm jsou nez´avisl´e oper´atory – vstupy. Najdeme je t´emˇerˇ ve vˇsech oper´atorech. Vyjimku ´ tvoˇr´ı pouze ty, kter´e vracej´ı nˇejakou staticky danou skal´arn´ı hodnotu nebo pˇristupuj´ı ke kontextovym Jak z´avisl´e, tak nez´avisl´e oper´atory jsou vˇzdy oper´atory. To ´ promˇennym. ´ znamen´a, zˇ e se na m´ıstˇe oper´atoru nikdy nevyskytne zˇ a´ dn´a skal´arn´ı hodnota. Pro vytvoˇren´ı skal´arn´ı hodnoty existuje speci´aln´ı oper´ator, ktery´ m´a skuteˇcnou skal´arn´ı hodnotu danou pomoc´ı statick´e sloˇzky (viz kapitola 3.3.1). 3.2.1
Strom oper´atoru˚
Vzhledem k tomu, zˇ e se oper´ator obvykle skl´ad´a z dalˇs´ıch z´avislych nebo nez´avislych ´ ´ suboper´atoru, ˚ vznikne kompilac´ı hierarchie reprezentovateln´a stromem, kde kaˇzdy´ oper´ator pˇredstavuje jeden vrchol a hrana odkaz na suboper´ator. Oper´atory bez z´avislych ´ a nez´avislych ´ suboper´atoru˚ utvoˇr´ı listy. Cely´ strom oper´atoru, kompilace, byv´ ˚ ktery´ je vysledkem ´ ´ a nazyv´ ´ an tak´e jako pl´an vykon´av´an´ı dotazu. Uk´azkovy´ strom oper´atoru˚ je moˇzn´e vidˇet napˇr. na obr´azku 2 n´ızˇ e.
11
3.2.2
Vypoˇ ´ cet
Pl´an vykon´av´an´ı dotazu ud´av´a poˇrad´ı v jak´em budou jednotliv´e oper´atory vyhodnocov´any. Vypoˇ ´ cet vˇzdy zaˇc´ın´a a konˇc´ı koˇrenov´ym oper´atorem, tzn. t´ım, ktery´ tvoˇr´ı koˇren stromu. Kaˇzdy´ oper´ator nejprve vyhodnot´ı vˇsechny sv´e nez´avisl´e vstupy a aˇz pot´e na jejich z´akladˇe pˇr´ıpadnˇe vyhodnot´ı vstupy z´avisl´e, cˇ ili mezivysledky. Podle vysledk u˚ nez´avislych vstupu, ´ ´ ´ ˚ d´ılˇc´ıch mezivysledk u˚ nebo pˇr´ıpadnˇe statickych a vr´at´ı vysledek. Vysledek ´ ´ sloˇzek provede svou vlastn´ı ulohu ´ ´ ´ koˇrenov´eho oper´atoru je vysledkem vyhodnocov´an´ı cel´eho dotazu. ´ 3.2.3
Oper´ator IN
Kaˇzdy´ oper´ator je vyhodnocov´an v r´amci nˇejak´e kontextov´e hodnoty – n-tice nebo poloˇzky. Tuto kontextovou hodnotu (zkr´acenˇe kontext) nastav´ı nˇejaky´ oper´ator Op se z´avislym ´ suboper´atorem Opsub pˇri poˇzadavku na jeho vyhodnocen´ı. Obsahuje-li Op vstupy nez´avisl´e, pak jsou tyto vyhod´ celem oper´atoru IN je pouh´e navr´acen´ı tohoto kontextu. noceny se stejnym ´ kontextem jako Op. Uˇ
Pˇr´ıklad 1: V´yznam oper´atoru IN V uk´azkov´em stromu na obr´azku 2 je IN pouˇzity´ celkem 4 kr´at. Pro lepˇs´ı orientaci jsou jeho vyskyty rozliˇseny spodn´ım indexem. Co pˇresnˇe kter´e oper´atory znamenaj´ı nen´ı moment´alnˇe ´ duleˇ ˚ zit´e. Podstatn´e je uvˇedomit si, ktery´ oper´ator nastavil kterou kontextovou hodnotu, jeˇz z´ısk´av´ame oper´atorem IN. To je moˇzn´e zjistit jednoduˇse tak, zˇ e budeme proch´azet strom od konkr´etn´ıho listu IN postupnˇe na rodiˇce tak dlouho, neˇz projdeme hranou pˇredstavuj´ıc´ı odkaz na z´avisly´ suboper´ator. Výsledek
𝑀𝑎𝑝𝑇𝑜𝐼𝑡𝑒𝑚
𝑇𝑟𝑒𝑒𝐽𝑜𝑖𝑛[attribute, Message] 𝐽𝑜𝑖𝑛 𝑇𝑢𝑝𝑙𝑒𝐴𝑐𝑐𝑒𝑠𝑠 event
𝑰𝑵𝟏
𝑀𝑎𝑝𝐹𝑟𝑜𝑚𝐼𝑡𝑒𝑚
𝐶𝑎𝑙𝑙[eq]
𝑰𝑵𝟒
𝑇𝑟𝑒𝑒𝐽𝑜𝑖𝑛[child, LogEvent]
𝑇𝑢𝑝𝑙𝑒 event
𝑇𝑟𝑒𝑒𝐽𝑜𝑖𝑛[attribute, entryType]
𝐶𝑎𝑙𝑙 root
𝑰𝑵𝟐
𝑇𝑢𝑝𝑙𝑒𝐴𝑐𝑐𝑒𝑠𝑠 event
𝑆𝑐𝑎𝑙𝑎𝑟 error
𝑰𝑵𝟑
Odkaz na závislý suboperátor Odkaz na nezávislý suboperátor
Obr´azek 2: Uk´azka stromu oper´atoru˚
12
Pro IN2 je to tedy oper´ator MapFromItem, pro IN3 oper´ator Join a pro IN4 oper´ator MapToItem. IN1 je jediny´ pˇr´ıpad, ktery´ nesouvis´ı s zˇ a´ dnym ´ oper´atorem se z´avislym ´ vstupem. Je moˇzn´e si pˇredstavit, zˇ e koˇrenovy´ oper´ator MapToItem je vyhodnocov´an jako z´avisly´ vstup vzhledem k nˇejak´e programov´e funkci, kter´a zahajuje vypoˇ dotazu s nˇejakym ´ cet vysledku ´ ´ vychoz´ ım kontextem n-tic´ı, jej´ızˇ obsahem mohou byt ´ ´ napˇr. glob´aln´ı promˇenn´e nebo kontextovy´ XML uzel nastaveny´ na dotazovany´ XML dokument. V tuto chv´ıli sp´ısˇ e pro zaj´ımavost – strom na obr. 2 je pl´anem pro XQuery dotaz na uk´azce 9. for $event in /EventLogeEvent where $event/@Entry_Type = "Error" return $event/@Message
Uk´azka 9: Uk´azkovy´ XQuery dotaz
Kompletn´ı seznam oper´atoru˚ je k dispozici v tabulce 1, kter´a je s malymi upravami pˇrebr´ana ´ ´ z cˇ l´anku [16], tabulky 1. Oproti [16] jsou zde vynech´any nepouˇzit´e oper´atory, naopak se zde nav´ıc vyskytuj´ı And, Or a IN. Funkce nˇekterych ´ m´enˇe zn´amych ´ duleˇ ˚ zitych ´ oper´atoru˚ bude vysvˇetlena pozdˇeji pˇri popisu kompilaˇcn´ıch pravidel.
3.3
Kompilaˇcn´ı pravidla
Tato podkapitola je vˇenov´ana problematice, jak seskl´adat strom oper´atoru˚ tak, aby jeho vyhodnocen´ı vedlo ke korektn´ımu vysledku. Nejprve budou pops´any element´arn´ı kompilaˇcn´ı kroky, na ´ nichˇz bude ilustrov´ana funkˇcnost jednoduchych ´ oper´atoru. ˚ Pozdˇeji pak bude rozebr´an pˇreklad sloˇzitˇejˇs´ıch konstrukc´ı – FLWOR a XPath vyraz u. ´ ˚ Pro form´aln´ı popis s´emantiky kompilaˇcn´ıch pravidel bude pouˇzita n´asleduj´ıc´ı notace: · · · JexprKcontextOp ⇒ Opout
Tato notace pˇredstavuje pˇreklad vyrazu expr na strom oper´atoru˚ s koˇrenem Opout v kontextu ´ oper´atoru contextOp (pozor, nepl´est s kontextovou hodnotou) podle pravidel uvedenych nad ´ cˇ arou. Kontextovy´ oper´ator contextOp se pouˇz´ıv´a pouze pˇri popisov´an´ı kompilace FLWOR a XPath vyraz u. y´ oper´ator ´ ˚ Kompilace tˇechto konstrukc´ı je rozdˇelena na nˇekolik cˇ a´ st´ı, kde vysledn ´ pˇrekladu jedn´e cˇ a´ sti vstupuje jako kontextovy´ oper´ator do pˇrekladu cˇ a´ sti n´asleduj´ıc´ı. Pravidla nad cˇ arou jsou dvoj´ıho typu. Z´apis expr ⇒ Op znamen´a d´ılˇc´ı pˇreklad vyrazu expr na ´ oper´ator Op. O tom, jak´a kompilaˇcn´ı pravidla se pouˇzij´ı rozhodne aˇz konkr´etn´ı podoba vyrazu ´ expr. Druhym ´ pravidlem je prost´e pˇriˇrazen´ı ve tvaru Op = (rozklad na oper´atory). Jedn´a se o d´ale nedˇelitelny´ kompilaˇcn´ı krok, ktery´ pˇredstavuje konstrukci podstromu oper´atoru˚ podle prav´e strany a pˇriˇrazen´ı do oper´atoru na lev´e stranˇe. 13
Oper´atory pracuj´ıc´ı nad poloˇzkami Sequence(S1 , S2 , . . . , Sn ) Empty() Scalar[a]() Element[q](Sin ) Attribute[q](a) Text(a) Comment(a) TreeJoin[axis, nodetest](Sin ) Castable[type](a) Cast[type](ain ) TypeMatches[type](Sin ) Var[q] Call[q](S1 , S2 , . . . , Sn ) Cond{Sa , Sb }(boolean) Or{b1 , b2 , . . . , bn }() And{b1 , b2 , . . . , bn }() Oper´atory pracuj´ıc´ı nad n-ticemi Konstrukce n-tice Tuple[q1 , . . . , qn ](S1 , . . . , Sn ) Spojen´ı n-tice TupleConcat(τ1 , τ2 ) Pˇr´ıstup ke sloˇzce TupleAccess[q](τ) Selekce Select{boolean}(σin ) Kart´ezsky´ souˇcin Product(σ1 , σ2 ) Spojen´ı Join{boolean}(σ1 , σ2 ) Z´avisl´e spojen´ı MapConcat{boolean}(σ1 , σ2 ) Mapov´an´ı indexu MapIndex[q](σin ) Tˇr´ıdˇen´ı OrderBy[q1 , . . . , qn , mod1 , . . . , modn ](σin ) Hybridn´ı oper´atory Pˇrevod sekvence na tabulku MapFromItem{τ}(Sin ) Pˇrevod tabulky na sekvenci MapToItem{i}(σin ) Existenˇcn´ı kvantifik´ator MapSome{boolean}(Sin ) Vˇseobecny´ kvantifik´ator MapEvery{boolean}(Sin ) Speci´aln´ı oper´atory Navr´acen´ı kontextu IN() Sekvence Pr´azdn´a sekvence Skal´arn´ı hodnota XML element XML atribut XML text XML koment´arˇ Tree join Test pˇretypovatelnosti Pˇretypov´an´ı Kontrola datov´eho typu Pˇr´ıstup k promˇenn´e Vol´an´ı funkce Alternativa Logicky´ souˇcet Logicky´ souˇcin
Tabulka 1: Oper´atory algebry
14
→ → → → → → → → → → → → → → → →
Sout Sout a element q {Sin } attribute q {a} text q {a} comment q {a} Sout boolean aout boolean a Sout Sout boolean boolean
→ → → → → → → → →
[q1 : S1 , . . . , qn : Sn ] τout iout σout σout σout σout σout σout
→ → → →
σout Sout boolean boolean
→
τout nebo ıout
Pravidla jsou aplikov´ana pˇresnˇe v takov´em poˇrad´ı, jak jdou za sebou. Je potˇreba si uvˇedomit, zˇ e prov´ad´ıme kompilaci, ne vyhodnocov´an´ı. To znamen´a, zˇ e vypoˇ ´ cet teprve pˇripravujeme, ale neprov´ad´ıme. 3.3.1
Kompilace element´arn´ıch konstrukc´ı
Poloˇzka Opout = Scalar[a] a ⇒ Opout Vysledkem kompilace je vˇzdy strom oper´atoru. ´ ˚ Jak jiˇz bylo uvedeno, v tomto stromu se nikdy ani na stranˇe z´avislych, ani na stranˇe nez´avislych ´ ´ oper´atoru˚ nevyskytuje skal´arn´ı hodnota. Jakoukoli skal´arn´ı hodnotu je potˇreba nejprve zkonstruovat oper´atorem Scalar, kter´emu skuteˇcnou poˇzadovanou hodnotu pˇred´ame jako staticky´ parametr. Promˇenn´a Opout = Var[v] $v ⇒ Opout Pˇr´ıstup k promˇenn´e v jednoduˇse kompilujeme na oper´ator Var[v]. Jak bude ale pozdˇeji vysvˇetleno, prakticky se bude tento oper´ator vˇzdy nahrazovat pˇr´ıstupem k v sloˇzce kontextov´e n-tice. Sekvence
Opout
expr1 ⇒ Op1 .. . exprn ⇒ Opn = Sequence(Op1 , . . . , Opn )
(expr1 , . . . , exprn ) ⇒ Opout Jednotliv´e vyrazy expr1 , . . . , exprn nemus´ı ve vysledku d´avat pouze poloˇzky. Vˇsechny d´ılˇc´ı ´ ´ sekvence spoj´ı oper´ator Sequence do jedn´e vysledn´ e (viz obr´azek 3). Znamen´a to, zˇ e napˇr´ıklad ´ z´apis (1,(2,3),(4,(5,6))) znamen´a tot´ezˇ co (1,2,3,4,5,6). Datovy´ model neumoˇznuje, ˇ aby poloˇzka obsahovala vnoˇrenou sekvenci. Funkce
Opout
arg1 ⇒ Op1 .. . argn ⇒ Opn = Call[ f ](Op1 , . . . , Opn )
f (arg1 , . . . , argn ) ⇒ Opout Pˇri kompilaci pˇrech´az´ı vol´an´ı funkce pˇrirozenˇe na oper´ator Call. Tento oper´ator m´a statickym ´ parametrem urˇcen n´azev funkce f a obecnˇe n nez´avislych ´ vstupu˚ urˇcuje hodnoty argumentu. ˚
15
(1, 2, 3, 4, 5, 6)
ܵ݁݁ܿ݊݁ݑݍଵ
݈ܵܿܽܽݎሾ1ሿ
(2, 3)
ܵ݁݁ܿ݊݁ݑݍଶ
݈ܵܿܽܽݎሾ2ሿ
ܵ݁݁ܿ݊݁ݑݍଷ
݈ܵܿܽܽݎሾ4ሿ
݈ܵܿܽܽݎሾ3ሿ
(4, 5, 6)
ܵ݁݁ܿ݊݁ݑݍସ
݈ܵܿܽܽݎሾ5ሿ
(5, 6)
݈ܵܿܽܽݎሾ6ሿ
Obr´azek 3: Kompilace sekvence Aritmetick´e vyrazy ´ Do t´eto chv´ıle moˇzn´a nemus´ı byt e jasn´e, kam se vlastnˇe podˇely aritmetick´e oper´atory. V ta´ uplnˇ ´ bulce 1 byly nadefinov´any nejruznˇ ˚ ejˇs´ı speci´aln´ı oper´atory, ale zˇ a´ dn´e z nich nepˇripom´ınaj´ı napˇr. oper´ator souˇctu, rozd´ılu atd. Urˇcitˇe to nen´ı t´ım, zˇ e by snad XQuery takov´e vyrazy nepodporoval. ´ Maly´ trik spoˇc´ıv´a v tom, zˇ e lze veˇsker´e tyto operace nahradit vol´an´ım vestavˇenych ´ funkc´ı. Pˇri kompilaci souˇctu, rozd´ılu, souˇcinu, pod´ılu nebo operace modulo se tedy jednoduˇse zavolaj´ı dvouparametrov´e funkce add, sub, mul, div nebo mod. O nahrazen´ı aritmetickych ´ oper´atoru˚ vol´an´ım vestavˇenych ´ funkc´ı se bˇezˇ nˇe star´a normalizace (viz kapitola 2.3.3) – XQuery Core skuteˇcnˇe aritmetick´e vyrazy nepodporuje. ´ Konkr´etnˇe napˇr. pro operaci souˇctu bude pˇreklad vypadat takto:
Opout
expra ⇒ Opa exprb ⇒ Opb = Call[add](Opa , Opb )
expra + exprb ⇒ Opout Lev´a i prav´a strana souˇctu bude pˇreloˇzena na pomocn´e oper´atory Opa a Opb , kter´e pak nastav´ıme na vstup oper´atoru Call se staticky danym ´ n´azvem funkce add. Un´arn´ı minus lze jednoduˇse zkompilovat stejnˇe jako bin´arn´ı variantu s t´ım, zˇ e na lev´e stranˇe bude 0 (po kompilaci na oper´ator Scalar). Vyrazy porovn´av´an´ı ´ XQuery jazyk rozliˇsuje celkem 4 typy porovn´av´an´ı – obecn´e porovn´an´ı, hodnotov´e porovn´an´ı, porovn´an´ı Xml uzlu a porovn´an´ı poˇrad´ı Xml uzlu. Nejˇcastˇeji je moˇzn´e setkat se s obecnym ´ porovn´an´ım, kde srovn´av´ame obsah dvou sekvenc´ı S1 a S2 . Jde o standardn´ı z´apis symbolu˚ =, !=, <, >, <= a >=, kter´e se pˇri kompilaci pˇreloˇz´ı na vol´an´ı dvouargumentovych ´ funkc´ı eq, neq, lt, gt, le a ge. Tyto funkce vracej´ı pravdivou booleovskou hodnotu za pˇredpokladu, zˇ e zadan´a rovnost nebo nerovnost vyhov´ı pro alesponˇ jednu dvojici poloˇzek i1 ∈ S1 a i2 ∈ S2 . Ve vˇetˇsinˇe pˇr´ıpadu˚ pouˇzit´ı jsou S1 a S2 jednoprvkov´e. Druhym e ´ typem porovn´an´ı je tzv. hodnotov´e, kdy nesrovn´av´ame dvˇe sekvence, ale vyhradnˇ ´ 16
dvˇe poloˇzky. Pro tato porovn´an´ı m´a XQuery speci´aln´ı kl´ıcˇ ov´a slova eq, neq, lt, gt, le a ge, kter´e se pouˇz´ıvaj´ı naprosto stejnˇe jako standardn´ı symboly u obecn´eho porovn´an´ı. Pˇri kompilaci se hodnotov´e porovn´an´ı pˇreloˇz´ı na vol´an´ı funkc´ı veq, vneq, vlt, vgt, vle a vge. Dalˇs´ı dva uveden´e typy porovn´an´ı nejsou v t´eto pr´aci implementov´any, avˇsak jejich pˇreklad by probˇehl velice podobnˇe opˇet na vol´an´ı funkc´ı. Logick´e vyrazy ´ Logick´e operace (logicky´ souˇcin a souˇcet) by sice bylo moˇzn´e podobnym pˇrepsat na ´ zpusobem ˚ funkce and a or, nicm´enˇe pˇriˇsli bychom tak o podstatnou vyhodu moˇznosti l´ın´eho vyhodno´ cov´an´ı. Pˇri zpracov´av´an´ı oper´atoru Call se chtˇe nechtˇe nejprve mus´ı vyhodnotit vˇsechny vstupy, coˇz je u logickych u˚ obvykle zbyteˇcn´e. Proto zde pˇreci jen pouˇzijeme speci´aln´ı oper´atory ´ vyraz ´ Or a And, kter´e jednotliv´e vstupy vyhodnocuj´ı postupnˇe. Jakmile logicky´ souˇcet naraz´ı na ,,true“ nebo logicky´ souˇcin na ,,false“, dojde k okamˇzit´emu navr´acen´ı vysledku. ´
Opout
arg1 ⇒ Op1 .. . argn ⇒ Opn = And{Op1 , . . . , Opn }()
Opout
arg1 and . . . and argn ⇒ Opout
arg1 ⇒ Op1 .. . argn ⇒ Opn = Or{Op1 , . . . , Opn }()
arg1 or . . . or argn ⇒ Opout
XML konstruktory Jak bylo v kapitole 2.3.2 uvedeno, v dotazech XQuery muˇ ˚ zeme pomoc´ı pˇr´ımych ´ nebo nepˇr´ımych ´ konstruktoru˚ vytv´arˇ et vlastn´ı XML uzly. Na obr´azek 4 lze pohl´ızˇ et dvˇema zpusoby – bud’ jako na sestaven´ı stromu oper´atoru˚ podle ˚ vstupn´ıho dotazu nebo jako na vysledek vyhodnocen´ı uveden´eho stromu. Jelikoˇz v dotazu nejsou ´ pouˇzit´e zˇ a´ dn´e charakteristick´e konstrukce pro XQuery, bude vyhodnocov´an´ı spoˇc´ıvat pouze v parsov´an´ı XML na DOM a zpˇetn´e serializaci DOM na textovy´ rˇ etˇezec. Ukázkový XML Text
Odpovídající strom operátorů
𝐸𝑙𝑒𝑚𝑒𝑛𝑡[a]
𝑆𝑒𝑞𝑢𝑒𝑛𝑐𝑒
𝐴𝑡𝑡𝑟𝑖𝑏𝑢𝑡𝑒[id]
𝑆𝑐𝑎𝑙𝑎𝑟[1]
𝐶𝑜𝑚𝑚𝑒𝑛𝑡
𝐸𝑙𝑒𝑚𝑒𝑛𝑡[b]
𝑆𝑐𝑎𝑙𝑎𝑟[Komentář]
𝐴𝑡𝑡𝑟𝑖𝑏𝑢𝑡𝑒[id]
𝐴𝑡𝑡𝑟𝑖𝑏𝑢𝑡𝑒[id]
𝑆𝑐𝑎𝑙𝑎𝑟[1]
𝑆𝑐𝑎𝑙𝑎𝑟[2]
Obr´azek 4: Kompilace XML
17
𝐸𝑙𝑒𝑚𝑒𝑛𝑡[b]
𝑇𝑒𝑥𝑡
𝑆𝑐𝑎𝑙𝑎𝑟[Text]
3.3.2
FLWOR vyrazy ´
Kompilaˇcn´ı pravidla budou aplikov´ana postupnˇe pˇresnˇe v takov´em poˇrad´ı, v jak´em jdou za sebou jednotliv´e klauzule. Gramatika XQuery umoˇznuje nˇekolikr´at zopakovat klauzuli for a ˇ let v libovoln´em poˇrad´ı, n´asleduje nepovinn´a omezuj´ıc´ı podm´ınka where, nepovinn´e setˇr´ızen´ı order by a povinn´a klauzule return. Cely´ FLWOR vyraz bude zpracov´av´an pomoc´ı oper´atoru˚ ´ pracuj´ıc´ıch nad tabulkami, pouze v pˇr´ıpadˇe vstupn´ıho vyrazu nebo vypoˇ potˇrebovat ´ ´ ctu vysledku ´ ony tzv. hybridn´ı oper´atory. Pravidla pro pˇreklad jsou s malymi upravami pˇrevzata z [16]. ´ ´ for Bude iterov´ana promˇenn´a x pˇres vstupn´ı sekvenci poloˇzek danou vyrazem expr. Vstupn´ı sekvence ´ poloˇzek muˇ vnoˇren´eho XPath ˚ ze byt ´ staticky zad´ana nebo muˇ ˚ ze vych´azet napˇr´ıklad z vysledku ´ nebo FLWOR vyrazu. ´ expr ⇒ Op1 Jas TKOp1 ⇒ Op1 Op2 = MapFromItem{Tuple[x](IN)}(Op1 ) Op2 = MapIndex[pos](Op2 ) Op3 = MapConcat{Op2 }(Op0 ) JclausesKOp3 ⇒ Opout
Jfor $x [as T] [at $pos] in expr clausesKOp0 ⇒ Opout V prvn´ım kroku je zkompilov´an vyraz expr na pomocny´ oper´ator Op1 . Nejedn´a se samozˇrejmˇe ´ o jeden oper´ator, ale o cely´ podstrom s koˇrenem Op1 . Druhy´ krok je nepovinny. ´ Prov´ad´ı se v pˇr´ıpadˇe nutnosti oˇsetˇren´ı datov´eho typu vstupn´ı sekvence. Klauzuli as tato implementace kvuli ˚ zjednoduˇsen´emu typov´emu syst´emu nepodporuje (viz kapitola 4.4.1). Ve tˇret´ım kroku je proveden pˇrechod od sekvence poloˇzek k jednoatributov´e tabulce, tzn. ˇ k tabulce obsahuj´ıc´ı n-tice s jedinou sloˇzkou x. Ctvrt y´ krok je opˇet nepovinny. ´ Z´aleˇz´ı na tom, zda hodl´ame vyuˇz´ıt moˇznosti poziˇcn´ı promˇenn´e at $pos. Pokud ano, pak oper´atorem MapIndex do vznikaj´ıc´ı tabulky jednoduˇse pˇrid´ame sloˇzku pos s celoˇc´ıselnou hodnotou v rozmez´ı {1..|expr|}, tzn. zajist´ıme oˇc´ıslov´an´ı jednotlivych ´ n-tic. V z´apise kompilaˇcn´ıho pravidla je v tomto kroku pˇr´ıpadnˇe pˇreps´an pomocny´ oper´ator Op2 . P´aty´ krok vyuˇz´ıv´a oper´ator MapConcat. Ten zajist´ı, zˇ e prozat´ım pˇripraveny´ vypoˇ ´ cet v oper´atoru Op2 bude proveden pro kaˇzdou n-tici z vysledku oper´atoru, ktery´ vznikl kompi´ lac´ı pˇredchoz´ı for nebo let klauzule. Princip cˇ innosti MapConcat je vysvˇetlen n´ızˇ e. Posledn´ı krok pˇrekladu for nepˇredstavuje nic jin´eho, neˇz zpracov´an´ı zbytku FLWOR vyrazu ´ s t´ım, zˇ e oper´ator Op3 bude dalˇs´ımu kroku pˇred´an jako kontextovy. ´ Je zde jedna drobn´a komplikace, na kterou nesm´ıme zapomenout. Ve zpracov´an´ı zbytku FLWOR vyrazu mus´ı byt ´ ´ jakykoli ´ pˇr´ıstup k promˇenn´e x kompilov´an ne na oper´ator Var[x], ale na TupleAccess[x](IN), tj. pˇr´ıstup ke sloˇzce x kontextov´e n-tice. Stejn´e pravidlo bude pˇr´ıpadnˇe platit tak´e pro poziˇcn´ı promˇennou pos. Substituce prob´ıh´a z toho duvodu, zˇ e ve skuteˇcnosti neexistuje zˇ a´ dn´a pamˇet’ov´a struktura, kter´a ˚ by si pamatovala hodnoty promˇennych ´ samostatnˇe. Vˇsechny hodnoty jsou obsaˇzeny ve vznikaj´ıc´ı tabulce n-tic. Oper´ator MapConcat muˇ ˚ ze byt ´ obt´ızˇ nˇejˇs´ı na spr´avn´e pochopen´ı. Na obr´azku 5 je zn´azornˇen princip jeho cˇ innosti. Tento oper´ator pˇreb´ır´a nez´avislym ´ vstupem tabulku. Pro kaˇzdou n-tici ze 18
vstupn´ı tabulky vyhodnot´ı z´avisly´ oper´ator, ktery´ v tomto pˇr´ıpadˇe produkuje dalˇs´ı tabulku o 2 ntic´ıch. N-tice ze vstupn´ı tabulky je ve vypoˇ ´ ctu z´avisl´eho suboper´atoru dostupn´a v kontextu. Z´apis #a je zkr´acen´ım pˇr´ıstupu ke sloˇzce a kontextov´e n-tice. Z uk´azky je patrn´e, zˇ e cˇ innost MapConcat je velmi podobn´a kart´ezsk´emu souˇcinu (oper´ator Product), obsah prav´e pˇripojovan´e tabulky vˇsak z´avis´ı na obsahu lev´e nez´avisl´e tabulky. 𝐚 1 1 2 2 3 3
𝐛 4 4 5 5 6 6
𝐜 5 4 7 10 9 18
𝑀𝑎𝑝𝐶𝑜𝑛𝑐𝑎𝑡
𝐜 #𝑎 + #𝑏 #𝑎 ∙ #𝑏
𝐚 1 2 3
𝐛 4 5 6
ˇ Obr´azek 5: Cinnost oper´atoru MapConcat
let ´ Klauzule let zav´ad´ı do FLWOR vyrazu z´avislou promˇennou y. Ukolem oper´atoru˚ je v tomto ´ pˇr´ıpadˇe pˇridat do vznikaj´ıc´ı tabulky sloˇzku y s hodnotou vypoˇctenou podle expr. expr ⇒ Op1 Jas TKOp1 ⇒ Op1 Op2 = MapConcat{Tuple[y](Op1 )}(Op0 ) JclausesKOp3 ⇒ Opout
Jlet $y [as T] := expr clausesKOp0 ⇒ Opout V prvn´ım kroku je pˇreloˇzen vyraz expr do oper´atoru Op1 . Druhy´ krok opˇet pˇredstavuje oˇsetˇren´ı ´ datov´eho typu, kterym nebudeme. Pomoc´ı MapConcat dojde k pˇripojen´ı jednosloˇzkov´e ´ se zabyvat ´ n-tice [y : expr] k tabulce vznikl´e vyhodnocen´ım kontextov´eho oper´atoru Op0 , tzn. tabulce, kter´a je vysledkem vˇsech pˇredchoz´ıch klauzul´ı for a let pˇrekl´adan´eho FLWOR vyrazu. Nakonec opˇet ´ ´ pokraˇcujeme zpracov´an´ım zbytku, kde stejnˇe jako v pˇr´ıpadˇe for budeme nahrazovat jakykoli ´ vyskyt promˇenn´e y pˇr´ıstupem ke sloˇzce y kontextov´e n-tice. ´ V cˇ em se tedy z´asadnˇe liˇs´ı zpracov´an´ı klauzul´ı for a let? Rozd´ıl je ve zpracov´an´ı vstupn´ıho vyrazu expr. Zat´ımco u for pˇrev´ad´ıme sekvenci danou expr na tabulku s n-ticemi obsahuj´ıc´ımi ´ jednotliv´e d´ılˇc´ı poloˇzky sekvence, u klauzule let nech´av´ame sekvenci v celku a tvoˇr´ıme jedinou n-tici se sloˇzkou y, kter´a tuto sekvenci obsahuje. Z klauzule let je patrn´e, proˇc datovy´ model umoˇznuje sloˇzk´am n-tic obsahovat cel´e sekvence. ˇ 19
where Zat´ımco pˇredchoz´ı for a let slouˇzily k vytvoˇren´ı tabulky, where bude vzniklou tabulku podle dan´e podm´ınky pouze redukovat. Z´akladem zpracov´an´ı t´eto klauzule je vˇseobecnˇe zn´amy´ oper´ator relaˇcn´ı algebry Select. expr ⇒ Op1 Op2 = Select{Op1 }(Op0 ) JclausesKOp2 ⇒ Opout
Jwhere expr clausesKOp0 ⇒ Opout Vyraz expr je tedy zkompilov´an na pomocny´ oper´ator Op1 . Kontextovy´ oper´ator Op0 , cˇ ili ten, ´ ktery´ produkuje tabulku podle pˇredchoz´ıch let a for, bude slouˇzit jako nez´avisly´ vstup do oper´atoru Select, z´avislym ´ vstupem selekce bude podm´ınka zkompilovan´a v Op1 . Pokraˇcujeme dalˇs´ı klauzul´ı a jelikoˇz nedoˇslo k zˇ a´ dn´emu zav´adˇen´ı promˇenn´e, nen´ı potˇreba oˇsetˇrovat substituci. order by expr1 ⇒ Op1 .. . exprn ⇒ Opn Op0 = MapConcat{Tuple[o1 , . . . , on ](Op1 , . . . , Opn )}(Op0 ) Op0 = OrderBy[o1 , . . . , on , modi f ier1 , . . . , modi f iern ](Op0 ) JclausesKOp0 ⇒ Opout
Jorder by expr1 modi f ier1 , . . . , exprn modi f iern KOp0 ⇒ Opout
Nejprve budou zkompilov´any vˇsechny vyrazy expr1 . . . exprn , podle kterych ´ ´ budeme prov´adˇet tˇr´ıdˇen´ı, na oper´atory Op1 . . . Opn . Pot´e dojde k pˇripojen´ı n-tic se sloˇzkami jednotlivych ´ vypoˇctenych ´ vyraz u˚ k vysledku Op0 . Teprve pak je moˇzn´e aplikovat oper´ator OrderBy, kter´emu staticky ´ ´ nadefinujeme, podle kterych sloˇzek n-tic v tabulce m´a tˇr´ıdit a jakym zpusobem, tzn. vze´ ´ ˚ stupnˇe (ascending), sestupnˇe (descending), popˇr. jak m´a byt ´ tˇr´ıdˇena pr´azdn´a sekvence (empty least nebo empty greatest). Opˇet pokraˇcujeme zpracov´av´an´ım zbytku FLWOR vyrazu, kterym ´ ´ je v tuto chv´ıli jistˇe pouze klauzule return. Drobnou komplikac´ı je pouze to, zˇ e zde do tabulky mapujeme sloˇzky n-tic o1 , . . . , on , o kter´e si s´am uˇzivatel neˇza´ dal. Je potˇreba d´at pozor, abychom se nevhodnou volbou pojmenov´an´ı sloˇzky n-tice, nedostali do konfliktu s nˇejakou uˇzivatelem definovanou promˇennou. return expr ⇒ Op1 Opout = MapToItem{Op1 }(Op0 ) Jreturn exprKOp0 ⇒ Opout Posledn´ı krok pˇrekladu FLWOR je v celku jednoduchy. ´ Nejprve dojde ke kompilaci vyrazu, ´ ktery´ pˇredstavuje vypoˇ Pomoc´ı oper´atoru MapToItem je zajiˇstˇeno, ´ cet jedn´e d´ılˇc´ı poloˇzky vysledku. ´ zˇ e tento vyraz bude vyhodnocen pro kaˇzdou n-tici z vysledku kontextov´eho oper´atoru Op0 . ´ ´ Vˇsechny d´ılˇc´ı vysledky nakonec utvoˇr´ı vyslednou sekvenci. ´ ´
20
Na obr´azku 6 je v blokov´em sch´ematu shrnuto, jakym prob´ıh´a pˇreklad jednotlivych ´ zpusobem ˚ ´ klauzul´ı podle vyˇ pravidel. Pro zjednoduˇsen´ı je vynech´ana klauzule order by. ´ se uvedenych ´ Bˇehem cel´e kompilace FLWOR se pracuje s promˇennou kontextov´eho oper´atoru. Kaˇzd´a klauzule tuto promˇennou zaobal´ı jinym ´ oper´atorem nebo v´ıce oper´atory. let
for MapConcat { MapFromItem { CreateTuple[var](IN) } ( expandExpr výrazu ) } (
where
MapConcat { CreateTuple[var] ( expandExpr výrazu ) } (
return
Select { expandExpr výrazu } (
MapToItem { expandExpr výrazu } (
)
)
)
IN() )
Obr´azek 6: Blokov´e sch´ema kompilace FLWOR N´asleduje souhrnn´a uk´azka, kter´a demonstruje vysledek vˇetˇsiny vyˇ ´ ´ se nadefinovanych ´ kompilaˇcn´ıch pravidel.
Pˇr´ıklad 2: Souhrnn´y pˇr´ıklad kompilace Pokusme se nyn´ı pˇreloˇzit n´asleduj´ıc´ı vyraz: ´ for $i in 1 to 10 let $j := $i * 2 where $j > 10 return $i
Bˇehem pˇrekladu bude postupnˇe vytv´arˇ en strom na obr´azku 7 n´ızˇ e. V tabulce 2 jsou uvedeny mezivysledky pˇri vykon´av´an´ı dotazu, kter´e se vztahuj´ı k vyznaˇcenym ´ ´ m´ıstum ˚ ve stromu oper´atoru. ˚ Pˇreklad for a rozsahov´eho vyrazu ´ Pˇreklad cel´eho vyrazu je zah´ajen kompilac´ı for. Nejprve je pˇreloˇzen vyraz 1 to 10 na vol´an´ı ´ ´ dvouparametrov´e funkce range(low, high). Jedn´a se o jednoduch´e kompilaˇcn´ı pravidlo pro pˇreklad rozsahu hodnot, kter´e zde dosud nebylo uvedeno. Funkce range vrac´ı sekvenci celych ´ cˇ ´ısel od definovan´e spodn´ı hodnoty podle parametru low po horn´ı hodnotu high s krokem 1. Mezivysledek po vyhodnocen´ı Call[range] je moˇzn´e vidˇet v tabulce 2 jako result2 . Oper´ator ´ MapFromItem v kombinaci s Tuple[i] zajist´ı, zˇ e bude vznikl´a sekvence transformov´ana na tabulku s n-ticemi o jedn´e sloˇzce i. Vysledek po MapFromItem je oznaˇcen jako result3 . ´ Cely´ dosavadn´ı mezivysledek byl poˇc´ıt´an v r´amci vyhodnocen´ı z´avisl´e cˇ a´ sti oper´atoru ´ MapConcat pro kaˇzdou n-tici z jeho nez´avisl´eho vstupu, ktery´ je moment´alnˇe tvoˇren IN. Tento IN se nevztahuje k zˇ a´ dn´emu z´avisl´emu vstupu jin´eho oper´atoru, ale k programov´e funkci, kter´a 21
cel´e vyhodnocov´an´ı zah´ajila (viz kapitola 3.2.3). Pro zjednoduˇsen´ı muˇ ˚ zeme pˇredpokl´adat, zˇ e tato funkce nastavila kontextovou n-tici jako pr´azdnou (result1 ). Vysledek oper´atoru MapConcat, ´ resp. cel´e klauzule for je uveden v result4 .
result7
𝑀𝑎𝑝𝑇𝑜𝐼𝑡𝑒𝑚
překlad return 𝑇𝑢𝑝𝑙𝑒[𝑖]
𝐼𝑁
result6
𝑆𝑒𝑙𝑒𝑐𝑡[𝑖]
překlad where
𝐶𝑎𝑙𝑙[𝑔𝑡] result5
𝑀𝑎𝑝𝐶𝑜𝑛𝑐𝑎𝑡
𝑇𝑢𝑝𝑙𝑒𝐴𝑐𝑐𝑒𝑠𝑠[𝑗]
𝑆𝑐𝑎𝑙𝑎𝑟[10]
překlad let 𝐼𝑁
result4
𝑀𝑎𝑝𝐶𝑜𝑛𝑐𝑎𝑡 𝑇𝑢𝑝𝑙𝑒[𝑗] result3
result1
𝐼𝑁
𝑀𝑎𝑝𝐹𝑟𝑜𝑚𝐼𝑡𝑒𝑚
𝐶𝑎𝑙𝑙[mul]
𝑇𝑢𝑝𝑙𝑒𝐴𝑐𝑐𝑒𝑠𝑠[𝑖]
result2
𝐶𝑎𝑙𝑙[𝑟𝑎𝑛𝑔𝑒]
𝑆𝑐𝑎𝑙𝑎𝑟[2]
𝑇𝑢𝑝𝑙𝑒[𝑖] 𝐼𝑁
𝑆𝑐𝑎𝑙𝑎𝑟[1]
𝑆𝑐𝑎𝑙𝑎𝑟[10]
𝐼𝑁
překlad for
Odkaz na závislý suboperátor Odkaz na nezávislý suboperátor
Obr´azek 7: Kompilace FLWOR result1 = [] i 1 result3 = 2 .. . 10
result2 = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) i
i
1 result4 = 2 .. . 10
1 result5 = 2 .. . 10
j 1 4 .. . 20
result7 = (6, 7, 8, 9, 10) Tabulka 2: Mezivysledky vyhodnocov´an´ı ´
22
i 6 7 result6 = 8 9 10
j 12 14 16 18 20
Pˇreklad let a aritmetick´eho vyrazu ´ N´asleduje pˇreklad klauzule let. Nejprve je pˇreloˇzen d´ılˇc´ı vyraz $i * 2. Podle pravidla ´ pro kompilaci aritmetick´eho vyrazu n´asoben´ı v kapitole 3.3.1 se tento vyraz pˇrekl´ad´a na ´ ´ vol´an´ı funkce mul. Prvn´ı cˇ initel je d´an promˇennou i, m´ısto oper´atoru pro pˇr´ıstup k promˇenn´e Var[i] se d´ıky substituci uplatn´ı oper´ator TupleAccess[i] nad kontextovou n-tic´ı. Druhy´ cˇ initel tvoˇr´ı oper´ator generuj´ıc´ı skal´arn´ı hodnotu Scalar[2]. Oper´ator MapConcat zajist´ı, zˇ e je tento pˇripraveny´ vypoˇ ´ cet spuˇstˇen nad kaˇzdou n-tic´ı z jeho nez´avisl´eho vstupu, ktery´ je tvoˇren vystupn´ ım oper´atorem z pˇrekladu pˇredchoz´ı klauzule for. Mezivysledek po vyhodnocen´ı ´ ´ MapConcat, cˇ ili cel´e klauzule let ukazuje opˇet tabulka 2, promˇenn´a result5 . Pˇreklad where s vyrazem pro porovn´av´an´ı ´ Porovn´an´ı > se podle odstavce 3.3.1 pˇrekl´ad´a na vol´an´ı funkce gt. Nez´avisly´ vstup selekce tvoˇr´ı vystup pˇredchoz´ı klauzule let. Vysledek po selekci ukazuje v tabulce mezivysledk u˚ promˇenn´a ´ ´ ´ result6 . return Posledn´ı klauzul´ı je return. Nejprve je zkompilov´an vyraz pro vypoˇ ´ ´ cet jedn´e d´ılˇc´ı poloˇzky. Jedn´a se pouze o pˇr´ıstup k promˇenn´e, ktery´ se vzhledem k substituci pˇrev´ad´ı na pˇr´ıstup do pˇr´ısluˇsn´e sloˇzky kontextov´e n-tice. MapConcat tento vypoˇ ´ cet spust´ı nad kaˇzdou n-tic´ı z tabulky vznikl´e pˇredchoz´ı klauzul´ı where. Vˇsechny vysledn´ e poloˇzky utvoˇr´ı sekvenci, kter´a je vystupem ´ ´ cel´eho dotazu, viz promˇenn´a result7 .
3.3.3
XPath vyrazy ´
Pokud by algebra pracovala pouze s XQuery core, pak by se kompilace XPath vyraz u˚ omezila ´ jen na zpracov´an´ı axis kroku, lze normalizac´ı pˇrev´est na FLWOR. ˚ jelikoˇz predik´aty a filter vyrazy ´ Pl´an dotazu lze ale sestavit rovnou z XPath v puvodn´ ı podobˇe. ˚ Gramatika povoluje pouˇz´ıv´an´ı zkratkovych ´ z´apisu˚ (viz kapitola 2.3.1). Zkr´acen´e z´apisy lze ale jednoduˇse rozepsat na plny´ tvar, takˇze se jim d´ale vˇenovat nebudeme. Podrobnˇejˇs´ı informace lze nal´ezt v [4]. Na obr´azku 8 je pˇr´ıklad XPath vyrazu s pouˇzit´ım zkratkovych ´ ´ z´apisu˚ a po rozeps´an´ı. Obr´azek d´ale zachycuje rozklad vyrazu na jednotliv´e kroky a predik´aty. ´ /library//book[@id = "10"]/author/(first/text() + last/text()) /child::library/descendant-or-self::node()/child::book[attribute::id = "10"]/child::author/ (child::first/child::text() + child::last/child::text())
axis krok child::library
axis krok
axis krok
descendant-or-self::node()
child::book
predikát attribute::id = “10“
axis krok child::author
Obr´azek 8: Struktura XPath vyrazu ´
23
filter výraz child::first/child::text() + child::last/child::text()
Stejnˇe jako v pˇr´ıpadˇe FLWOR prob´ıh´a kompilace XPath po cˇ a´ stech za pouˇzit´ı kontextov´eho oper´atoru. Zah´ajen´ı pˇrekladu 1. V pˇr´ıpadˇe, zˇ e se na zaˇca´ tku vyrazu nach´az´ı rovnou axis step, je kontextovy´ oper´ator inicia´ lizov´an na pˇr´ıstup k promˇenn´e Var[dot]. 2. Pokud je vyraz uvozen jednoduchym ´ ´ lom´ıtkem, zaˇc´ın´a vyhodnocov´an´ı od koˇrene XML dokumentu. Koˇren muˇ ˚ zeme snadno obdrˇzet vol´an´ım vestavˇen´e funkce Call[root](). 3. Jestliˇze se na zaˇca´ tku nach´az´ı dvojit´e lom´ıtko, je potˇreba naˇc´ıst XML dokument a rovnou z nˇej vybrat vˇsechny potomky pomoc´ı TreeJoin[descendant-or-self, node()](Call[root]()). Axis kroky Opout = TreeJoin[axis, nodetest](Op0 ) Jaxis :: nodetestKOp0 ⇒ Opout Kompilace axis step je pˇr´ımoˇcar´a. Staˇc´ı pouze aplikovat oper´ator TreeJoin, ktery´ je pro tento uˇ ´ cel v podstatˇe urˇceny. ´ Oper´ator TreeJoin pracuje tak, zˇ e pro kaˇzdy´ XML uzel ze vstupn´ı sekvence provede poˇzadovany´ pohyb po dan´e ose (axis), cˇ ´ımˇz vznikne mezivysledek obsa´ huj´ıc´ı mnoˇzinu XML uzlu. jsou nakumulov´any do celkov´e vysledn´ e ˚ Vˇsechny mezivysledky ´ ´ (uspoˇra´ dan´e) mnoˇziny, pˇriˇcemˇz poˇrad´ı uzlu˚ mus´ı byt ım dokumentu ´ takov´e, jako bylo v puvodn´ ˚ a mus´ı byt Eliminace duplicit je nutn´a z duvodu v´ıce n´asleduj´ıc´ıch ´ eliminov´any duplicitn´ı vyskyty. ´ ˚ axis kroku, e mnoˇzinˇe ˚ kdy by mohlo doj´ıt k situaci, zˇ e se jeden konkr´etn´ı uzel vyskytne ve vysledn´ ´ dvakr´at. Kromˇe toho je provedena filtrace vystupn´ ı mnoˇziny na z´akladˇe dan´eho testu uzlu (staticky´ ´ argument oper´atoru – nodetest). Jedn´a se nejˇcastˇeji o jmenny´ test elementu. Existuje ale cel´a rˇ ada testu˚ – testy na atributy, textov´e uzly, koment´arˇ e, na libovolny´ uzel a dalˇs´ı. ˇ Cinnost oper´atoru TreeJoin byv´ ´ a nazyv´ ´ ana jako navigace. Filter vyrazy ´ f ilterExpr ⇒ Op1 Op2 = MapFromItem{Tuple[dot](IN)}(Op0 ) Op3 = MapConcat{Op2 }(IN) Opo ut = MapToItem{Op1 }(Op3 ) J f ilterExprKOp0 ⇒ Opout Nejprve je zkompilov´an samotny´ filter vyraz na pomocny´ oper´ator Op1 . Pot´e je zajiˇstˇeno ´ pˇreveden´ı vstupn´ı sekvence reprezentovan´e oper´atorem Op0 pomoc´ı MapFromItem na tabulku, kter´a je n´aslednˇe pˇrimapov´ana pomoc´ı MapConcat k aktu´aln´ı kontextov´e n-tici. Kontextov´a ntice totiˇz muˇ FLWOR. Nakonec je ˚ ze obsahovat nˇejak´e platn´e promˇenn´e napˇr. vnˇejˇs´ıho vyrazu ´ aplikov´an oper´ator MapToItem. Ten postupnˇe nad n-ticemi v tabulce jednak provede samotny´ vypoˇ ktery´ je v tuto chv´ıli zkompilovany´ v Op1 , a jednak provede pˇreveden´ı zpˇet ´ cet filter vyrazu, ´ na sekvenci poloˇzek.
24
Predik´aty ´ V pˇr´ıpadˇe kompilace predik´atu˚ algebra opˇet vyuˇzije oper´atory pracuj´ıc´ı v prostoru n-tic. Uplnˇ e stejnˇe jako u filter vyraz u˚ bude i zde potˇreba zajistit dostupnost kontextov´eho uzlu a vˇsech ´ aktu´alnˇe platnych ´ promˇennych ´ dvojic´ı oper´atoru˚ MapFromItem a MapConcat. Pot´e jednoduˇse vybereme vyhovuj´ıc´ı z´aznamy oper´atorem Select a provedeme pˇrechod zpˇet od tabulky k sekvenci. Jedinou vyraznˇ ejˇs´ı komplikac´ı je, zˇ e se v predik´atu nemus´ı nutnˇe nach´azet ´ pouze logicky´ vyraz. Specifikace XPath totiˇz umoˇznuje, aby typ vnitˇrn´ıho vysledku predik´atu byl ´ ˇ ´ kromˇe logick´eho vyrazu tak´e cel´e cˇ ´ıslo nebo sekvence. ´ Je-li vnitˇrn´ım mezivysledkem cel´e cˇ ´ıslo, pak toto cˇ ´ıslo pˇredstavuje poˇrad´ı jedin´eho uzlu ze ´ vstupn´ı sekvence, ktery´ bude propuˇstˇen d´ale. Jinak rozhodne tzv. efektivn´ı booleovsk´a hodnota sekvence, pro jej´ızˇ vypoˇ ´ cet plat´ı n´asleduj´ıc´ı pravidla: 1. Obsahuje-li sekvence jedinou poloˇzku typu boolean, pak efektivn´ı booleovsk´a hodnota je d´ana hodnotou t´eto poloˇzky. 2. Obsahuje-li sekvence jedinou poloˇzku typu integer nebo double, nabyv´ ´ a efektivn´ı booleovsk´a hodnota pravdy pr´avˇe kdyˇz dan´e cˇ ´ıslo nen´ı nulov´e. 3. Obsahuje-li sekvence jedinou poloˇzku typu string, je efektivn´ı booleovsk´a hodnota pravdiv´a v pˇr´ıpadˇe nepr´azdn´eho rˇ etˇezce. 4. V pˇr´ıpadˇe jak´ekoli obecn´e sekvence rozhodne o efektivn´ı booleovsk´e hodnotˇe jej´ı nepr´azdnost. Normalizace pˇrev´ad´ı predik´aty XPath na where klauzule FLWOR vyraz u, ´ ˚ pˇriˇcemˇz pro alternativu dle datovych je vˇsak relativnˇe ´ typu˚ vyuˇz´ıv´a konstrukci typeswitch. Tenhle zpusob ˚ komplikovany´ a pˇrid´av´a do cel´eho vyrazu zbyteˇcnˇe mnoho oper´atoru˚ nav´ıc. Pro celou logiku ´ vyhodnocen´ı pravdivostn´ı hodnoty pro mezivysledek predik´atu byla vytvoˇrena jednoduch´a ve´ stavˇen´a funkce predicate. predicateExpr ⇒ Op1 Op2 = MapFromItem{Tuple[dot](IN)}(Op0 ) Op3 = MapConcat{Op2 }(IN) Op4 = Select{Call[predicate](Op1 )}(Op3 ) Opout = MapToItem{TupleAccess[dot](IN)}(Op4 ) JpredicateExprKOp0 ⇒ Opout Kompilace tedy probˇehne z hlediska pˇrevodu mezi n-ticemi a poloˇzkami stejnˇe jako u filter vyraz u, ´ ˚ pouze dojde k omezen´ı tabulky oper´atorem Select, kde jeho z´avisl´a cˇ a´ st nevyhodnocuje oper´ator podm´ınky pˇr´ımo, ale aˇz na z´akladˇe vysledku funkce predicate. ´
Pˇr´ıklad 3: Pˇreklad XPath v´yrazu Nadefinovan´a kompilaˇcn´ı pravidla budou prezentov´ana na pˇr´ıkladu z obr´azku 8 vyˇ y´ ´ se. Vysledn ´ strom oper´atoru˚ na obr´azku 9 n´ızˇ e se vyznaˇcenymi m´ısty odkazuje na obr´azek 10, kde jsou ´ sch´ematicky zn´azornˇeny mezivysledky vybranych ´ ´ duleˇ ˚ zitych ´ oper´atoru. ˚ 25
/library//book[@id = “10“]/author/( first/text() +last/text()) result7
𝑀𝑎𝑝𝑇𝑜𝐼𝑡𝑒𝑚
result6
𝐶𝑎𝑙𝑙[add]
𝑀𝑎𝑝𝐶𝑜𝑛𝑐𝑎𝑡
𝐼𝑁
𝑇𝑟𝑒𝑒𝐽𝑜𝑖𝑛[child, text()]
𝑇𝑟𝑒𝑒𝐽𝑜𝑖𝑛[child, text()]
𝑇𝑟𝑒𝑒𝐽𝑜𝑖𝑛[child, first]
𝑇𝑟𝑒𝑒𝐽𝑜𝑖𝑛[child, last]
𝑇𝑢𝑝𝑙𝑒[dot]
𝑇𝑢𝑝𝑙𝑒𝐴𝑐𝑐𝑒𝑠𝑠[dot]
𝑇𝑢𝑝𝑙𝑒𝐴𝑐𝑐𝑒𝑠𝑠[dot]
𝐼𝑁
𝐼𝑁
𝐼𝑁
𝑀𝑎𝑝𝐹𝑟𝑜𝑚𝐼𝑡𝑒𝑚
first/text() +last/text() result5
𝑇𝑟𝑒𝑒𝐽𝑜𝑖𝑛 child; author /library//book[@id = “10“]/author
𝑀𝑎𝑝𝑇𝑜𝐼𝑡𝑒𝑚
/library//book[@id = “10“]
result4
𝑆𝑒𝑙𝑒𝑐𝑡 𝑇𝑢𝑝𝑙𝑒𝐴𝑐𝑐𝑒𝑠𝑠[dot] result3
𝑀𝑎𝑝𝐶𝑜𝑛𝑐𝑎𝑡 𝐼𝑁 result2
𝐼𝑁
𝑀𝑎𝑝𝐹𝑟𝑜𝑚𝐼𝑡𝑒𝑚
𝐶𝑎𝑙𝑙[predicate] 𝑇𝑢𝑝𝑙𝑒[dot]
𝐶𝑎𝑙𝑙[eq]
𝐼𝑁 𝑆𝑐𝑎𝑙𝑎𝑟["10"]
result1
𝑇𝑟𝑒𝑒𝐽𝑜𝑖𝑛[child; book] 𝑇𝑟𝑒𝑒𝐽𝑜𝑖𝑛 attribute; id 𝑇𝑟𝑒𝑒𝐽𝑜𝑖𝑛[descendant-or-self; node()] 𝑇𝑢𝑝𝑙𝑒𝐴𝑐𝑐𝑒𝑠𝑠[dot] 𝑇𝑟𝑒𝑒𝐽𝑜𝑖𝑛[child, library] 𝐼𝑁 𝐶𝑎𝑙𝑙[root]
.
/
@id
/library /library//book
Obr´azek 9: Pˇreklad uk´azkov´eho XPath vyrazu ´ 26
XML dokument
library section
section
book id = “7“
book id = “10“
author
book id = “15“
author
author
first
last
first
last
first
last
John
Smith
Peter
Black
Adam
White
result1
book id = “7“
book id = “10“
author
book id = “15“
author
first
last
first
last
first
last
John
Smith
Peter
Black
Adam
White
result2
result3
dot
result4
a
dot
book id = “7“
id = “7“
author
2
last
John
Smith
book
dot book id = “10“
author first
last
John
Smith
2
author first
last
Peter
Black
book id = “10“
author
2
first
last
Peter
Black
book id = “15“
a
book
first
id = “10“
author
result5
author first
last
Peter
Black
author first
last
Peter
Black
book id = “15“
author
2
first
last
Adam
White
result6
author first
last
Adam
White
result7
a
dot
(Peter Black)
author
2
first
last
Peter
Black
Značení XML elementu Značení XML atributu
Obr´azek 10: Mezivysledky uk´azkov´eho pˇrekladu XPath ´
27
/child::library/descendant-or-self::node()/child::book[attribute::id = "10"] /child::author/(child::first/child::text() + child::last/child::text())
Vyraz je uvozen jednoduchym ´ ´ lom´ıtkem, takˇze je potˇreba zajistit naˇcten´ı vstupn´ıho XML dokumentu vol´an´ım funkce root. Prvn´ım krokem je navigace na vˇsechny pˇr´ım´e potomky s n´azvem ,,library“. Jedn´a se o axis step, takˇze pouˇzijeme oper´ator TreeJoin. N´asleduje z´apis /descendant-or-self:node()/child:book (po rozeps´an´ı ze zkratkov´eho //book). Jde tedy o dvojity´ axis step, takˇze dvakr´at pouˇzijeme TreeJoin. Pˇri vyhodnocov´an´ı v tuto chv´ıli obdrˇz´ıme mezivysledek oznaˇceny´ jako result1 . ´ Dalˇs´ı cˇ a´ st´ı dotazu je predik´at. Vznikaj´ıc´ı sekvenci poloˇzek je tedy nutn´e pˇrev´est na tabulku s n-ticemi o jedn´e sloˇzce dot. O toto pˇreveden´ı se star´a oper´ator MapFromItem s konstruktorem n-tice (oper´atorem Tuple) v z´avisl´e cˇ a´ sti (viz mezivysledek result2 ). To vˇse probˇehne v r´amci ´ z´avisl´e vˇetve oper´atoru MapConcat, ktery´ zajist´ı, zˇ e v podm´ınce selekce budou dostupn´e kromˇe kontextov´eho uzlu tak´e vˇsechny promˇenn´e, kter´e nastavil napˇr. vnˇejˇs´ı vyraz FLWOR. Muˇ ´ ˚ zeme pˇredpokl´adat, zˇ e vnˇejˇs´ı kontextov´a n-tice obsahuje napˇr´ıklad sloˇzku a s hodnotou 2. N´asleduje proveden´ı selekce (result4 ) a n´avrat k toku datovych ´ poloˇzek oper´atorem MapToItem. Dalˇs´ım krokem je jiˇz nˇekolikr´at pˇrekl´adany´ axis step se jmennym ´ testem na n´azev uzlu ,,author“ a navigaci na osu child, takˇze opˇet jednoduˇse pouˇzijeme oper´ator TreeJoin. Posledn´ım krokem je filter vyraz. Zde je moˇzn´e opˇet pozorovat pˇrechod od sekvence poloˇzek ´ k tabulce pomoc´ı oper´atoru˚ MapFromItem, Tuple a MapConcat na stejn´em principu jako pˇri kompilaci predik´atu. Pro kaˇzdou n-tici pak probˇehne vypoˇ o coˇz se postar´a ´ cet filter vyrazu, ´ z´avisl´a vˇetev oper´atoru MapToItem. Vysledek dotazu je oznaˇceny´ jako result7 . Je zde pro zjed´ noduˇsen´ı drobn´a nepˇresnost. Pˇri spojov´an´ı kˇrestn´ıho jm´ena a pˇr´ıjmen´ı by se mezi obˇema cˇ a´ stmi samozˇrejmˇe mˇela nach´azet mezera.
3.3.4
Kompilace dalˇs´ıch konstrukc´ı
Byl pops´an pˇreklad nejpouˇz´ıvanˇejˇs´ıch konstrukc´ı XQuery. Mezi dalˇs´ı m´enˇe zn´am´e konstrukce paˇr´ı napˇr. jiˇz zminovan y´ typeswitch, ktery´ prov´ad´ı vˇetven´ı na z´akladˇe datov´eho typu. D´ale ˇ pak klasick´a alternativa, tzn. vˇetven´ı na z´akladˇe booleovsk´e hodnoty, vˇseobecn´e kvantifik´atory every, existenˇcn´ı kvantifik´atory some a dalˇs´ı. Kompilaˇcn´ı pravidla jsou pro tyto konstrukce vˇetˇsinou pˇr´ımoˇcar´a a vyuˇz´ıvaj´ı oper´atory pracuj´ıc´ı na n-ticemi. Jejich podrobny´ popis by byl pro uˇ ´ cely t´eto pr´ace zbyteˇcnˇe zdlouhavy. ´
3.4
Optimalizace
Vyˇ ´ se popsan´a pravidla pro kompilaci sice sestav´ı strom oper´atoru˚ tak, abychom po jeho evaluaci obdrˇzeli spr´avny´ vysledek, nicm´enˇe ne vˇzdy je vypoˇ ´ ´ cet efektivn´ı. Existuje cel´a rˇ ada pravidel, jak oper´atory pˇreskl´adat, aby vysledek zustal zachov´an, ale vypoˇ ´ ˚ ´ cet probˇehl rychleji. Bude pops´ano celkem 5 pravidel, z nichˇz prvn´ı dvˇe jsou specifick´a pro tuto pr´aci.
28
3.4.1
Odstranˇen´ı MapConcat
Tato optimalizace se tyk´ ´ a pˇredevˇs´ım cˇ a´ st´ı oper´atorov´eho stromu, kter´e vznikly kompilac´ı XPath vyraz u. napˇr. konstanta, pˇredstavuje z hlediska ´ ˚ Probl´emem je, zˇ e kaˇzdy´ byt’ element´arn´ı vyraz, ´ gramatiky jednoduchy´ XPath s jedn´ım filter vyrazem. Z toho vyplyv´ ´ ´ a nutnost namapovat vysledek ´ z pˇredchoz´ıho nebo poˇca´ teˇcn´ıho kroku na promˇennou dot. Na obr´azku 11 je zachycen strom oper´atoru˚ pro vyraz ,,1“. Jedn´a se o prakticky nepouˇzitelny´ ´ dotaz, nicm´enˇe z hlediska gramatiky XQuery je vˇse naprosto v poˇra´ dku. Uˇz na prvn´ı pohled je zˇrejm´e, zˇ e kompilaˇcn´ı pravidla byla v tuto chv´ıli zbyteˇcnˇe dusledn´ a a vygenerovala velk´e ˚ mnoˇzstv´ı pˇrebyteˇcnych ´ oper´atoru. ˚ Prvn´ı optimalizaˇcn´ı pravidlo, kter´e by n´as v tuto chv´ıli mohlo napadnout je odstranit cely´ MapToItem a zanechat pouze Scalar[1], jelikoˇz skal´arn´ı oper´ator nepˇristupuje ke kontextov´e n-tici, tzn. nez´avisly´ vstup vubec nepotˇrebuje. Tato uvaha ale nen´ı v poˇra´ dku, protoˇze kdyby nez´avisl´a ˚ ´ cˇ a´ st vyprodukovala v´ıce neˇz jednu n-tici, pak by vysledek nebyl spr´avny. ´ ´ Z´avisl´a cˇ a´ st se mus´ı prov´est pˇresnˇe tolikr´at, jaky´ je poˇcet n-tic z nez´avisl´eho oper´atoru. 𝑀𝑎𝑝𝑇𝑜𝐼𝑡𝑒𝑚
𝑀𝑎𝑝𝐶𝑜𝑛𝑐𝑎𝑡
𝐼𝑁
𝑆𝑐𝑎𝑙𝑎𝑟[1]
𝑀𝑎𝑝𝐹𝑟𝑜𝑚𝐼𝑡𝑒𝑚
𝑇𝑢𝑝𝑙𝑒𝐴𝑐𝑐𝑒𝑠𝑠 dot
𝑇𝑢𝑝𝑙𝑒 dot
𝐼𝑁
𝐼𝑁
Obr´azek 11: Kompilace skal´arn´ı hodnoty bez optimalizace Zkusme se nejprve zamˇerˇ it na cˇ innost suboper´atoru MapFromItem. V nez´avisl´em suboper´atoru pouze pˇristoup´ıme k nˇejak´e sloˇzce dot kontextov´e n-tice, obdrˇz´ıme tedy poloˇzku, kterou pˇred´ame z´avisl´emu vstupu, ktery´ z n´ı vytvoˇr´ı novou jednoprvkovou n-tici. Situace je ilustrov´ana na tabulce 3. Nalevo je obsah kontextov´e n-tice, ke kter´e pˇristupoval TupleAccess, napravo vysledek MapFromItem. ´ a
b
dot
1
2
−→
dot
Tabulka 3: Mezivysledek MapFromItem ´ N-tici, ke kter´e pˇristupoval TupleAccess nastavil jako kontextovou oper´ator MapConcat. Jej´ı obsah mus´ı byt ´ shodny´ s obsahem nˇejak´e vnˇejˇs´ı kontextov´e n-tice, kter´a shodou okolnost´ı utvoˇrila vstup tohoto oper´atoru. Vysledek MapConcat je uveden v tabulce 4. ´ 29
a
b
dot
dot
1
2
Tabulka 4: Mezivysledek MapConcat ´ N´azvy sloˇzek n-tic se sice dle definice nesm´ı opakovat, nicm´enˇe procesor si s duplicitn´ımi vyskyty porad´ı tak, zˇ e pˇristupuje vˇzdy k posledn´ımu z atributu˚ v poˇrad´ı pˇrid´av´an´ı. V tuto chv´ıli ´ je ale jasn´e, zˇ e doˇslo k pouh´emu zkop´ırov´an´ı jedn´e sloˇzky a to je z hlediska dalˇs´ıho vyhodnocov´an´ı zbyteˇcn´e. Pokud by nˇektery´ z oper´atoru˚ pozdˇeji potˇreboval pˇristoupit k dot, nebude z´aleˇzet na tom, kterou kopii skuteˇcnˇe pouˇzije. Optimalizaˇcn´ı pravidlo tedy funguje tak, zˇ e je li nalezen MapConcat s nez´avislym ´ vstupem IN a z´avislym ´ vstupem tvoˇrenym ´ MapFromItem, kde doch´az´ı pouze k pˇr´ıstupu ke sloˇzce q a konstrukci jednoprvkov´e n-tice se sloˇzkou q, muˇ ˚ ze byt ´ tento MapConcat rovnou nahrazen oper´atorem n-tic´ı IN. MapConcat{MapFromItem{Tuple[q](IN)}}(TupleAccess[q](IN))}(IN) → IN Po aplikaci tohoto optimalizaˇcn´ıho pravidla na strom oper´atoru z obr. 11, obdrˇz´ıme novy´ strom na obr. 12. ݉݁ݐܫܶܽܯ
ܰܫ
݈ܵܿܽܽ[ݎ1]
Obr´azek 12: Kompilace skal´arn´ı hodnoty po optimalizaci odstranˇen´ım MapConcat
3.4.2
Odstranˇen´ı MapToItem
Vrat’me se nyn´ı k puvodn´ ı uvaze odstranit MapToItem, pokud jeho z´avisl´a cˇ a´ st nepouˇz´ıv´a kontex˚ ´ tovou n-tici IN. Bylo rˇ eˇceno, pokud by vyhodnocen´ım nez´avisl´eho suboper´atoru vznikla tabulka s jinym po odstranˇen´ı MapToItem korektn´ı, jelikoˇz vysledek ´ poˇctem n-tic neˇz 1, nebyl by vysledek ´ ´ nen´ı ovlivnˇen jen obsahem, ale tak´e d´elkou tabulky. Jenˇze v tuto chv´ıli d´elku tabulky zn´ame – jedn´a se pˇresnˇe o jednu n-tici (kontextovou), takˇze vysledek odstranˇen´ı oper´atoru MapToItem neutrp´ı zˇ a´ dnou ujmu. Pˇri dalˇs´ım zamyˇslen´ı je moˇzn´e ´ ´ MapToItem odstranit i v pˇr´ıpadˇe, zˇ e z´avisly´ vstup IN vyuˇz´ıv´a. Za pˇredpokladu, zˇ e nez´avislym ´ vstupem je IN, prov´ad´ı MapToItem pouze zkop´ırov´an´ı t´eto kontextov´e n-tice opˇet do sv´eho z´avisl´eho vstupu. MapToItem{Op1 }(IN) → Op1 Pokud tedy na strom z obr´azku 12 uplatn´ıme toto optimalizaˇcn´ı pravidlo, zustane pouze ˚ oper´ator Scalar[1]. Z´avˇereˇcn´a cˇ a´ st t´eto pr´ace (kap. 5.2) ukazuje cˇ asov´a srovn´an´ı pro bˇeh dotazu bez a s optimalizacemi odstranˇen´ım MapConcat a MapToItem. 30
3.4.3
Vloˇzen´ı Product
ˇ Principem je nahrazen´ı oper´atoru MapConcat kart´ezskym tˇechto dvou ´ souˇcinem Product. Cinnost oper´atoru˚ se liˇs´ı pouze t´ım, zˇ e MapConcat prov´ad´ı pˇripojen´ı prav´e tabulky ke kaˇzd´emu z´aznamu lev´e tabulky, pˇriˇcemˇz obsah prav´e z´avis´ı na obsahu z´aznamu˚ z lev´e. U oper´atoru Product jsou obˇe tabulky nez´avisl´e. MapConcat{Op2 }(Op1 ) → Product(Op1 , Op2 ), za pˇredpokladu, zˇ e Op2 je nez´avisly´ na kontextu. Pokud tedy v z´avisl´em suboper´atoru Op2 nepouˇzijeme pˇr´ıstup k mezivysledku nez´avisl´eho ´ Op1 , muˇ ˚ zeme nahradit MapConcat oper´atorem Product. 3.4.4
Vloˇzen´ı Join
Pˇredchoz´ı optimalizace tvoˇr´ı v podstatˇe pouze mezikrok, ktery´ umoˇzn´ı pouˇzit´ı oper´atoru Join dobˇre zn´am´eho z relaˇcn´ı algebry. Pokud se nad kart´ezskym ´ souˇcinem Product nach´az´ı oper´ator Select, je moˇzn´e tuto dvojici nahradit oper´atorem Join. Vyhoda tohoto nahrazen´ı spoˇc´ıv´a v tom, zˇ e ´ lze v z´avislosti na tvaru spojovac´ı podm´ınky pro evaluaci Join pouˇz´ıt ruzn´ ˚ e efektivn´ı algoritmy, napˇr. spojen´ı hashov´an´ım (hash-join). Optimalizace vloˇzen´ım Product a Join jsou pˇrevzaty z [16]. Select{Op1 }(Product(Op2 , Op3 )) → Join{Op1 }(Op2 , Op3 ) 3.4.5
Spojen´ı kroku˚ XPath
Posledn´ı zde popsan´a a pozdˇeji implementovan´a optimalizace souvis´ı s pouˇz´ıv´an´ım zkratkov´eho z´apisu osy descendant-or-self pomoc´ı //. Jednoduchy´ XPath a//b je rozepisov´an na a/descendant-or-self::node()/child::b. Na obr´azku 13 je sestaveny´ pl´an dotazu pro vyhodnocen´ı takov´eho vyrazu, pro snazˇs´ı orientaci jsou jednotliv´e oper´atory TreeJoin rozliˇseny ´ spodn´ım indexem. 𝑇𝑟𝑒𝑒𝐽𝑜𝑖𝑛3 [child, b]
𝑇𝑟𝑒𝑒𝐽𝑜𝑖𝑛2 [descendant-or-self, node()]
𝑇𝑟𝑒𝑒𝐽𝑜𝑖𝑛1 [child, a]
𝑇𝑢𝑝𝑙𝑒𝐴𝑐𝑐𝑒𝑠𝑠[dot]
𝐼𝑁
Obr´azek 13: Pl´an dotazu a//b Optimalizaˇcn´ı pravidlo jednoduˇse transformuje dva po sobˇe jdouc´ı oper´atory TreeJoin – prvn´ı s osou descendant-or-self a testem na libovolny´ XML uzel (mimo atribut), druhy´ s osou child a testem q, na jeden TreeJoin s osou descendant a testem q.
31
TreeJoin[descendant-or-self, node()](TreeJoin[child, q](Op)) → TreeJoin[descendant, q](Op)
𝐴0
𝐴1
𝐴2
𝐴3
𝐴4
𝐴5
Obr´azek 14: Rozbor optimalizace
Dukaz ˚ Na obr´azku 14 je zn´azornˇen podstrom nˇejak´e cˇ a´ sti XML dokumentu. Pro odvozen´ı tohoto pˇrepisu bude potˇreba form´alnˇe nadefinovat nˇekolik pomocnych ´ funkc´ı. Funkce c(a) pˇriˇrazuje kaˇzd´emu uzlu a mnoˇzinu jeho pˇr´ımych ´ potomku˚ A. Funkce child(A) pˇredchoz´ı zobrazen´ı pouze zobecnuje ˇ pro moˇznost pouˇzit´ı nad celou mnoˇzinou podle vztahu (1). Jedn´a se tedy o popis cˇ innosti oper´atoru TreeJoin[child, node()](A) child(A) =
c(a)
(1)
a∈A
Pohledem na obr´azek 14 by mˇelo byt zobrazen´ı child pro kaˇzdou urove nˇ ´ jasn´e, zˇ e vysledkem ´ ´ je urove nˇ n´asleduj´ıc´ı (2). ´ Ai+1 = child(Ai )
(2)
D´ale je potˇreba form´alnˇe zaznaˇcit cˇ innost TreeJoin pˇri navigaci na osy descendant-or-self a descen´ dant (funkce dos(A) a desc(A)). Urove nˇ 0 bude povaˇzov´ana jako referenˇcn´ı, ke kter´e budeme jednotliv´e navigace vztahovat. dos(A0 ) =
n
Ai
(3)
i=0
desc(A0 ) =
n i=1
32
Ai
(4)
Kaˇzdy´ XML dokument je samozˇrejmˇe koneˇcny, ´ coˇz znamen´a, zˇ e mus´ı existovat nˇejak´a urove nˇ n, pro kterou plat´ı (5). ´ An = ∅ (5) Je tedy potˇreba dok´azat (6), tzn., zˇ e proveden´ı navigace na osu descendant-or-self n´asledovan´e navigac´ı na child je ekvivalentn´ı k proveden´ı jedn´e navigace descendant. child(dos(A0 )) = desc(A0 ) Na levou i pravou stranu vztahu (3) aplikujeme navigaci child a obdrˇz´ıme vztah (9). n child (dos(A0 )) = child Ai
(6)
(7)
i=0
N´asleduje kl´ıcˇ ovy´ bod, kdy se s funkc´ı pro navigaci na child zanoˇr´ıme do mnoˇzinov´eho sjednocen´ı. Nez´aleˇz´ı na tom, zda navigaci na child provedeme nad celou mnoˇzinou po sjednocen´ı jednotlivych ı nebo provedeme navigaci nad kaˇzdou urovn´ ı zvl´asˇ t’ a sjednocen´ı provedeme ´ urovn´ ´ ´ aˇz pak. child (dos(A0 )) =
n
child (Ai )
(8)
i=0
Za pouˇzit´ı vztahu (2) provedeme jednoduchou upravu na tvar (9) a (10). ´ child (dos(A0 )) =
n
Ai+1
(9)
i=0
child (dos(A0 )) =
n+1
Ai
(10)
i=1
Horn´ı hranici pro mnoˇzinov´e sjednocen´ı n + 1 je moˇzn´e sn´ızˇ it na n, jelikoˇz uˇz mnoˇzina An je pr´azdn´a, takˇze An+1 mus´ı byt ´ pr´azdn´a tak´e. Potom prav´a strana odpov´ıd´a podle vztahu (4) navigaci na osu descendant a je tedy odvozen vztah (6). V z´avˇeru t´eto pr´ace jsou opˇet v kapitole 5.2 srovn´any cˇ asy vyhodnocov´an´ı dotazu bez a s touto optimalizac´ı. 3.4.6
Dalˇs´ı moˇznosti optimalizace
Dalˇs´ı moˇznosti optimalizace, kter´e v t´eto pr´aci nejsou implementov´any, spoˇc´ıvaj´ı v pˇresunu nˇekterych ´ oper´atoru˚ v pl´anu dotazu smˇerem ke koˇrenov´emu oper´atoru nebo smˇerem k listum. ˚ V cˇ l´anku [16] je pops´an princip tzv. unnesting pˇrepisu, ˚ jejichˇz uˇ ´ celem je pokud moˇzno eliminovat vykon´av´an´ı zanoˇrenych smyˇcek pˇri vyhodnocov´an´ı dotazu, coˇz se tyk´ ´ ´ a pˇredevˇs´ım cˇ innosti oper´atoru˚ MapConcat. Toho je doc´ıleno zaveden´ım speci´aln´ıho oper´atoru GroupBy a nˇekolika optimalizaˇcn´ıch pravidel, kter´e napˇr. umoˇzn´ı pˇresun GroupBy ze z´avisl´eho suboper´atoru MapConcat nad tento MapConcat. Efektivnˇejˇs´ıho vyhodnocen´ı by bylo moˇzn´e dos´ahnout tak´e zaveden´ım oper´atoru TupleTreePattern [14], ktery´ je schopen v jednom kroku efektivnˇe vyhodnotit v´ıce za sebou
33
n´asleduj´ıc´ıch axis steps a predik´atu˚ napˇr. za pouˇzit´ı indexovan´e XML datab´aze. Oper´ator TupleTreePattern pracuje na z´akladˇe tzv. TPQ (Tree Pattern Query), coˇz je zjednoduˇsen´a podoba XPath vyraz u. ´ ˚ Princip optimalizace tedy spoˇc´ıv´a v nalezen´ı co nejvˇetˇs´ıch moˇznych ´ cˇ a´ st´ı v pl´anu dotazu, kter´e lze pˇrepsat na TupleTreePattern, jemuˇz je statickym ´ atributem nadefinov´an TPQ.
34
4
Implementace XQuery procesoru
Tato kapitola se vˇenuje postupu implementace XQuery procesoru, ktery´ je souˇca´ st´ı pˇr´ılohy diplomov´e pr´ace. Zjednoduˇsen´a blokov´a funkce cel´eho procesoru je zachycena na n´asleduj´ıc´ım sch´ematu. XQuery
Dotaz ve formě textového řetezce
Parser Syntaktický strom
Kompiler Plán dotazu
Optimalizátor Optimalizovaný plán dotazu XML dokument
DOM reprezentace dokumentu
Procesor
Objekty datového modelu
Výsledek
Obr´azek 15: Blokov´a struktura procesoru Na vstupu vˇzdy stoj´ı zadany´ XQuery dotaz, ktery´ je v prvn´ım kroku pˇreveden parserem na syntakticky´ strom. Ze syntaktick´eho stromu d´ale kompiler sestav´ı pl´an vykon´av´an´ı dotazu, ktery´ je pˇr´ıpadnˇe poupraven optimaliz´atorem. V posledn´ı f´azi vstupuje do hry procesor, ktery´ strom oper´atoru˚ vyhodnot´ı, pˇriˇcemˇz muˇ ˚ ze, ale tak´e nemus´ı, vyuˇz´ıvat koˇrenovy´ XML dokument. Kapitola se bude postupnˇe zamˇerˇ ovat na detailnˇejˇs´ı jednotlivych ´ bloku˚ z hlediska implementace.
4.1
Standard W3C a zjednoduˇsen´ı
Tato implementace standard jazyka XQuery z velk´e cˇ a´ sti dodrˇzuje, nicm´enˇe objevuje se zde nˇekolik uprav a zjednoduˇsen´ı. ´ 4.1.1
Podporovan´e konstrukce
1. FLWOR vyrazy ´ FLWOR vyrazy jsou podporov´any v cel´em rozsahu. Jedinym omezen´ım je ´ ´ chybˇej´ıc´ı moˇznost stanoven´ı datov´eho typu promˇenn´e pomoc´ı kl´ıcˇ ov´eho slova as. Toto omezen´ı vych´az´ı ze zjednoduˇsen´eho typov´eho syst´emu, ktery´ bude pops´an pozdˇeji v kapitole 4.4. 2. XPath vyrazy ´ XPath vyrazy jsou podporov´any vˇcetnˇe vˇsech definovanych XML os a zkrat´ ´ kovych z´apisu. ´ ˚ Jsou podporov´any jmenn´e testy a v omezen´e m´ırˇ e tak´e tzv.
35
kind tests (tj. testy na typ uzlu), konkr´etnˇe comment(), node(), text() a attribute(attribName) 3. Aritmetick´e a relaˇcn´ı vyrazy ´ Jsou podporov´any standardn´ı aritmetick´e vyrazy nad cˇ ´ıselnymi ´ ´ poloˇzkami – operace sˇc´ıt´an´ı, odˇc´ıt´an´ı, n´asoben´ı, dˇelen´ı (celoˇc´ıseln´e i desetinn´e) a modulo. D´ale standardn´ı vyrazy porovn´av´an´ı – ostr´e a neostr´e uspoˇra´ d´an´ı, rovnost a nerovnost ´ poloˇzek. Vzhledem k tomu, zˇ e implementace nen´ı omezena pouze na XQuery core, pˇri pouˇz´ıv´an´ı nen´ı nutn´e pˇrepisovat aritmetick´e nebo relaˇcn´ı oper´atory na vestavˇen´e funkce. Tato implementace je oproti standardu m´ırnˇe n´aroˇcnˇejˇs´ı na dodrˇzov´an´ı typovych vyrazy je ´ konvenc´ı. Zejm´ena pˇri pr´aci s aritmetickymi ´ ´ potˇreba prov´adˇet explicitn´ı pˇretypov´an´ı hodnot zadanych rˇ etˇezci nebo ´ textovymi ´ XML uzly na cel´e nebo desetinn´e cˇ ´ıslo. 4. Logick´e vyrazy ´ Podporov´any jsou z´akladn´ı logick´e operace – logicky´ souˇcet or a souˇcin and. Operace negace je v XQuery standardnˇe realizov´ana vestavˇenou funkc´ı not. 5. Alternativa Implementace podporuje vˇetven´ı if a vˇetven´ı podle datov´eho typu typeswitch. 6. Pˇretypov´an´ı V r´amci vydefinovan´eho zjednoduˇsen´eho typov´eho syst´emu, je podporov´ana i operace pˇretypov´an´ı. Kompletn´ı popis kompatibility a pˇretypovatelnosti jednotlivych ´ typu˚ je moˇzn´e nal´ezt v pˇr´ıloze B. 7. Kvantifikovan´e vyrazy ´ Podporov´any jsou tak´e vˇseobecn´e a existenˇcn´ı kvantifikovan´e vyrazy every a ´ some. 8. XML konstruktory Implementace podporuje konstruktory XML uzlu˚ a to jak konstruktory pˇr´ım´e, tak konstruktory vypoˇcten´e (viz kapitola 2.3.2). 9. Vestavˇen´e funkce Kompletn´ı seznam podporovanych vestavˇenych funkc´ı je uveden v tabulce 5. ´ ´ Jejich popis vˇcetnˇe typu˚ argumentu˚ lze nal´ezt v pˇr´ıloze A. Vyznam funkc´ı ´ neodpov´ıd´a pˇresnˇe standardu a je upraven pro potˇreby t´eto pr´ace. Je velmi pravdˇepodobn´e, zˇ e bude tento seznam v budoucnu rozˇsiˇrov´an.
36
add lt vle predicate empty
sub gt vge boolean not
mul le abs range
div ge count distinct
idiv veq position avg
mod vne last sum
eq vlt doc min
ne vgt root max
Tabulka 5: Podporovan´e vestavˇen´e funkce
4.1.2
Nepodporovan´e nebo cˇ a´ steˇcnˇe podporovan´e konstrukce
• Vytv´arˇ en´ı funkc´ı a modulu˚ • Specifikace uˇzivatelem definovanych ´ typu˚ • Jmenn´e prostory • Ordered a unordered vyrazy ´ • Procesn´ı instrukce, entity a sekce CDATA • Porovn´av´an´ı poˇrad´ı XML elementu˚
4.2
Implementaˇcn´ı prostˇred´ı
Cely´ XQuery procesor byl naimplementov´an v jazyce C++. Bylo vyuˇzito vyvojov´ e prostˇred´ı ´ Microsoft Visual Studio (v prubˇ ve verz´ıch 2010 a 2005). Jazyk C++ byl zvolen zejm´ena ˚ ehu vyvoje ´ z duvodu rychlosti bˇehu vysledn´ eho programu a moˇznosti efektivn´ıho nakl´ad´an´ı s pamˇet´ı. Im˚ ´ plementace by pravdˇepodobnˇe byla pohodlnˇejˇs´ı v nˇekter´em z vyˇssˇ´ıch programovac´ıch jazyku˚ C# nebo Java, avˇsak za cenu ztr´aty zde velmi zˇ a´ dan´e rychlosti. Kromˇe z´akladn´ıch datovych ´ typu˚ a funkc´ı, kter´e C++ nab´ız´ı, byl vyuˇz´ıv´an jmenny´ prostor std pˇredevˇs´ım pro pr´aci s textovymi rˇ etˇezci. Pozdˇeji byla vyuˇzita i extern´ı knihovna Xerces Parser ´ pro naˇc´ıt´an´ı vstupn´ıch XML dokumentu. ˚
4.3
Univerz´aln´ı datov´e struktury
Na zaˇca´ tku i bˇehem vyvoje procesoru vzniklo nˇekolik univerz´aln´ıch datovych ´ ´ typu˚ pˇredevˇs´ım pro zjednoduˇsen´ı pr´ace s polem. Pozdˇeji se bude text na tyto vznikl´e typy cˇ asto odvol´avat, proto tedy alesponˇ struˇcny´ popis. 4.3.1
MyList
Jedn´a se o sˇ ablonu zapouzdˇruj´ıc´ı pr´aci s dynamickym ´ polem pomoc´ı metod jako add(T item), removeAt(int index), T getItem(int index) a setItem(int index, T item). Pˇri pˇrid´av´an´ı prvku˚ se MyList v pˇr´ıpadˇe nutnosti s´am star´a o spr´avn´e pˇrealokov´an´ı intern´ıho pole. Z hlediska efektivity pˇrealokov´an´ı neprob´ıh´a vˇzdy pˇri pˇrid´av´an´ı prvku. Pokud souˇcasn´a kapacita nestaˇc´ı, dojde k alokaci nov´eho pole o dvojn´asobn´em rozmˇeru. Experiment´alnˇe se uk´azalo, zˇ e nejvhodnˇejˇs´ı vychoz´ ı velikost je 1. Pˇri vytv´arˇ en´ı instance vˇsak lze poˇca´ teˇcn´ı kapacitu urˇcit ´ argumentem konstruktoru. 37
4.3.2
MyStack
Vyznam t´eto sˇ ablony je evidentn´ı z n´azvu. Jedn´a se o z´asobn´ık implementovany´ dvˇema ´ zpusoby – spojovym ˚ ´ seznamem a polem. Konkr´etn´ı implementaci je moˇzno zvolit pˇri kompilaci zdrojovych ´ kod ´ u˚ procesoru. Jsou podporov´any standardn´ı metody push(T item), T pop(), T getPeak() a bool empty(). Jejich vyznam ne tˇreba vysvˇetlovat. Pro realizaci seznamu bylo ´ nutn´e vytvoˇrit tˇr´ıdu MyLinkNode reprezentuj´ıc´ı jeden uzel jednosmˇern´eho spojov´eho zenamu, ktery´ zapouzdˇruje skuteˇcnˇe nesenou hodnotu a pˇrid´av´a k n´ı odkaz na n´asleduj´ıc´ı prvek. 4.3.3
MyQueue
Opˇet velmi dobˇre zn´am´a datov´a struktura – fronta s podporou metod enqueue(T item), T dequeue(), T getHead(), T getTail() a bool empty(). Implementaci vnitˇrnˇe zajiˇst’uje spojovy´ seznam pomoc´ı tˇr´ıdy MyLinkNode popsan´e v pˇredchoz´ım odstavci. 4.3.4
MyHashSet
Jedn´a se o implementaci mnoˇziny s metodami add(T item) a bool contains(T item). Z n´azvu vyplyv´ ´ a, zˇ e MyHashSet pro realizaci mnoˇziny vnitˇrnˇe vyuˇz´ıv´a hash tabulku. Pro rˇ eˇsen´ı koliz´ı je zde vyuˇz´ıv´ana metoda dvojit´eho hashov´an´ı s funkcemi h1 (k) = k mod m a h2 (k) = 1 + (k mod (m − 1)), kde k pˇredstavuje celoˇc´ıselnou hodnotu identifikuj´ıc´ı prvek a m velikost tabulky. Tabulka m´a ve vychoz´ ım stavu 11 volnych pozic. K pˇrealokov´an´ı dojde vˇzdy po dosaˇzen´ı ´ ´ poloviˇcn´ıho zaplnˇen´ı. V r´amci tˇr´ıdy je k dispozici seznam 30-ti pˇreddefinovanych ´ prvoˇc´ısel, podle kterych ´ se v pˇr´ıpadˇe potˇreby urˇc´ı nov´a velikost. Prvoˇc´ısla jsou po sobˇe zvolena tak, aby kaˇzd´e bylo pˇribliˇznˇe 2 kr´at vˇetˇs´ı, viz tabulka 6. 11 397 12853 411527 13169977 421439783
23 797 25717 823117 26339969 842879579
47 1597 51437 1646237 52679969 1685759167
97 3203 102877 3292489 105359939 3371518343
197 6421 205759 6584983 210719881 2448069391
Tabulka 6: Prvoˇc´ısla pro volbu velikosti tabulky hash Identifikaci prvku v mnoˇzinˇe zajiˇst’uje pomocn´a sˇ ablona MyEqComparer, kter´a abstraktnˇe definuje metody pro detekci shodnosti a zjiˇstˇen´ı hodnoty hash. Vzhledem k tomu, zˇ e se prvky obvykle identifikuj´ı svou adresou, je souˇca´ st´ı univerz´aln´ıch struktur tak´e implementace ReferenceEqComparer. MyHashSet bylo nutn´e naimplementovat prim´arnˇe pro efektivn´ı pr´aci oper´atoru TreeJoin, ktery´ v posledn´ım kroku vyhodnocov´an´ı eliminuje duplicity. 4.3.5
MyIterator
Jedn´a se o abstraktn´ı tˇr´ıdu, kter´a zajiˇst’uje pruchod polem, spojovym ˚ ´ seznamem nebo jinym ´ typem pˇredstavuj´ıc´ım seznam hodnot pomoc´ı metod reset(), T getNext() a bool hasNext(). 38
Tato abstraktn´ı tˇr´ıda byla implementov´ana pro MyList jako MyListIterator a pro MyQueue jako MyQueueIterator. Iter´atory umoˇznily pˇredevˇs´ım v oper´atorech XQuery algebry oddˇelit proch´azen´ı seznamu (napˇr. sekvence poloˇzek nebo tabulky) od jeho fyzick´e implementace.
4.4
Datovy´ model
Datovy´ model popisuje syst´em navz´ajem propojenych ´ tˇr´ıd, kter´e zapouzdˇruj´ı pr´aci s jednotlivymi ´ typy hodnot XQuery. <
> DataValue
<<enum>> DataType
DataType getType() string toString() void initialize()
<> DataItemEnumerable SequenceIterator getIterator() int count() void initialize()
<> DataItem
*
int itemIndex
<> DataTupleEnumerable
XML_ATTRIBUTE XML_COMMENT XML_NODE XML_TEXT XML_DOCUMENT UNKNOWN
TableIterator getIterator() int count() void initialize()
DataSequence void addItem(DataItem value) void initialize()
SEQUENCE TABLE TUPLE BOOLEAN INTEGER STRING DOUBLE
DataTable
DataTuple void add(string name, DataItemEnumerable value) DataItemEnumerable getValue(string name) void initialize()
*
void addTuple(DataTuple tuple) void initialize()
Obr´azek 16: Tˇr´ıdn´ı diagram datov´eho modelu Z tˇr´ıdn´ıho diagramu na obr´azku 16 je patrn´e, zˇ e jak´akoli hodnota muˇ ˚ ze byt ´ na nejvyˇssˇ´ı urovni abstrakce interpretov´ana jako DataValue. Dalˇs´ı urove nˇ dˇediˇcnosti spoˇc´ıv´a v rozdˇelen´ı ´ ´ na DataTupleEnumerable a DataItemEnumerable. V z´akladu jde o du´aln´ı struktury – jedna pro pr´aci s n-ticemi, druh´a pro pr´aci s poloˇzkami. Vyznam tˇr´ıd *Enumerable spoˇc´ıv´a v moˇznosti iterov´an´ı pomoc´ı TableIterator nebo ´ SequenceIterator. Doch´az´ı tak k zakryt´ı rozd´ılu, ˚ zda pracujeme s n-tic´ı DataTuple nebo tabulkou DataTable a na druh´e stranˇe s poloˇzkou DataItem nebo sekvenc´ı DataSequence. Tˇr´ıdn´ı diagram datov´eho modelu poˇc´ınaje DataItem pokraˇcuje na obr´azku 17. Uveden´e tˇr´ıdy na obr´azc´ıch 16 a 17 slouˇz´ı jako pevny´ z´aklad, u kter´eho nejsou pˇredpokl´ad´any pravideln´e zmˇeny nebo rozˇsiˇrov´an´ı. Z toho vych´az´ı tak´e filosofie n´azvoslov´ı a organizace nˇekterych ´ metod. 4.4.1
Typovy´ syst´em
Z pohledu dotazu, ktery´ procesor vykon´av´a je pro kaˇzdy´ datovy´ objekt duleˇ ˚ zity´ jeho typ dany´ vyˇ ´ ctem DataType. Zde doch´az´ı ke zjednoduˇsen´ı oproti standardu W3C, ktery´ definuje moˇznost tvorby uˇzivatelskych ´ typu. ˚ V t´eto implementaci dotazy pracuj´ı pouze s fixn´ı mnoˇzinou datovych ´ typu, ˚ jejichˇz kompatibilita je pops´ana v pˇr´ıloze B. Z tohoto zjednoduˇsen´ı vyplyvaj´ ´ ı nˇekter´a dalˇs´ı
39
<> DataItem int itemIndex
BooleanItem
*
<> XmlNode XmlElement parent
StringItem
<> NumericItem
bool value
string value
void initialize(bool v)
void initialize(string v)
void initialize() IntegerItem
void navigate(TreeAxis axis, XmlElementFilter filter, MyList<XmlNode> result)
XmlElement
double value
void initialize(int v)
void initialize(double v)
XmlAttribute
XmlText
string name string value
string name void initialize() void addChild(XmlNode node) int childCount() XmlNode getChild(int index)
DoubleItem
int value
void initialize(string name, string value)
XmlComment
string text
string comment
void initialize(string s)
void initialize(string s)
XmlDocument void initialize()
Obr´azek 17: Tˇr´ıdn´ı diagram datov´e poloˇzky omezen´ı, napˇr. nepodporovan´a klauzule as ve vyrazech FLWOR, kde uˇzivatel s´am specifikuje ´ typ sekvence poloˇzek. Jazyk XQuery je relativnˇe silnˇe typovany, ´ coˇz znamen´a, zˇ e operace jako sˇc´ıt´an´ı cˇ ´ısla s rˇ etˇezcem reprezentuj´ıc´ım cˇ ´ıslo jsou obvykle neplatn´e a je nutn´e vyuˇz´ıt nˇejak´eho mechanismu pˇretypov´an´ı. Bylo nutn´e vyˇreˇsit konverzi mezi typy jak na implementaˇcn´ı urovni, tak na urovni procesoru ´ ´ z uˇzivatelsk´eho hlediska. Pˇretypov´an´ı v r´amci implementace Vzhledem k tomu, zˇ e pˇri pouˇz´ıv´an´ı datov´eho modelu doch´az´ı k pˇretypov´an´ı velmi cˇ asto, byl naimplementov´an relativnˇe jednoduchy´ syst´em pomocnych metod is* a as*. Pro kaˇzdy´ typ ´ modelu (vˇcetnˇe tˇech abstraktn´ıch) je ve tˇr´ıdˇe DataValue abstraktnˇe definov´ana metoda as* (napˇr. asDataItem()), kter´a provede pˇretypov´an´ı bez nutnosti pouˇzit´ı standardn´ı z´avorkov´e syntaxe. Pro otestov´an´ı, zda je pˇretypov´an´ı vubec moˇzn´e slouˇz´ı odpov´ıdaj´ıc´ı abstraktn´ı metoda is* (tzn. ˚ napˇr. isDataItem()). Vyznam ovˇsem nen´ı pouze v usnadnˇen´ı a zpˇrehlednˇen´ı z´apisu. Uveden´e metody totiˇz ´ neprov´ad´ı pˇretypov´an´ı vˇzdy pouze ve smyslu klasick´eho polymorfismu, ale napˇr´ıklad pro StringItem je moˇzn´e zavolat asDataSequence(), pˇrestoˇze se DataSequence a StringItem nach´az´ı v hierarchii dˇediˇcnosti na jin´e vˇetvi. N´avratov´a hodnota is* nav´ıc nemus´ı byt ´ pro dva dan´e typy vˇzdy stejn´a. Pokud napˇr. zavol´ame isDataItem() na DataSequence, muˇ ˚ zeme obdrˇzet hodnotu ,,pravda“ v z´avislosti na tom, zda sekvence obsahuje jedinou poloˇzku.
40
Pˇretypov´an´ı z hlediska procesoru Na druh´e stranˇe je nutn´e rˇ eˇsit pˇretypov´an´ı na urovni XQuery procesoru. Vˇsechny tˇr´ıdy modelu im´ plementuj´ı metody implicitlyCastable(DataType type), a castAs(DataType type), kter´e tvoˇr´ı z´aklad oper´atoru˚ Cast a Castable. Procesor tedy podporuje konstrukce castable a cast as, pˇriˇcemˇz je moˇzn´e pouˇz´ıvat typy uveden´e v tab. 7. Ve srovn´an´ı s vyˇ ´ ctem DataType (tˇr´ıdn´ı diagram na obr. 16) zde chyb´ı typ pro tabulku a n-tici. Duvodem je, zˇ e tyto dva typy hodnot slouˇz´ı vyhradnˇ e pro mezivysledky ˚ ´ ´ procesoru a nejsou tak pˇr´ıstupn´e uˇzivateli, ktery´ spouˇst´ı dotaz. Vyˇ ´ cet nav´ıc obsahuje pomocnou konstantu UNKNOWN. sequence boolean integer string double xml-attribute xml-comment xml-node xml-text xml-document
Sekvence poloˇzek Hodnota ,,true“ / ,,false“ Cel´e cˇ ´ıslo Textovy´ rˇ etˇezec Desetinn´e cˇ ´ıslo Xml atribut Xml koment´arˇ Xml element Xml textovy´ uzel Xml dokument
Tabulka 7: Datov´e typy procesoru
4.4.2
Spr´ava datovych ´ objektu˚
O vytv´arˇ en´ı instanc´ı datovych ´ objektu˚ se star´a tˇr´ıda DataModelManager, kter´a pro kaˇzdy´ (neabstraktn´ı) datovy´ typ obsahuje metodu create* (viz tˇr´ıdn´ı diagram na obr. 18). Kaˇzd´a nov´a hodnota si nav´ıc zapamatuje odkaz na DataModelManager, ktery´ ji vytvoˇril, aby mohla pˇr´ıpadnˇe sama zakl´adat dalˇs´ı hodnoty pro vysledky vypoˇ by mohlo ´ ´ ctu˚ napˇr. aritmetickych ´ operac´ı. V uvahu ´ pˇripadat tak´e singleton rˇ eˇsen´ı, ale z duvodu napˇr. testov´an´ı se muˇ ˚ ˚ ze hodit vytvoˇrit dva oddˇelen´e spr´avce. Samotn´e konstruktory datovych ´ typu˚ zde nemaj´ı zˇ a´ dn´e argumenty, o veˇskerou inicializaci se staraj´ı metody initialize(args). Inicializace jedn´e instance totiˇz muˇ ˚ ze probˇehnout v´ıcekr´at. Argumenty t´eto metody se liˇs´ı u fin´aln´ıch tˇr´ıd, napˇr. pro BooleanItem je inicializaˇcn´ı metodˇe pˇred´av´ana skuteˇcn´a hodnota typu bool, pro XmlAttribute dvˇe hodnoty typu string (name a key) atd. V r´amci hierarchie dˇediˇcnosti je zajiˇstˇeno, zˇ e pˇri vol´an´ı initialize na nˇejaky´ konkr´etn´ı fin´aln´ı typ budou zavol´any tak´e inicializaˇcn´ı metody vˇsech pˇredku˚ podobnˇe jako se tomu dˇeje pˇri vol´an´ı konstruktoru. Recyklace instanc´ı Vyznam DataModelManager nespoˇc´ıv´a pouze v evidenci referenc´ı na vznikl´e objekty, aby je ´ nakonec bylo moˇzn´e rˇ a´ dnˇe zlikvidovat. DataModelManager um´ı existuj´ıc´ı objekty za urˇcitych ´ okolnost´ı znova vyuˇz´ıt. 41
DataModelManager
<> DataValue
MyList boolItems MyStack boolItemsCountStack int boolItemsCount MyList integerItems MyStack intItemsCountStack int intItemsCount … BooleanItem createBool(bool value) IntegerItem createInt(int value) …
Obr´azek 18: Tˇr´ıdn´ı diagram spr´avy datovych ´ objektu˚ Ke vˇsem neabstraktn´ım typum ˚ datov´eho modelu je pˇridruˇzeno jednak zvl´asˇ tn´ı pole, resp. pole zapouzdˇren´e tˇr´ıdou MyList, a jednak index posledn´ı platn´e instance. Pˇri poˇzadavku na novou instanci dojde k inkrementaci indexu a zjiˇstˇen´ı, zda nebyla pˇrekroˇcena velikost pˇr´ısluˇsn´eho pole. Pokud ano, pak skuteˇcnˇe dojde k vytvoˇren´ı a vloˇzen´ı do pole, jinak se vyuˇzije jiˇz existuj´ıc´ı objekt, ktery´ je na dan´em indexu zrovna k dispozici. Podle popisu v pˇredchoz´ım odstavci by ale promˇenn´a ukazovala pokaˇzd´e na posledn´ı pozici a nov´a instance by byla vytv´arˇ ena vˇzdy. To sice plat´ı, ale pouze do t´e doby, neˇz je na DataModelManager zavol´ana metoda clear. Ta jednoduˇse vˇsechny indexy vynuluje a vznikl´e objekty je moˇzn´e zaˇc´ıt vyuˇz´ıvat znova. Tento zpusob m´a ale relativnˇe velkou nevyhodu. Zavol´an´ım clear oznaˇc´ıme jako neplatn´e ˚ ´ vˇsechny vznikl´e datov´e objekty a t´ım p´adem jedinym ´ bodem, kde je moˇzn´e recyklaci vyuˇz´ıt, je zpracov´an´ı v´ıce XQuery dotazu˚ za sebou. Vyˇciˇstˇen´ım nav´ıc pˇrijdeme napˇr. tak´e o hodnoty, kter´e vznikly zpracov´an´ım vstupn´ıho XML, takˇze pˇred kaˇzdym ´ dotazem je nutn´e vstupn´ı XML naˇc´ıtat znova. Pˇredchoz´ı myˇslenka byla upravena tak, zˇ e je s kaˇzdym ´ poˇc´ıtadlem asociov´an nav´ıc jeˇstˇe jednoduchy´ z´asobn´ık (implementovany´ tˇr´ıdou MyStack) a metoda clear je nahrazena dvojic´ı metod pushInstanceCounters a popInstanceCounters. Pomoc´ı z´asobn´ıku tak nedoch´az´ı k upln´ emu vynulov´an´ı, ale pouze k obnoven´ı nˇejak´eho pˇredchoz´ıho stavu. ´ Nejen, zˇ e je t´ımto zpusobem odpad´a nutnost znovu naˇc´ıtat vstupn´ı XML, recyklaci lze nav´ıc ˚ relativnˇe snadno vyuˇz´ıt i pˇr´ımo bˇehem vykon´av´an´ı dotazu, ˚ coˇz bude podrobnˇeji uk´az´ano na vyhodnocov´an´ı oper´atoru Select v kapitole 4.8.2. 4.4.3
Implementace DataSequence a DataTable
U implementace DataSequence a DataTable bylo potˇreba zv´azˇ it, jakou organizaci zvolit pro reprezentaci seznamu poloˇzek nebo n-tic. V uvahu pˇripadaly dvˇe – pole zapouzdˇren´e pomoc´ı ´ MyList a fronta zapouzdˇren´a v MyQueue. Implementov´any byly nakonec obˇe. Testov´an´ım se uk´azalo, zˇ e z hlediska rychlosti vyhodnocen´ı na tom jsou obˇe pˇribliˇznˇe stejnˇe. Efektivita spojov´eho seznamu, kterym ´ je fronta realizov´ana, pravdˇepodobnˇe nebyla zcela vyuˇzita t´ım, zˇ e je pro kaˇzdy´ uzel nutn´e instanciovat zaobaluj´ıc´ı tˇr´ıdu. Seznam nen´ı moˇzn´e reprezentovat pomocnymi ´ promˇennymi pˇr´ımo v poloˇzce nebo n-tici, jelikoˇz v r´amci v´ıce rozpoˇc´ıtanych u˚ muˇ ´ ´ mezivysledk ´ ˚ ze byt ´ poloˇzka nebo n-tice v jednu chv´ıli souˇca´ st´ı v´ıce sekvenc´ı nebo tabulek.
42
4.4.4
DOM
Z hlediska manipulace s XML je nejvyhodnˇ ejˇs´ı jeho reprezentace ve formˇe DOM (Document ´ Object Model). DOM tvoˇr´ı ned´ılnou souˇca´ st datov´eho modelu poˇc´ınaje tˇr´ıdou XmlNode (viz tˇr´ıdn´ı diagram na obr´azku 17). Souˇca´ st´ı jsou d´ale tˇr´ıdy XmlDocument, XmlAttribute, XmlText a XmlComment, jejichˇz vyznam by mˇel byt ´ ´ zˇrejmy. ´ Tˇr´ıda XmlNode pˇredstavuj´ıc´ı abstraktn´ı urove nˇ pro kaˇzdy´ XML uzel poskytuje metodu ´ navigate, kter´a podle argumentu osy vol´a jednu z vnitˇrn´ıch metod pro navigaci. Samotn´a tˇr´ıda XmlNode implementuje metody pro navigaci na osy ancestor, ancestor-or-self, descendant-or-self, following, following-sibling, preceding a preceding-sibling. Navigace na attribute, child a descendant je z´aleˇzitost´ı aˇz tˇr´ıdy XmlElement, jelikoˇz pro vyhodnocen´ı tˇechto os je potˇreba pracovat s pˇr´ımymi ´ 1 nebo nepˇr´ımymi potomky . ´ 4.4.5
Symbolick´e n´azvy promˇennych ´
V kapitole 3.3.2, kde byl popisov´an pˇreklad FLWOR vyrazu, byla nadefinov´ana nutnost substituce ´ pˇr´ıstupu k promˇennym ´ pomoc´ı oper´atoru Var na pˇr´ıstup do pˇr´ısluˇsn´e sloˇzky kontextov´e ntice oper´atorem TupleAccess. Jednou z posledn´ıch uprav procesoru bylo zaveden´ı symbolickych ´ ´ n´azvu˚ promˇennych, resp. symbolickych ´ ´ oznaˇcen´ı sloˇzek n-tic. N-tic se totiˇz v pˇr´ıpadˇe sloˇzitˇejˇs´ıch dotazu˚ muˇ ˚ ze vygenerovat obrovsk´e mnoˇzstv´ı (ve sloˇzitych ´ dotazech rˇ a´ dovˇe miliony) a z hlediska definice si kaˇzd´a mus´ı n´est oznaˇcen´ı svych ´ ´ sloˇzek. Oznaˇcen´ı ve formˇe textov´eho rˇ etˇezce je sice pˇrirozen´e, ale tak´e zbyteˇcnˇe prostorovˇe n´aroˇcn´e. Nav´ıc oper´ator Tuple, ktery´ n-tice generuje a pˇriˇrazuje jim n´azvy sloˇzek mus´ı pro kaˇzdou novou n-tici n´azev kop´ırovat, coˇz zhorˇsuje vykonnost procesoru. ´ Proto byla do tˇr´ıdy DataModelManager zaimplementov´ana jednoduch´a tabulka s dvojicemi kl´ıcˇ = symbolick´y n´azev a metoda int getSymbolicKey(string key), kter´a pro zadany´ kl´ıcˇ ve formˇe textov´eho rˇ etˇezce vr´at´ı odpov´ıdaj´ıc´ı symbolicky´ n´azev v podobˇe celoˇc´ıseln´e hodnoty. Jestliˇze je metoda pro urˇcity´ kl´ıcˇ vol´ana poprv´e, postar´a se o vytvoˇren´ı nov´eho symbolick´eho n´azvu a zaveden´ı z´aznamu do tabulky, jinak vr´at´ı odpov´ıdaj´ıc´ı existuj´ıc´ı symbolicky´ n´azev. N´azvy sloˇzek n-tic jsou tedy tvoˇreny celymi ´ cˇ ´ısly. V pl´anu vykon´av´an´ı dotazu se v oper´atorech Tuple a TupleAccess skuteˇcn´e n´azvy pˇreloˇz´ı na symbolick´e bˇehem statick´eho vyhodnocov´an´ı (viz pozdˇeji v kapitole 4.8.1).
4.5
Parser
Implementace parseru vych´azela z gramatiky definovan´e standardem W3C ve formˇe EBNF [5]. Jedinym ´ omezen´ım je to, zˇ e v souˇcasn´e dobˇe implementace nepracuje s unicode. Pˇrestoˇze procesor nˇekter´e konstrukce XQuery nepodporuje, parsov´an´ı vstupn´ıho dotazu je aˇz na zminovan y´ unicode ˇ kompletn´ı. Existuj´ı v z´asadˇe dvˇe moˇznosti, jak pˇristoupit k vytvoˇren´ı parseru. Prvn´ı a jednoduˇssˇ´ı moˇznost je vyuˇzit´ı gener´atoru, ktery´ na vstupu obdrˇz´ı gramatiku a vygeneruje zdrojovy´ kod. ´ Druhou moˇznost´ı je ruˇcn´ı implementace. Vzhledem k obt´ızˇ n´e dostupnosti gener´atoru, ktery´ by byl schopen vytvoˇrit XQuery parser v jazyce C++, byla nakonec vyuˇzita druh´a moˇznost, cˇ ili ruˇcn´ı im1 Navigace na descendant-or-self je implementov´ ana ve tˇr´ıdˇe XmlNode pˇrestoˇze obecny´ uzel potomky m´ıt nemus´ı. Tato navigace ale vyuˇz´ıv´a navigaci na descendant, kter´a je skuteˇcnˇe implementovan´a aˇz v XmlElement, pouze k n´ı pˇrid´av´a vlastn´ı uzel.
43
plementace. Jak ale bude pozdˇeji pops´ano, byla vytvoˇrena speci´aln´ı utilita, kter´a z´akladn´ı skelet parseru vygenerovala. Parsov´an´ı se obvykle skl´ad´a ze dvou nez´avislych ´ kroku˚ – lexik´aln´ı a syntaktick´e analyzy. ´ Lexikální analýza
XQuery
Další token
Syntaktická analýza
Obr´azek 19: Lexik´aln´ı a syntaktick´a analyza ´ (viz [8]) Bˇehem lexik´aln´ı analyzy je vstupn´ı soubor pˇreveden na posloupnost tokenu, ´ ˚ na z´akladˇe kterych syntaktick´a analyza vytvoˇr´ı strom. Nen´ı nutn´e, aby tyto dva kroky prob´ıhaly zcela ´ ´ oddˇelenˇe, tzn. nejprve vytvoˇren´ı pole tokenu˚ a aˇz pot´e proveden´ı analyzy. Syntaktick´a analyza ´ ´ si postupnˇe sama zˇ a´ d´a o dalˇs´ı a dalˇs´ı tokeny. Blok prov´adˇej´ıc´ı lexik´aln´ı analyzu ´ se obvykle oznaˇcuje jako tzv. scanner. V pˇr´ıpadˇe XQuery je situace o nˇeco m´alo komplikovanˇejˇs´ı a to pˇredevˇs´ım kvuli ˚ pˇr´ımym ´ konstruktorum. ˚ Prakticky to znamen´a, zˇ e se v XQuery m´ıs´ı samotn´a konstrukce dotazu s jazykem XML. Z´asadn´ı rozd´ıl je jednak v pˇr´ıstupu k tzv. b´ılym ´ znakum ˚ a jednak v pohledu na kl´ıcˇ ov´a slova. 4.5.1
Termin´aln´ı symboly
Je nutn´e rozliˇsovat termin´aln´ı symbol a typ termin´aln´ıho symbolu. Z uk´azky v tabulce 8 vyplyv´ ´ a, zˇ e v urˇcitych ´ pˇr´ıpadech bude obsah termin´aln´ıho symbolu rovnou d´an jeho typem a v urˇcitych ´ pˇr´ıpadech bude potˇreba konkr´etn´ı obsah upˇresnit konkr´etn´ı hodnotou. Termin´aln´ı symboly bez obsahu
Termin´aln´ı symboly s obsahem
TT_DOLLAR TT_NOT_EQUAL TT_DOT TT_COMMA TT_LEFT_BRACKET
TT_STRING_LITERAL TT_INTEGER_LITERAL TT_NCNAME TT_DECIMAL_LITERAL
Tabulka 8: Pˇr´ıklady termin´aln´ıch symbolu˚ bez obsahu a s obsahem
Termin´aln´ı symboly se dˇel´ı na dvˇe skupiny (vyplyv´ ´ a ze standardu W3C). Prvn´ı skupinu tvoˇr´ı tzv. delimiting terminal symbols, cˇ esky oddˇeluj´ıc´ı termin´aly. To jsou takov´e termin´aln´ı symboly, kter´e mohou n´asledovat bezprostˇrednˇe za sebou bez jak´ehokoli oddˇelovaˇce. Jedn´a se napˇr. o pomlˇcku, z´avorku, znam´enko plus, ukonˇcovac´ı znaˇcku tagu a dalˇs´ı. Kompletn´ı seznam je moˇzn´e nal´ezt ve specifikaci standardu XQuery [5]. Pro lepˇs´ı pochopen´ı nen´ı sloˇzit´e pˇredstavit si jednoduchy´ aritmeticky´ vyraz, kde za levou z´avorkou n´asleduje ihned un´arn´ı minus, tzn. pomlˇcka. ´ Druhou skupinou jsou tzv. non-delimiting terminal symbols, neboli nedˇel´ıc´ı termin´aly. To jsou pˇredevˇs´ım kl´ıcˇ ov´a slova a identifik´atory. Ty mus´ı byt ´ mezi sebou oddˇeleny b´ılou mezerou nebo nˇejakym je celkem zˇrejmy. ´ jinym ´ oddˇeluj´ıc´ım termin´alem. Duvod ˚ ´ Staˇc´ı si pˇredstavit dvˇe kl´ıcˇ ov´a slova bez jak´ehokoli oddˇelen´ı. V takov´em pˇr´ıpadˇe by samozˇrejmˇe nebylo moˇzn´e urˇcit, zda se 44
jedn´a o dvˇe kl´ıcˇ ov´a slova nebo jeden dlouhy´ identifik´ator. Kompletn´ı seznam tˇechto symbolu˚ je opˇet souˇca´ st´ı pˇr´ılohy. Nejednoznaˇcnost termin´alu˚ Gramatika XQuery nedefinuje termin´aln´ı symboly uplnˇ e jednoznaˇcnˇe. To znamen´a, zˇ e urˇcity´ ´ textovy´ rˇ etˇezec muˇ ˚ ze byt ´ za ruzn ˚ ych ´ okolnost´ı identifikov´an jako ruzn ˚ y´ termin´aln´ı symbol. Jako pˇr´ıklad muˇ ˚ zeme uv´est QName a NCName, viz uk´azka 10. Oba symboly jsou v gramatice definov´any jako termin´aln´ı. Jak se m´a scanner zachovat, jestliˇze n´asleduj´ıc´ım rˇ etˇezcem na vstupu bude ,,aaa:bbb“? V tuto chv´ıli nelze s urˇcitost´ı rˇ´ıct, zda scanner pˇri poˇzadavku na dalˇs´ı termin´al vr´at´ı ,,aaa“ jako NCName nebo ,,aaa:bbb“ jako cely´ QName. QName PrefixedName UnprefixedName Prefix LocalPart NCName Name
::= ::= ::= ::= ::= ::= ::=
PrefixedName | UnprefixedName Prefix ’:’ LocalPart LocalPart NCName NCName Name - (Char* ’:’ Char*) NameStartChar (NameChar)*
Uk´azka 10: Problematick´e termin´aln´ı symboly ˇ sen´ı probl´emu spoˇc´ıv´a v tom, zˇ e si blok syntaktick´e analyzy Reˇ podle parsovan´eho grama´ tick´eho pravidla s´am urˇc´ı mnoˇzinu termin´aln´ıch symbolu, ˚ kterou bude v danou chv´ıli ochoten akceptovat. To znamen´a, zˇ e syntaktick´a analyza ´ postupnˇe dotazuje scanner na termin´aln´ı symboly, jejichˇz vyskyt je v danou chv´ıli oˇcek´av´an a scanner pouze odpov´ıd´a logickou hodnotou, zda ´ dany´ termin´aln´ı symbol aktu´alnˇe je cˇ i nen´ı na vstupu. 4.5.2
Syntakticky´ strom
Obvykle prob´ıh´a pˇreklad form´aln´ıho jazyka na oper´atory nebo jin´a element´arn´ı vol´an´ı (napˇr. instrukce assembleru) rovnou bˇehem f´aze parsov´an´ı. V t´eto implementaci jsou vˇsak obˇe f´aze striktnˇe oddˇeleny a samotny´ pˇreklad prob´ıh´a aˇz na z´akladˇe pamˇet’ov´e konstrukce syntaktick´eho stromu. Syntakticky´ strom je tvoˇren gramatickymi ´ pravidly pouˇzitymi ´ ve vstupn´ım dotazu, kde vnitˇrn´ı uzly tvoˇr´ı netermin´aln´ı symboly (gramatick´a pravidla) a listov´e uzly tvoˇr´ı termin´aly. Koˇrenovym ´ pravidlem je vˇzdy pravidlo Module (viz [5], pˇr´ıloha A.1). Striktn´ı oddˇelen´ı f´aze parsov´an´ı a pˇrekladu m´a nˇekolik vyhod: ´ 1. Oba bloky je moˇzn´e nez´avisle upravovat nebo v pˇr´ıpadˇe potˇreby uplnˇ e vymˇenit. ´ 2. Reprezentace ve formˇe syntaktick´eho stromu umoˇznuje prov´est urˇcitou transformaci ˇ vstupn´ıho dotazu. Pokud by se pr´ace d´ale rozˇsiˇrovala a z hlediska efektivity by se uk´azalo, zˇ e normalizace vstupn´ıho dotazu bude nutn´a, muˇ syntaktick´eho ˚ ze se prov´est pr´avˇe na urovni ´ stromu. V pr´aci [9] je syntakticky´ strom pouˇz´ıv´an jako model dotazu.
45
3. V souvislosti s pˇr´ıpadnym ´ propojen´ım procesoru s indexovanou XML datab´az´ı a vyhled´av´an´ım TPQ (Tree Pattern Query) ve stromu oper´atoru˚ bude pravdˇepodobnˇe nutn´e prov´est transformaci na tzv. TPNF [14]. 4.5.3
Scanner <<struct>> Token
<<enum>> TokenType
string value
Typy terminálních symbolů
Scanner string text int position
bool lookup(TokenType[] t, int length) Token readToken(TokenType t) char getCurrent() char readChar()
Obr´azek 20: Tˇr´ıdn´ı diagram scanneru Funkci scanneru, cˇ ili lexik´aln´ı analyzy, zajiˇst’uje tˇr´ıda Scanner. Kl´ıcˇ ovymi metodami jsou ´ ´ readToken, lookup, readChar a getCurrent. Implementace scanneru Scanner (viz tˇr´ıdn´ı diagram na obr. 20) je instanciov´an vˇzdy na z´akladˇe nˇejak´eho vstupn´ıho textov´eho rˇ etˇezce text a pamatuje si pozici aktu´alnˇe cˇ ten´eho znaku v promˇenn´e position. Poziˇcn´ı promˇenn´a je inicializov´ana na nulovou hodnotu. Metodou lookup je moˇzn´e dotazovat scanner, zda od aktu´aln´ı pozice pˇreˇc´ıst danou lze sekvenci typu˚ termin´aln´ıch symbolu. ˚ Pˇri tomto nahl´ızˇ en´ı se z hlediska uˇzivatele scanneru nesm´ı nic zmˇenit. Scanner sice bˇehem lookup s poziˇcn´ı promˇennou pracuje, avˇsak pˇred navr´acen´ım vysledku dojde k obnoven´ı jej´ıho puvodn´ ıho stavu. ´ ˚ Nahl´ızˇ en´ı je duleˇ ˚ zit´e proto, zˇ e ne vˇzdy je moˇzn´e rozhodnout o n´asleduj´ıc´ım gramatick´em pravidle na z´akladˇe prvn´ıho pˇreˇcten´eho termin´alu. Gramatika tedy nen´ı typu LL1. Napˇr´ıklad v pˇr´ıpadˇe deklarac´ı se konkr´etn´ı syntaktick´e pravidlo urˇc´ı aˇz t´ım, co n´asleduje za kl´ıcˇ ovym ´ slovem declare (viz pravidla na uk´azce 11). [7] Setter
[11] BoundarySpaceDecl
::= BoundarySpaceDecl | DefaultCollationDecl | BaseURIDecl | ConstructionDecl | OrderingModeDecl | EmptyOrderDecl | CopyNamespacesDecl ::= "declare" "boundary-space" ("preserve" | "strip")
46
[12] DefaultNamespaceDecl [13] OptionDecl [14] OrderingModeDecl [15] EmptyOrderDecl [16] CopyNamespacesDecl
::= "declare" "default" ("element" | "function") "namespace" URILiteral ::= "declare" "option" QName StringLiteral ::= "declare" "ordering" ("ordered" | "unordered") ::= "declare" "default" "order" "empty" ("greatest" | "least") ::= "declare" "copy-namespaces" PreserveMode "," InheritMode
Uk´azka 11: Gramatick´a pravidla nerozhodnuteln´a na z´akladˇe prvn´ıho termin´alu
Metoda readToken funguje podobnˇe jako lookup, avˇsak jej´ı cˇ innost konˇc´ı navr´acen´ım obsahu jednoho typu termin´aln´ıho symbolu (pˇredan´eho argumentem) a upravou position. Par´ ser obvykle pomoc´ı lookup nejprve vyzkouˇs´ı nˇekolik moˇznost´ı a aˇz pot´e se rozhodne, jakym ´ zpusobem se zanoˇr´ı. ˚ Velmi duleˇ ˚ zit´e veˇrejn´e metody jsou tak´e getCurrent a readChar. Obˇe metody vrac´ı znak vstupn´ıho rˇ etˇezce na aktu´aln´ı pozici position. Metoda readChar nav´ıc pˇred navr´acen´ım vysledku poziˇcn´ı promˇennou inkrementuje. Je zde moˇzn´e nal´ezt analogii s metodami lookup ´ a readToken. 4.5.4
Syntaktick´a analyza ´
Syntaktick´a analyza ´ se prov´ad´ı pomoc´ı rekurzivn´ıho sestupu dle dan´e gramatiky. Z tˇr´ıdn´ıho diagramu na obr´azku 21 je patrn´e, zˇ e pro implementaci syntaktick´eho stromu byl vyuˇzit n´avrhovy´ vzor kompozit. Termin´aln´ı uzel (SyntaxTerminalNode) se vˇzdy odkazuje na konkr´etn´ı termin´aln´ı symbol (Token – viz tˇr´ıdn´ı diagram na obr. 20). Netermin´aln´ı uzel byl vytvoˇren vˇzdy podle nˇejak´eho gramatick´eho pravidla a odkazuje se tedy na jeden z prvku˚ vyˇ ´ ctu RuleType. Parser *
Scanner scanner
SyntaxNode SyntaxNode SyntaxNode … SyntaxNode
<> SyntaxNode
*
vytvořené instance
void print() string toString()
parseRule1() parseRule2() parseRule3() parseToken(TokenType t)
SyntaxTerminalNode
void print() string toString()
SyntaxNonterminalNode MyList<SyntaxNode> childNodes void addChild(SyntaxNode node) SyntaxNode getChild(int index) int count() string toString()
<<struct>> Token
Obr´azek 21: Tˇr´ıdn´ı diagram parseru
47
<<enum>> RuleType
Generov´an´ı parseru V uvodu podkapitoly 4.5 bylo naznaˇceno, zˇ e implementace parseru probˇehla cˇ a´ steˇcnˇe auto´ matizovanˇe. Vubec prvn´ı krok, jeˇstˇe pˇred zah´ajen´ım pr´ace na procesoru, spoˇc´ıval ve vytvoˇren´ı ˚ jednoduch´eho gener´atoru, ktery´ z dan´e gramatiky v EBNF z´aklad parseru XQuery v jazyce C++ vytvoˇril. Jen pro ilustraci - metod parse* se ve tˇr´ıdˇe Parser nach´az´ı v´ıce neˇz 100. Bez tohoto zjednoduˇsen´ı by bylo manu´aln´ı kodov´ an´ı cˇ asovˇe velmi n´aroˇcn´e. ´ Tento jednoduchy´ gener´ator si poradil se z´akladn´ımi konstrukcemi samotn´e gramatiky – sekvencemi, alternativami, iteracemi symbolu˚ s povinnym vyˇ ´ nebo nepovinnym ´ vyskytem, ´ ´ cty znaku˚ atd. Komplikovan´e bylo pˇredevˇs´ım sestaven´ı kodu pro analyzu ´ ´ alternativy pr´avˇe z duvodu ˚ nejednoznaˇcnosti termin´alu. ˚ Vysledkem byl kod, ´ ´ jenˇz obsahoval metody parse*, kter´e se za pomoc´ı nahl´ızˇ en´ı navz´ajem volaly. Gener´ator velmi dobˇre poslouˇzil pro vytvoˇren´ı kodu analyzuj´ıc´ıho XQuery dotazy bez ´ pˇr´ımych ´ XML konstruktoru. ˚ Jejich parsov´an´ı bylo nutn´e doimplementovat manu´alnˇe. Ne vˇzdy gener´ator sestavil kod e spr´avnˇe tak, aby parser ,,nezabloudil“. Do´ u alternativ uplnˇ ´ dateˇcn´e upravy byly v principu jednoduch´e, avˇsak vzhledem k mnoˇzstv´ı gramatickych ´ ´ pravidel cˇ asovˇe dosti n´aroˇcn´e. V mnoha pˇr´ıpadech bylo nutn´e upravit poˇrad´ı podm´ınek tak, aby napˇr. bylo upˇrednostnˇeno kl´ıcˇ ov´e slovo oproti identifik´atoru. Oˇsetˇren´ı chyb a spr´ava pamˇeti Lexik´aln´ı i syntaktick´a analyza skonˇcit ´ muˇ ˚ ze v pˇr´ıpadˇe nekorektnˇe zadan´eho XQuery vyrazu ´ chybou. Muˇ ˚ ze se jednat napˇr. o neoˇcek´avany´ token, neuzavˇrenou z´avorku, neukonˇceny´ tag a dalˇs´ı. Jestliˇze parser naraz´ı na chybu, vygeneruje se vyjimka s pˇr´ısluˇsnym ´ ´ chybovym ´ kodem. ´ Souˇca´ st´ı tˇr´ıdy Parser (viz tˇr´ıdn´ı diagram na obr. 21) je datov´a struktura, kter´a postupnˇe shromaˇzd’uje reference na vznikl´e uzly syntaktick´eho stromu. Tato struktura je v souˇcasn´e verzi rˇ eˇsena pomoc´ı MyList<SyntaxNode>. Vˇzdy pˇri instanciov´an´ı termin´aln´ıho nebo netermin´aln´ıho uzlu se do struktury okamˇzitˇe pˇrid´a vznikl´a reference. Vˇsechny vznikl´e instance je tak moˇzn´e i v pˇr´ıpadˇe chyby a n´aslednˇe generovan´e vyjimky rˇ a´ dnˇe odalokovat. ´ Parsov´an´ı XML Vypoˇcten´e konstruktory jsou z hlediska parsov´an´ı rutinn´ı z´aleˇzitost. Menˇs´ı komplikace nastanou pˇri pouˇz´ıv´an´ı konstruktoru˚ pˇr´ımych. Jakmile parser naraz´ı na pravidlo DirectConstructor, neˇza´ d´a ´ scanner d´ale o tokeny, ale cˇ te vstupn´ı soubor po znac´ıch pomoc´ı metod readChar a getCurrent, kter´e jsou souˇca´ st´ı scanneru (viz obr. 20). Bˇehem parsov´an´ı XML je potˇreba sledovat zaˇca´ tky a konce elementu, ˚ koment´arˇ u˚ nebo procesn´ıch instrukc´ı. V hlaviˇck´ach uzlu˚ se mohou samozˇrejmˇe objevit tak´e atributy. Kromˇe toho je potˇreba poˇc´ıtat s pˇreddefinovanymi entitami napˇr. pro z´apis znaku ,,<“ nebo ,,>“, tzn. < nebo ´ >. Nakonec se v obsahu elementu, ˚ atributu˚ nebo koment´arˇ u˚ muˇ ˚ ze objevit i zanoˇreny´ vyraz ´ ve sloˇzenych z´ a vork´ a ch. ´ Byl vytvoˇren speci´aln´ı typ tokenu TT_EXTRA, ktery´ slouˇz´ı pr´avˇe pro uˇ ´ cely, kdy se tokeny nevytv´arˇ´ı bˇehem lexik´aln´ı, ale aˇz bˇehem syntaktick´e analyzy. Na obr´azku 22 je naznaˇceno parsov´an´ı ´ kr´atk´eho konstruktoru XML elementu a. Celkem zaj´ımavou vlastnost´ı jazyka XQuery je, zˇ e na cely´ XQuery procesor lze svym ´ zpusobem ˚ pohl´ızˇ et tak´e jako na parser XML. Pokud se v XML vyhneme nˇekterym ´ speci´aln´ım konstrukc´ım, 48
vysledek = x < y + { $i }
:SyntaxTerminalNode
:SyntaxTerminalNode
:SyntaxNonterminalNode
token.tokenType = TT_EXTRA token.value = “vysledek = x“
token.tokenType = TT_EXTRA token.value = “y + “
ruleType = RT_ENCLOSED_EXPR
:SyntaxNonterminalNode ruleType = RT_COMMON_CONTENT
Obr´azek 22: Princip parsov´an´ı XML elementu kter´e jsou charakteristick´e pro XQuery, pak ono XML samo o sobˇe pˇredstavuje platny´ XQuery dotaz. Tento ,,dotaz“ se pˇreloˇz´ı na oper´atory tak, zˇ e vysledkem vyhodnocen´ı je DOM. Aby bylo ´ jednoznaˇcnˇe rozliˇseno, co je skuteˇcnˇe XML a co je XQuery dotaz, gramatika XQuery zakazuje, aby se v hlaviˇcce dotazu nach´azela procesn´ı instrukce . Pˇri testov´an´ı procesoru bˇehem vyvoje byla uveden´a vlastnost uplatnˇena ve vestavˇen´e funkci ´ pro naˇc´ıt´an´ı vstupn´ıch XML dokumentu. ˚ Pozdˇeji byla funkce z hlediska efektivity upravena tak, aby pro parsov´an´ı XML dokumentu vyuˇz´ıvala Xerces Parser.
4.6
Kompiler
Jakmile m´ame pˇripraveny´ syntakticky´ strom, potˇrebujeme z nˇej vytvoˇrit pl´an vykon´av´an´ı dotazu. O tuto transformaci se star´a kompiler neboli pˇrekladaˇc implementovany´ tˇr´ıdou Compiler. Tˇr´ıdn´ı diagram z´akladn´ıch typu˚ pˇrekladaˇce se nach´az´ı na obr. 23. Ze stejnych u, ´ duvod ˚ ˚ jako u syntaktick´e analyzy, ´ je pˇri vytv´arˇ en´ı instanc´ı konkr´etn´ıch oper´atoru˚ nutn´e peˇclivˇe udrˇzovat seznam vzniklych ´ referenc´ı. O jejich evidenci se v tomto pˇr´ıpadˇe nestar´a sama tˇr´ıda Compiler, ale oddˇelen´a tˇr´ıda OperatorManager. K tomuto rozdˇelen´ı doˇslo proto, zˇ e kompiler nen´ı jedin´e m´ısto, kde mohou objekty oper´atoru˚ vznikat. Na diagramu jsou d´ale zachyceny abstraktn´ı tˇr´ıdy Operator a StaticOpType pro reprezentaci oper´atoru a statick´e sloˇzky oper´atoru. 4.6.1
Kompilace
V tomto kroku muˇ ˚ zeme pˇredpokl´adat, zˇ e byl syntakticky´ strom vytvoˇren pomoc´ı parseru a je tedy v souladu s gramatikou XQuery. Souˇca´ st´ı kompileru je mnoˇzstv´ı metod expand*, kter´e na z´akladˇe nˇejak´e konstrukce XQuery, tzn. syntaktick´eho uzlu, sestav´ı oper´ator, resp. opˇet cely´ strom oper´atoru. ˚
49
Závislé a nezávislé suboperátory *
OperatorManager
vytvořené instance *
Operator createAnd() Operator createSelect() Operator createJoin() …
<> Operator DataModelManager dataModelManager Enviroment enviroment MyList getDependent() MyList getIndependent() MyList<StaticOpType> getStatic()
int saveSubstState() void restoreSubstState()
string toString() DataValue evaluate(DataValue input) void evaluateStatic() void evaluateStaticCore()
Compiler DataModelManager dataModelManager
Statické atributy operátorů *
Operator expandXQuery(SyntaxNonterminalNode root) *
Operator expandExpr(SyntaxNonterminalNode rule) Operator expandFLWOR(SyntaxNonterminalNode rule) … StaticOpType expandKindTest(SyntaxNonterminalNode rule) …
vytvořené instance
<> StaticOpType DataModelManager dataModelManager string toString() DataValue evaluate(DataValue input)
Obr´azek 23: Tˇr´ıdn´ı diagram pˇrekladaˇce Metoda expandExpr Tato metoda tˇr´ıdy Compiler pˇredstavuje univerz´aln´ı vychoz´ ı bod pro kompilaci jak´ehokoli ´ gramatick´eho pravidla, tzn. netermin´alu. Na z´akladˇe typu vstupn´ıho netermin´aln´ıho uzlu se metoda rozhodne, zda je pravidlo natolik jednoduch´e, zˇ e se o pˇreklad postar´a sama nebo pro zpracov´an´ı zavol´a jinou konkr´etn´ı metodu expand*.
Pˇr´ıklad 4: Kompilace vˇetven´ı Algoritmus 1 demonstruje kompilaci jednoduch´eho pravidla vˇetven´ı IfExpr podle gramatick´eho pravidla na uk´azce 12. Zde je gramatikou pˇresnˇe urˇceno, na jakych ´ pozic´ıch se poduzly pˇredstavuj´ıc´ı podm´ınku, kladnou a z´apornou vˇetev nach´azej´ı. [45] IfExpr ::= "if" "(" Expr ")" "then" ExprSingle "else" ExprSingle
Uk´azka 12: Gramatick´e pravidlo pro vˇetven´ı
V tomto pˇr´ıpadˇe je vytvoˇrena instance oper´atoru Cond. Instance nen´ı zaloˇzena standardnˇe kl´ıcˇ ovym slovem new, ale metodou createCond (objektu spr´avce oper´atoru˚ ´ OperatorManager), kter´a podle argumentu˚ rovnou nastav´ı v poˇrad´ı oper´ator pro vypoˇ ´ cet kladn´e vˇetve, oper´ator pro vypoˇ ´ cet z´aporn´e vˇetve a oper´ator pro vypoˇ ´ cet podm´ınky. Z gramatiky v´ıme, zˇ e se netermin´aln´ı symbol pro logicky´ vyraz rozhoduj´ıc´ı podm´ınku nach´az´ı v r´amci ´ pravidla IfExpr pevnˇe na indexu 2, pravidlo pro kladnou vˇetev na indexu 5 a pravidlo pro z´apornou vˇetev na indexu 7. Pro kompilaci tˇechto pravidel se rekurzivnˇe opˇet zavol´a metoda expandExpr.
50
ˇ ast metody expandExpr pro pˇreklad podm´ınky Algoritmus 1: C´ if pˇrekl´adan´ym pravidlem je IfExpr then return operatorManager.createCond( expandExpr(potomek syntaktick´eho uzlu na indexu 5), expandExpr(potomek syntaktick´eho uzlu na indexu 7), expandExpr(potomek syntaktick´eho uzlu na indexu 2)); end
Vol´an´ı jin´e metody pro pˇreklad Jestliˇze univerz´aln´ı metoda expandExpr zjist´ı, zˇ e pˇrekl´ad´a napˇr. pravidlo AndExpr nebo OrExpr, nen´ı uˇz kompilace tak pˇr´ımoˇcar´a jako v pˇredchoz´ım pˇr´ıpadˇe a zavol´a se jednouˇ ´ celov´a metoda expandAndExpr nebo expandOrExpr. Kompilaci by sice v tomto pˇr´ıpadˇe jeˇstˇe bylo moˇzn´e vyˇreˇsit rovnou v tˇele expandExpr, avˇsak vysledn y´ kod ´ ´ by se takto pomalu stal velmi nepˇrehlednym. ´ Propad´av´an´ı pravidel Existuje mnoho pˇr´ıpadu, ˚ kdy se netermin´al pouze alternativnˇe pˇrepisuje na jeden jiny´ netermin´al. NumericLiteral := IntegerLiteral | DecimalLiteral | DoubleLiteral
Uk´azka 13: Propadaj´ıc´ı pravidlo
Z hlediska parsov´an´ı jsou takov´eto pˇrepisy duleˇ ˚ zit´e, ale z hlediska kompilace tato pravidla svym propad´avaj´ı a nedoch´az´ı k vytv´arˇ en´ı zˇ a´ dn´eho oper´atoru. Jestliˇze se tedy kompi´ zpusobem ˚ luje napˇr. pravidlo NumericLiteral z uk´azky 13, pak metoda expandSyntax rovnou zavol´a sama sebe s nultym ´ potomkem netermin´aln´ıho uzlu, ktery´ pr´avˇe zpracov´av´a. V tomto pˇr´ıpadˇe to bude vˇzdy jedeno z pravidel IntegerLiteral, DecimalLiteral nebo DoubleLiteral. Teprve tato pravidla budou zkompilov´ana na oper´ator Scalar. Substistuce promˇennych ´ O substituci promˇennych se star´a jiˇz zminovan´ a tˇr´ıda OperatorManager, kter´a prim´arnˇe ´ ˇ slouˇz´ı pro spr´avu pamˇeti. Vyuˇz´ıv´a se zde toho, zˇ e jedinym ´ moˇznym ´ m´ıstem v programu, kde muˇ ˚ ze vzniknout oper´ator Var pro pˇr´ıstup k promˇenn´e, je metoda createVar pr´avˇe ve tˇr´ıdˇe OperatorManager. V t´eto metodˇe lze proj´ıt tabulku aktu´alnˇe substituovanych promˇennych ´ ´ a v pˇr´ıpadˇe nalezen´ı shody vr´atit m´ısto instance Var instanci oper´atoru TupeAccess s pˇr´ıstupem do kontextov´e n-tice IN. Kdy se substituce prov´ad´ı a jaky´ je jej´ı vyznam popisuje kapitola 3.3.2. ´ Z hlediska kompileru, cˇ ili tˇr´ıdy Compiler a nˇekter´e z metod expand* (viz tˇr´ıdn´ı diagram na obr. 23), lze pouˇz´ıv´an´ı substituc´ı pˇripodobnit z´asobn´ıku (proto tak´e n´azev metody pushSubst). Jestliˇze byla v poˇrad´ı aktivov´ana nejprve substituce promˇenn´e var1 a aˇz pot´e var2 , mus´ı doj´ıt ke zruˇsen´ı substituce v opaˇcn´em poˇrad´ı, tzn. var2 , pot´e var1 . Du´alnˇe k metodˇe pushSubst by tedy mˇela existovat tak´e nˇejak´a metoda popSubst.
51
Ve skuteˇcnosti je tomu ale trochu jinak. Zat´ımco aktivov´an´ı substituc´ı prob´ıh´a obvykle postupnˇe napˇr. v urˇcitych zruˇsen´ı substituc´ı se prov´ad´ı najednou. Z toho ´ f´az´ıch kompilace FLWOR vyrazu, ´ duvodu je v yhodnˇ e jˇ s ı celkov y stav substituc´ ı nejprve nˇejakym uloˇzit, pot´e pokraˇcovat ˚ ´ ´ ´ ´ zpusobem ˚ v kompilaci, podle potˇreby substituce jednotlivych ´ promˇennych ´ postupnˇe aktivovat a nakonec se k uloˇzen´emu stavu opˇet vr´atit. Uloˇzen´ı a obnoven´ı substituˇcn´ıho stavu se prov´ad´ı metodami getSubstState a restoreSubstState. Uložení stavu substituce
Aktivace substituce
Obnovení stavu
i dot
k j i dot
k j i dot
int state = saveSubstState(); // state = 1
pushSubst(“j“); pushSubst(“k“);
restoreSubstState(state);
Obr´azek 24: Princip substituce promˇennych ´ Z uk´azky na obr´azku 24 je patrn´e, zˇ e pˇri obnoven´ı stavu substituce zust´ ˚ avaj´ı v tabulce n´azvy promˇennych. To samozˇrejmˇe niˇcemu nevad´ı, protoˇze pˇri testu na substituci prob´ıh´a vyhled´av´an´ı ´ pouze po aktu´aln´ı index. 4.6.2
Kompilace sloˇzitˇejˇs´ıch konstrukc´ı
Mezi komplikovanˇejˇs´ı konstrukce XQuery na kompilaci patˇr´ı FLWOR a XPath vyrazy. V obou ´ pˇr´ıpadech se vˇsak jedn´a pouze o opatrnou manipulaci s gramatickymi pravidly a vytv´arˇ en´ı ´ oper´atoru˚ podle pouˇzit´e algebry, tzn pravidel nadefinovanych ´ v kapitol´ach 3.3.2 a 3.3.3. Z hlediska implementace je obt´ızˇ n´a zejm´ena spr´avn´a lokalizace kl´ıcˇ ovych ´ gramatickych ´ pravidel v syntaktick´em stromu. Tato uloha by byla pravdˇepodobnˇe snazˇs´ı, kdyby pˇreklad prob´ıhal ´ rovnou bˇehem parsov´an´ı. Pˇriˇsli bychom ale o urˇcit´e vyhody (viz kapitola 4.5.2). Pro ilustraci jsou ´ z´akladn´ı gramatick´a pravidla pro FLWOR a XPath vyrazy uvedena v uk´azk´ach 14 a 15. ´ [33]
FLWORExpr
[34]
ForClause
[35] [36]
PositionalVar LetClause
[37]
WhereClause
::= (ForClause | LetClause)+ WhereClause? OrderByClause? "return" ExprSingle ::= "for" "$" VarName TypeDeclaration? PositionalVar? "in" ExprSingle ("," "$" VarName TypeDeclaration? PositionalVar? "in" ExprSingle)* ::= "at" "$" VarName ::= "let" "$" VarName TypeDeclaration? ":=" ExprSingle ("," "$" VarName TypeDeclaration? ":=" ExprSingle)* ::= "where" ExprSingle
Uk´azka 14: Koˇrenov´e netermin´aly FLWOR
52
[68]
PathExpr
RelativePathExpr
::= | | ::=
("/" RelativePathExpr?) ("//" RelativePathExpr) RelativePathExpr StepExpr (("/" | "//") StepExpr)*
[69] [70] [71] [72] [75] [82]
StepExpr AxisStep ForwardStep ReverseStep PredicateList
::= ::= ::= ::= ::=
FilterExpr | (ReverseStep (ForwardAxis (ReverseAxis Predicate*
AxisStep | ForwardStep) PredicateList NodeTest) | AbbrevForwardStep NodeTest) | AbbrevReverseStep
Uk´azka 15: Koˇrenov´e netermin´aly pro XPath
4.7
Optimalizace
Samotn´a optimalizace se sk´ad´a z postupn´eho uplatnˇen´ı nˇekolika optimalizaˇcn´ıch pravidel, kter´a byla nadefinov´ana v kapitole 3.4. Aplikace kaˇzd´eho z nich je nepovinn´a, resp. vysledek vyhod´ nocen´ı dotazu mus´ı s optimalizac´ı i bez n´ı stejny. ´ Optimaliz´ator funguje na modul´arn´ım principu a je tedy moˇzn´e snadno urˇcovat, jak´a pravidla se skuteˇcnˇe uplatn´ı a v jak´em poˇrad´ı. <> OperatorTransformation
<> Operator
Operator transform(Operator input)
... Operator transform(OperatorTransformation transform) ...
<> OptimizerTransformation OperatorManager operatorManager Operator transform(Operator input)
RemoveMapToItemTransformation
RemoveMapConcatTransformation
InsertProductTransformation
Operator transform(Operator input)
Operator transform(Operator input)
Operator transform(Operator input)
...
Obr´azek 25: Tˇr´ıdn´ı diagram optimalizace Tˇr´ıda OperatorTransformation z tˇr´ıdn´ıho diagramu na obr. 25 obecnˇe popisuje nˇejakou transformaci oper´atoru metodou transform bez n´avaznosti na optimaliz´ator. Konkr´etn´ı implementace t´eto metody muˇ ˚ ze zajistit nahrazen´ı jednoho oper´atoru nebo kombinace jinym ´ oper´atorem nebo kombinac´ı. Abstraktn´ı tˇr´ıda OptimizerTransformation popisuje transformaci urˇcenou vyhradnˇ e pro ´ optimaliz´ator. Tyto dvˇe urovnˇ e abstrakce vznikly proto, aby byl cely´ syst´em schopen s mi´ nim´aln´ımi upravami fungovat i v teoretick´em pˇr´ıpadˇe odebr´an´ı vˇseho, co se optimalizac´ı tyˇ ´ ´ ce. Vzhledem k tomu, zˇ e optimalizac´ı vznikaj´ı nov´e oper´atory, je potˇreba transformac´ım optimiz´eru pˇredat tak´e instanci OperatorManager. 53
Aby bylo moˇzn´e transformaci propagovat na cely´ strom, doˇslo k rozˇs´ırˇ en´ı tˇr´ıdy Operator z tˇr´ıdn´ıho diagramu na obr´azku 23 o abstraktn´ı metodu transform. Kaˇzd´a konkr´etn´ı implementace oper´atoru mus´ı v t´eto metodˇe na z´akladˇe argumentem pˇredan´e transformace upravit nejprve vˇsechny sv´e suboper´atory a pot´e vr´atit transformovanou podobu sama sebe (this). Na algoritmu 2 je zachycena transformace oper´atoru Select. Identifik´ator op pˇredstavuje oper´ator pro vypoˇ – podm´ınky ´ cet nez´avisl´eho vstupu, boolean je oper´ator pro vypoˇ ´ cet mezivysledku ´ selekece. Algoritmus 2: Transformace oper´atoru Select input : transformace t ve formˇe instance OperatorTransformation output: transformovan´a podoba oper´atoru Select op ← op.transform(t); boolean ← boolean.transform(t); return t.transform(this);
Pˇr´ıklad 5: Transformace vloˇzen´ı Product Pro uk´azku zde bude na algoritmu 3 pops´ano nahrazen´ı oper´atoru MapConcat oper´atorem Product, tzn. kart´ezskym ´ souˇcinem. Proˇc je toto moˇzn´e a za jakych ´ okolnost´ı, popisuje kapitola 3.4.3. Logiku transformace zajiˇst’uje metoda tˇr´ıdy InsertProductTransform, kter´a dˇed´ı z OptimizerTransformation na tˇr´ıdn´ım diagramu (obr. 25). Transformace se uplatn´ı pouze tehdy, jestliˇze zpracov´av´a oper´ator MapConcat, jinak metoda vr´at´ı vstupn´ı oper´ator beze zmˇeny. Pˇri uplatnˇen´ı transformace je potˇreba zjistit, zda se v z´avisl´em podoper´atoru nenach´az´ı reference na kontextovou n-tici, resp. oper´ator IN. Prohledat se mus´ı cely´ podstrom, pˇriˇcemˇz v podstromu se prohled´avaj´ı pouze nez´avisl´e suboper´atory. Pˇri pˇrechodu na z´avisly´ suboper´ator by se pˇr´ıpadnˇe nalezeny´ IN nevztahoval k MapConcat, pro ktery´ IN hled´ame (viz kapitola 3.2.3). Jednou z moˇznost´ı, jak tuto detekci prov´est je pro pruchod stromem at’ uˇz do hloubky nebo ˚ do sˇ´ırˇ ky pouˇz´ıt rekurzi. Rekurzivn´ı proch´azen´ı oper´atoru˚ je nahrazeno z´asobn´ıkem, na jehoˇz vrchol je ze zaˇca´ tku um´ıstˇen nez´avisly´ podoper´ator pr´avˇe zpracov´avan´eho mapConcat. V pˇr´ıpadˇe, zˇ e m´a doj´ıt k nahrazen´ı, je m´ısto puvodn´ ıho mapConcat navr´acena nov´a instance ˚ Product s pˇrebranym ´ z´avislym ´ i nez´avislym ´ podoper´atorem.
4.8
Vyhodnocov´an´ı
Posledn´ı f´aze spoˇc´ıv´a ve vyhodnocen´ı pˇripraven´eho pl´anu dotazu. V blokov´em sch´ematu na obr´azku 15 je sice naznaˇceno, zˇ e se o vyhodnocen´ı star´a procesor. Ve skuteˇcnosti je principem vyhodnocen´ı vol´an´ı metody oper´atoru evaluate, kter´a argumentem pˇreb´ır´a kontextovou hodnotu. V dalˇs´ı cˇ a´ sti textu budou pops´any pouze nˇekter´e sloˇzitˇejˇs´ı oper´atory. Vˇetˇsina oper´atoru˚ prov´ad´ı trivi´aln´ı operace, jejichˇz popis by zde postr´adal smysl.
54
Algoritmus 3: Transformace vloˇzen´ı Product input : oper´ator op – koˇren transformovan´eho podstromu output: transformovan´a podoba if transformovan´y oper´ator je MapConcat then inicializuj pr´azdny´ z´asobn´ık ; mapConcat ← pˇretypuj op na MapConcat ; vloˇz do z´asobn´ıku z´avisly´ oper´ator z mapConcat ; while z´asobn´ık nen´ı pr´azdn´y do oppom ← vyjmi prvek ze z´asobn´ıku ; if oppom je oper´ator IN then byl nalezen z´avisly´ IN ; ukonˇci cyklus ; else vloˇz do z´asobn´ıku vˇsechny nez´avisl´e oper´atory z oppom ; end end if byl nalezen z´avisl´y IN then return instanciuj Product s puvodn´ ˚ ım nez´avisl´ym a z´avisl´ym vstupem z mapConcat ; end end return vstupn´ı oper´ator op beze zmˇeny ;
4.8.1
Vyhodnocen´ı statickych ´ sloˇzek oper´atoru˚
V pˇr´ıpadˇe nˇekterych ´ oper´atoru˚ je pˇred spuˇstˇen´ım vykon´av´an´ı pl´anu potˇreba nejprve inicializovat nˇejak´e vnitˇrn´ı promˇenn´e na z´akladˇe statickych ´ sloˇzek. Jedn´a se napˇr. o pˇreklad n´azvu˚ sloˇzek n-tic na symbolick´e n´azvy (viz kapitola 4.4.5). O statick´e vyhodnocen´ı se staraj´ı metody evaluateStatic a evaluateStaticCore (viz tˇr´ıdn´ı diagram na obr. 23). Prvn´ı metoda pouze zajiˇst’uje rekurzivn´ı vol´an´ı sama sebe na z´avisl´e i nez´avisl´e oper´atory a vol´an´ı evaluateStaticCore. Ve druh´e uveden´e metodˇe je moˇzn´e podle potˇreby prov´est inicializaci, kter´a z´avis´ı na statickych ´ sloˇzk´ach a sloˇzen´ı z´avislych ´ nebo nez´avislych suboper´atoru. ´ ˚ Vol´an´ım evaluateStatic na koˇrenovy´ oper´ator cel´eho stromu jeˇstˇe pˇred zaˇca´ tkem vyhodnocov´an´ı dotazu tak muˇ ˚ zeme pˇrednastavit nˇekter´e vnitˇrn´ı vlastnosti oper´atoru, ˚ kter´e jsou bˇehem vyhodnocov´an´ı nemˇenn´e. 4.8.2
Oper´ator Select
ˇ Cinnost algoritmu 4 pro vyhodnocen´ı Select nen´ı sama o sobˇe nijak zaj´ımav´a, c´ılem uk´azky pseudokodu 4 je prezentace vˇsech pˇredem pˇripravenych ´ ´ vlastnost´ı datov´eho modelu. Nejprve je vyhodnocen nez´avisly´ podoper´ator op nad stejnym ´ kontextem, s jakym ´ byl vol´an pr´avˇe zpracov´avany´ Select. Jedn´a se o oper´ator vracej´ıc´ı vstupn´ı tabulku n-tic. D´ale si lze vˇsimnout jednak praktick´eho vyuˇzit´ı metody pro pˇretypov´an´ı asDataTupleEnumerable a jednak toho, zˇ e na vyhodnoceny´ vstup nen´ı pohl´ızˇ eno jako na tabulku, ale jako na DataTupleEnumerable. Nez´aleˇz´ı na tom, zda je vstupem cel´a tabulka, nebo jedna n-tice. 55
Algoritmus 4: Vyhodnocen´ı oper´atoru Select input : kontextov´a hodnota in output: tabulka n-tic po proveden´ı selekce DataValue inputValue ← op.evaluate(in) ; DataTupleEnumerable inputEnumerable ← inputValue.asDataTupleEnumerable() ; DataTable outputTable ← dataModelManager.createDataTable() ; TableIterator iterator ← inputEnumerable.getIterator() ; while iterator.hasNext() do DataTuple tuple ← iterator.getNext() ; dataModelManager.pushInstanceCounters() ; DataValue value ← boolean.evaluate(tuple) ; dataModelManager.popInstanceCounters() ; BooleanItem boolItem ← value.asBooleanItem() ; if boolItem.value = true then pˇridej n-tici tuple do vystupn´ ı tabulky outputTable ; ´ end end return outputTable;
Pomoc´ı dataModelManager je vytvoˇrena instance vystupn´ ı tabulky a muˇ ´ ˚ ze se zah´ajit iterace pˇres vstup. Pro kaˇzdou zpracov´avanou n-tici je vyhodnocen z´avisly´ boolean, ktery´ vyhodnocuje podm´ınku selekce. Pˇred resp. po vyhodnocen´ı boolean jsou vol´any metody pushInstanceCounters a popInstanceCounters, kter´e zajist´ı moˇznost recyklace instanc´ı promˇennych. Ze vˇsech hod´ not, kter´e potenci´alnˇe vzniknou bˇehem zpracov´an´ı boolean n´as totiˇz zaj´ım´a pouze vystupn´ ı ´ BooleanItem a i tu je moˇzn´e po pˇreˇcten´ı skuteˇcn´e logick´e hodnoty okamˇzitˇe zahodit. Ostatn´ı hodnoty, musely vzniknout z duvodu nˇejak´eho mezivysledku, ktery´ n´as uˇz d´ale nezaj´ım´a. Probl´em by ˚ ´ mohl vzniknout jen v pˇr´ıpadˇe pouˇz´ıv´an´ı glob´aln´ıch promˇennych, kter´e ale zat´ım implementov´any ´ nejsou. Pokud by bˇehem vypoˇ doˇslo k vytvoˇren´ı obsahu glob´aln´ı promˇenn´e, ´ ctu mezivysledku ´ nesmˇel by byt ´ tento obsah zahozen. 4.8.3
Oper´ator TreeJoin
Oper´ator TreeJoin je jedn´ım z tˇech, kter´e operuj´ı pouze nad sekvencemi poloˇzek. Nejsloˇzitˇejˇs´ı cˇ a´ st cˇ innosti oper´atoru je navigace v XML stromu, kterou neˇreˇs´ı s´am oper´ator, ale tˇr´ıda XmlNode. Navigace na osu descendant Nejen, zˇ e je navigace na vˇsechny pˇr´ım´e nebo nepˇr´ım´e potomky cˇ asto vyuˇz´ıvan´a pˇr´ımo v XQuery dotazu, pomoc´ı t´eto navigace lze tak´e rozepsat nˇekter´e dalˇs´ı – preceding, following nebo descendant-or-self. Algoritmus pro zjiˇstˇen´ı vˇsech potomku˚ v DOM reprezentaci je s´am o sobˇe velmi jednoduchy. ´ Staˇc´ı rekurzivnˇe proj´ıt cely´ podstrom pro dany´ XML element. Je pouze potˇreba zachovat poˇrad´ı
56
uzlu, ˚ coˇz je zajiˇstˇeno proch´azen´ım do hloubky. Byly otestov´any celkem cˇ tyˇri moˇznosti implementace t´eto metody – jednoduch´a rekurze, pˇrepis na nerekurzivn´ı podobu pomoc´ı z´asobn´ıku realizovan´eho spojovym ´ seznamem, pˇrepis na nerekurzivn´ı podobu pomoc´ı z´asobn´ıku realizovan´eho polem a pruchod pˇredpˇripravenym ˚ ´ spojovym ´ seznamem, ktery´ byl konstruov´an bˇehem vytv´arˇ en´ı DOM (viz n´ızˇ e). Posledn´ı zminovan y´ zpusob se experiment´alnˇe uk´azal jako nejefektivnˇejˇs´ı, nicm´enˇe neˇ ˚ dodrˇzuje puvodn´ ı poˇrad´ı uzlu˚ podle dokumentu. Druhym ˚ ´ nejrychlejˇs´ım se uk´azala klasick´a rekurze, o nˇeco pomalejˇs´ı byla nerekurzivn´ı varianta se z´asobn´ıkem realizovanym ´ pomoc´ı MyList a nejhuˇ ˚ re dopadla nerekurzivn´ı varianta se z´asobn´ıkem realizovanym ´ spojovym ´ seznamem. Vˇse bylo testov´ano na na XML dokumentu o velikosti 18 MB s cca 300 tis´ıci XML uzly (viz popis v kapitole 5) a jednoduch´em XPath dotazu //item[@id="item4016"]. Prumˇ ˚ ern´e cˇ asy vyhodnocov´an´ı jsou uvedeny v tabulce 9. Pruchod spojovym ˚ ´ seznamem Pouˇzit´ı rekurze Nerekurzivn´ı varianta pomoc´ı pole Nerekurzivn´ı varianta pomoc´ı spojov´eho seznamu
110 ms 120 ms 135 ms 210 ms
Tabulka 9: Srovn´an´ı algoritmu˚ pro navigaci na osu descendant
Efektivitu rekurze lze v tomto pˇr´ıpadˇe zduvodnit t´ım, zˇ e se v tˇele metody fyzicky pouˇz´ıvaj´ı ˚ pouze dvˇe lok´aln´ı promˇenn´e. Argumenty metody jsou oznaˇceny jako const, takˇze pˇri rekurzivn´ım vol´an´ı by nemˇelo doch´azet ani k vytv´arˇ en´ı lok´aln´ıch kopi´ı. Nav´ıc u bˇezˇ nych XML se ´ urove nˇ zanoˇren´ı pohybuje maxim´alnˇe v rˇ a´ du jednotek aˇz des´ıtek. ´ Neefektivitu z´asobn´ıku realizovan´eho spojovym ´ seznamem lze vysvˇetlit t´ım, zˇ e pro kaˇzdou poloˇzku je nutn´e vytvoˇrit novou instanci zaobaluj´ıc´ıho uzlu.
Postorder seznam Relativnˇe zaj´ımav´a experiment´aln´ı metoda pod´avaj´ıc´ı m´ırnˇe lepˇs´ı vysledky neˇz rekurze je pouˇzit´ı ´ pˇredpˇripraven´eho spojov´eho seznamu, ktery´ lze velmi jednoduˇse konstruovat pˇri vytv´arˇ en´ı DOM a reprezentovat nˇekolika pomocnymi promˇennymi pˇr´ımo ve tˇr´ıdˇe XmlNode. Seznam je postupnˇe ´ ´ vytv´arˇ en tak, aby pruchodem vznikl postorder z´apis. Kaˇzdy´ novˇe pˇridany´ uzel je zaˇrazen bez˚ prostˇrednˇe pˇred sv´eho rodiˇce. Proch´azen´ı vˇsech potomku˚ zaˇc´ın´a nalezen´ım nejlevˇejˇs´ıho uzlu cel´e vˇetve. Pot´e je seznam proch´azen tak dlouho, neˇz je nalezen pro danou vˇetev koˇrenovy´ uzel. Pruchod sice nevrac´ı uzly podle puvodn´ ıho uspoˇra´ d´an´ı v dokumentu, coˇz ale nevad´ı, pokud ˚ ˚ bude procesor ve vychoz´ ım stavu pracovat v tzv. unordered reˇzimu (viz [5]). Pˇredpokladem je, zˇ e ´ procesor nikdy nekonstruuje DOM tak, zˇ e by uzly napˇr. vkl´adal na urˇcity´ index – uzel je vloˇzen do sv´eho rodiˇce vˇzdy jako posledn´ı. Vkl´ad´an´ı do stromu s postorder z´apisem (viz obr. 26) prob´ıh´a jednoduˇse tak, zˇ e pˇreruˇs´ıme ,,pˇr´ıchoz´ı“ vazbu rodiˇce a prot´ahneme ji pˇres novˇe vloˇzeny´ uzel. Pro seznam to znamen´a, zˇ e novˇe vloˇzeny´ uzel bude zaˇrazen pˇred sv´eho rodiˇce. Aby bylo moˇzn´e z uzlu j okamˇzitˇe nal´ezt uzel i, kde je potˇreba vazbu pˇreruˇsit, je seznam ve skuteˇcnosti implementov´an jako obousmˇerny. ´
57
a
b
c
e
f
d
g
i
h
j
k
l
x m
n
Obr´azek 26: Postorder seznam Vytvoˇren´ı takov´eho seznamu, ktery´ by pruchodem d´aval klasicky´ preorder z´apis a t´ım vra˚ cel uzly podle poˇrad´ı v dokumentu, moˇzn´e je. Vyhled´av´an´ı pak prob´ıh´a s rozd´ılem, zˇ e uzly navˇstˇevujeme v poˇrad´ı od koˇrene aˇz po nejpravˇejˇs´ıho potomka dan´e vˇetve. Probl´em je ale v prubˇ ˚ ezˇ n´e konstrukci takov´eho seznamu. Na obr´azku 27 jsou zn´azornˇeny tˇri rozd´ıln´e situace pˇri vkl´ad´an´ı uzlu x do vznikaj´ıc´ı stromov´e DOM reprezentace. Aby zustal zachov´an preorder z´apis, mus´ı byt ˚ ´ ve vˇsech tˇrech pˇr´ıpadech (A, B, C) pˇreruˇsena vazba mezi uzly g a a. V pˇr´ıpadˇe A by se mohlo zd´at, zˇ e jde o tu vazbu, kter´a je ,,pˇr´ıchoz´ı“ do rodiˇcovsk´eho uzlu, kam se x vkl´ad´a. Naopak pˇr´ıpad C by mohl naznaˇcovat na pouh´e pˇresmˇerov´an´ı z posledn´ıho pˇr´ım´eho potomka rodiˇcovsk´eho uzlu. Obecnˇe by mechanizmus musel pracovat tak, zˇ e se nejprve nalezne nejpravˇejˇs´ı potomek ve vˇetvi toho elementu, kam se x vkl´ad´a, a tam se provede pˇresmˇerov´an´ı. To, co bychom tedy z´ıskali pˇri prov´adˇen´ı navigace na descendant, bychom pak ztratili pouˇz´ıv´an´ım konstruktoru˚ XML elementu, ˚ jelikoˇz kaˇzdym ´ novym ´ vloˇzen´ım uzlu do vznikaj´ıc´ıho stromu by muselo probˇehnout vyhled´an´ı nejpravˇejˇs´ıho potomka. A
B
a
C
a
c
b
x
d
c
b
e
f
a
d
g
c
b
e
f
x
g
Obr´azek 27: Preorder seznam
58
d
e
f
g
x
Sloˇzitost vˇsech uvedenych ´ algoritmu˚ se pohybuje v θ(n), kde n pˇredstavuje poˇcet uzlu, ˚ kter´e mus´ı algoritmus navˇst´ıvit. Nejn´akladnˇejˇs´ı operac´ı je v tomto pˇr´ıpadˇe test uzlu (test na jm´eno, test na atribut a dalˇs´ı). Efektivita jednotlivych ´ algoritmu˚ souvis´ı s reˇzi´ı kolem datovych ´ struktur, na z´akladˇe kterych ´ algoritmus pracuje. TreeJoin Vrat’me se tedy k cˇ innosti samotn´eho oper´atoru TreeJoin, kter´a zn´azornˇena algoritmem 5. Algoritmus 5: Implementace TreeJoin input : kontextov´a hodnota in output: sekvence s uzly po proveden´ı navigace DataValue inputValue ← independentOp.evaluate(in) ; DataItemEnumerable enumerable ← inputValue.asDataItemEnumerable() ; SequenceIterator iterator := enumerable.getIterator(); inicializuj pr´azdny´ seznam MyList⟨XmlElement⟩ items; while iterator.hasNext() do XmlNode node ← iterator.getNext() ; node.navigate(axis, nodeTest, items) ; end DataSequence outputSequence ← dataModelManager.createDataSequence() ; // Eliminace duplicit inicializuj pr´azdny´ MyHashSet⟨XmlElement⟩ hashSet ; for vˇsechny poloˇzky item v items do if hashSet neobsahuje poloˇzku item then pˇridej poloˇzku item do vystupn´ ı sekvence outputSequence ; ´ pˇridej poloˇzku item do hash tabulky hashSet. end end return outputSequence ; Nejprve je potˇreba vyhodnotit nez´avisly´ vstup independentOp, ktery´ je n´aslednˇe pˇretypov´an na DataItemEnumerable. Opˇet tedy zakryt´ı rozd´ılu mezi sekvenc´ı a poloˇzkou. Iter´atorem jsou proch´azeny vˇsechny poloˇzky vstupn´ı sekvence a metodou navigate postupnˇe nashrom´azˇ dˇeny do seznamu items. V podstatˇe jedinym samotn´eho TreeJoin je eliminace duplicit. Nejjed´ sloˇzitˇejˇs´ım ukolem ´ noduˇssˇ´ı implementac´ı by bylo pouˇzit´ı zanoˇren´e smyˇcky, coˇz ale z hlediska efektivity urˇcitˇe nen´ı nejlepˇs´ı rˇ eˇsen´ı. Pr´avˇe z toho duvodu byla implementov´ana mnoˇzina MyHash, kter´a je souˇca´ st´ı ˚ univerz´aln´ıch struktur popsanych ´ vyˇ ´ se v kapitole 4.3.
59
4.8.4
Oper´ator IN
Z hlediska spr´avn´eho pochopen´ı, jak funguje pˇred´av´an´ı hodnoty kontextu je vhodn´e vysvˇetlit ´ skuteˇcnou funkci oper´atoru IN. Ukolem tohoto oper´atoru nen´ı nic jin´eho, neˇz navr´acen´ı kontextu, se kterym ´ bylo vol´ano jeho vyhodnocen´ı. Trivi´aln´ı postup je uveden na algoritmu 6. Ve vˇetˇsinˇe pˇr´ıpadu˚ je obsahem IN n-tice, pouze v pˇr´ıpadˇe z´avisl´eho vstupu oper´atoru MapFromItem jde o poloˇzku. Algoritmus 6: Implementace IN input : kontextov´a hodnota in output: kontextov´a hodnota in return in ;
4.8.5
Oper´ator Call
Relativnˇe zaj´ımavy´ oper´ator z hlediska implementace pˇredstavuje Call, cˇ ili vol´an´ı funkce. Vyˇ ´ cet vˇsech z´akladn´ıch vestavˇenych ´ funkc´ı byl uveden v tabulce 5. Pro uˇ ´ cely testov´an´ı fungovala prvn´ı verze vyhodnocov´an´ı v principu velmi jednoduˇse formou jedn´e glob´aln´ı statick´e metody, viz algoritmus 7. Algoritmus 7: Puvodn´ ı implementace Call ˚ input : n´azev funkce, obsah kontextu IN, pole argumentu˚ funkce output: vysledek funkce ´ if n´azev funkce je ,,add“ then zpracov´an´ı funkce add else if n´azev funkce je ,,sub“ then zpracov´an´ı funkce sub else if n´azev funkce je ,,mul“ then zpracov´an´ı funkce mul end ··· Toto naivn´ı rˇ eˇsen´ı s sebou neslo nˇekolik vyznamn ych ´ ´ nevyhod: ´ • nutnost z´asahu do oper´atoru Call vˇzdy pˇri implementaci dalˇs´ı funkce, • ad-hoc rˇ eˇsen´ı – chybˇej´ıc´ı modul´arn´ı stavba, • nutnost nˇekolikan´asobn´eho porovn´av´an´ı rˇ etˇezce n´azvu funkce pˇri kaˇzd´em poˇzadavku na vyhodnocen´ı. Prostˇred´ı Novy´ princip modul´arn´ı stavby funkc´ı je zn´azornˇen na obr´azku 28. Tˇr´ıda Enviroment slouˇz´ı pro popis prostˇred´ı, ve kter´em bude XQuery dotaz vykon´av´an. Prostˇred´ım se rozum´ı to, jak´e funkce 60
Enviroment
<> Function
MyList XmlNode rootContextNode
* DataModelManager dataModelManager Enviroment enviroment
loadRootDocument(string filename) getFunction(string name, int argsCount) registerFunction(Function function) registerBuiltInFunctions()
string getName() int argsCount() DataValue evaluate( DataValue contextItem, DataValue[] args)
FAdd
FSub
string getName() int argsCount() DataValue evaluate( DataValue contextItem, DataValue[] args)
string getName() int argsCount() DataValue evaluate( DataValue contextItem, DataValue[] args)
...
Obr´azek 28: Tˇr´ıdn´ı diagram modul´arn´ı stavby funkc´ı budou k dispozici, co je koˇrenovy´ uzel a vyhledovˇ e tak´e jak´e jsou napˇr. glob´aln´ı promˇenn´e nebo ´ konstanty. Dle specifikace W3C by se dalo rˇ´ıct, zˇ e pr´avˇe tato tˇr´ıda popisuje tzv. statick´y kontext. Z diagramu by mˇelo byt modul´arn´ı rˇ eˇsen´ı funguje. Pro funkci ´ evidentn´ı, jakym ´ zpusobem ˚ je vytvoˇrena abstraktn´ı tˇr´ıda Function, kaˇzd´a konkr´etn´ı funkce pak mus´ı umˇet vr´atit svou signaturu, tzn. n´azev a poˇcet vstupn´ıch argumentu. ˚ Do budoucna by souˇca´ st´ı signatury mohly byt ´ tak´e jejich datov´e typy. Pˇred samotnym ´ pouˇz´ıv´an´ım funkce mus´ı probˇehnout jej´ı registrace do prostˇred´ı metodou registerFunction. Bˇehem vyhodnocov´an´ı statickych sloˇzek oper´atoru Call (kap. 4.8.1) je d´ano, jaky´ bude m´ıt ´ volan´a funkce n´azev, a poˇctem podoper´atoru˚ d´ano, kolik argumentu˚ bude funkce potˇrebovat. Z prostˇred´ı je tedy moˇzn´e jednoduˇse z´ıskat odkaz na potˇrebnou funkci vˇcetnˇe jej´ı implementace jeˇstˇe pˇred zah´ajen´ım vyhodnocov´an´ı. Dojde tedy k ,,prolinkov´an´ı“ mezi konkr´etn´ım oper´atorem Call a algoritmem samotn´e funkce. Zaveden´ım modul´arn´ı stavby funkc´ı skuteˇcnˇe doˇslo ke zrychlen´ı vykon´av´an´ı dotazu na uk´azce 16. Na zkuˇsebn´ım XML dokumentu (viz n´ızˇ e kap. 5) doˇslo ke zlepˇsen´ı z pˇribliˇznˇe 330 na 290 ms d´ıky efektivnˇejˇs´ımu vol´an´ı funkce eq pro porovn´av´an´ı. for $i in //item where some $t in $i//listitem/text() satisfies $t = "Test" return $i
Uk´azka 16: Testovac´ı dotaz
4.8.6
Dalˇs´ı oper´atory
Mezi dalˇs´ı m´ırnˇe komplikovanˇejˇs´ı oper´atory patˇr´ı napˇr. MapConcat, Join nebo Product. U tˇechto velmi podobnych ´ oper´atoru˚ snad stoj´ı za zm´ınku akor´at to, zˇ e spojov´an´ı n-tic se prov´ad´ı na rela61
tivnˇe n´ızk´e urovni. M´ısto postupn´eho pˇrekop´ırov´an´ı n´azvu˚ a hodnot z jedn´e n-tice do druh´e se ´ pouˇz´ıv´a n´ızkourov nov´ ´ ˇ a kopie bloku pamˇeti. Sloˇzitˇejˇs´ım oper´atorem byl d´ale OrderBy pˇredevˇs´ım kvuli ˚ nutnosti implementace QuickSort jako efektivn´ıho algoritmu tˇr´ıdˇen´ı. Ten byl nakonec implementov´an mimo tˇr´ıdu samotn´eho oper´atoru OrderBy pro moˇznost opakovan´eho vyuˇzit´ı tˇr´ızen´ı MyList. Kromˇe vˇsech vyˇ ´ se popsanych ´ principi´alnˇe duleˇ ˚ zitych ´ tˇr´ıd se ve skuteˇcn´e implementaci objevuje velk´e mnoˇzstv´ı dalˇs´ıch pomocnych konverzn´ıch funkc´ı atd. ´ struktur, metod, promˇennych, ´ Ty ale nejsou z hlediska popisu funkˇcnosti procesoru uplnˇ e podstatn´e. V pˇr´ıpadˇe, zˇ e by se pr´ace ´ d´ale rozˇsiˇrovala, bylo by potˇreba vytvoˇrit kompletn´ı program´atorskou dokumentaci. V tuto chv´ıli je samotny´ zdrojovy´ kod ´ relativnˇe detailnˇe okomentov´an a n´azvy vˇsech identifik´atoru˚ by do urˇcit´e m´ıry mˇely byt ´ samopopisn´e. K udrˇzov´an´ı program´atorsk´e dokumentace by bylo moˇzn´e vyuˇz´ıt napˇr. n´astroje Doxygen, ktery´ umoˇznuje automatick´e generov´an´ı syst´emu HTML str´anek ˇ na z´akladˇe koment´arˇ u˚ a samotn´eho kodu. ´
62
5
Experiment´aln´ı vyhodnocov´an´ı
Tato kapitola demonstruje na uk´azkovych ´ XQuery dotazech naimplementovany´ algebraicky´ procesor. Vˇsechny testy probˇehly na PC s konfigurac´ı uveden´e v tabulce 10. CPU Operaˇcn´ı pamˇet’ Operaˇcn´ı syst´em
Intel Core 2 Duo E7300, 2.66 GHz 4 GB Microsoft Windows 7 Proffesional 64-bit
Tabulka 10: Konfigurace testovac´ıho PC Testovac´ı XML dokument je zjednoduˇsen´ım dokumentu z testu˚ XMark [17]. Z´akladn´ı parametry jsou uvedeny tabulce 11. Dokument je souˇca´ st´ı CD pˇr´ılohy t´eto pr´ace. Velikost souboru Poˇcet XML uzlu˚ Poˇcet elementu˚ Maxim´aln´ı zanoˇren´ı XML
18 247 kB 313 296 271 848 12 urovn´ ı ´
Tabulka 11: Parametry testovac´ıho XML dokumentu
5.1
Srovn´an´ı jinych ´ implementac´ı
N´asleduje celkem 13 testu, ˚ jejichˇz uˇ ´ celem je jednak prezentace vˇetˇsiny implementovanych ´ konstrukc´ı jazyka XQuery a jednak porovn´an´ı d´elek bˇehu s jinymi dostupnymi procesory. ´ ´ Pro srovn´an´ı byly vybr´any implementace Saxon [10] a Xml Prime [2]. Oba tyto procesory jsou volnˇe dostupn´e pro nekomerˇcn´ı pouˇzit´ı. Kaˇzdy´ dotaz byl na vˇsech implementac´ıch spuˇstˇen celkem ˇ 5 kr´at, aby nedoˇslo k zav´adˇej´ıc´ım vysledk um byly mˇerˇ en´e ve ´ ˚ kvuli ˚ n´ahodnym ´ odchylk´am. Casy vˇsech pˇr´ıpadech pouze na vykon´av´an´ı dotazu, tzn. bez parsov´an´ı vstupn´ıho XML a bez parsov´an´ı, kompilace a optimalizace dotazu. Uk´azalo se, zˇ e Xml Prime vyhodnocuje nˇekter´e cˇ a´ sti dotazu aˇz bˇehem iterov´an´ı pˇres vyslednou sekvenci. Do cˇ asu je tedy zahrnuta jedna pr´azdn´a iterace pˇres ´ vysledek. ´ Souˇca´ st´ı kaˇzd´eho testu je vstupn´ı dotaz a dvˇe tabulky. Prvn´ı vˇzdy ud´av´a vysledn´ e cˇ asy v mili´ ˇ sekund´ach. R´adek Procesor pˇrestavuje cˇ asy pro n´asˇ implementovany´ procesor. Byly mˇerˇ eny cˇ asy prvn´ıho a druh´eho bˇehu dotazu. U vˇsech procesoru˚ je pˇri druh´em bˇehu evidentn´ı vyuˇz´ıv´an´ı pˇredalokovanych ´ objektu˚ z bˇehu prvn´ıho. Jsou uvedeny vˇzdy nejmenˇs´ı zjiˇstˇen´e cˇ asy. Druh´a tabulka se v´azˇ e k naˇsemu procesoru a slouˇz´ı jako pˇrehled poˇctu vytvoˇrenych ´ instanc´ı pro jednotliv´e typy datov´eho modelu v prvn´ım bˇehu. Sloupec Req pˇredstavuje poˇcet poˇzadavku˚ na vytvoˇren´ı objektu dan´eho typu, sloupec New ud´av´a, kolik instanc´ı bylo skuteˇcnˇe vytvoˇreno (viz recyklace instanc´ı v kap. 4.4.2). Vstupn´ı dotaz je uveden v takov´em tvaru, aby vyhovˇel naˇsemu procesoru. Pˇri spouˇstˇen´ı dotazu˚ na procesorech podle standardu W3C je potˇreba v nˇekterych ´ pˇr´ıpadech upravit n´azvy funkc´ı – obvykle m´ısto distinct pouˇz´ıt fn:distinct-values.
63
Test 1: Test generov´an´ı XML ulzu˚ for $ i in 1 to 100000 return { $ i }
Procesor Saxon Xml Prime
1. bˇeh 324 ms 375 ms 906 ms
2. bˇeh 84 ms 297 ms 687 ms
Req 400 002 200 000 2 100 000 0 0
sekvence n-tice tabulka integer double string
New 400 002 200 000 2 100 000 0 0
boolean Xml element Xml atribut Xml text Xml dokument Xml koment´arˇ
Req 0 100 000 0 100 000 0 0
New 0 100 000 0 100 000 0 0
Tento test je zamˇerˇ eny´ pˇredevˇs´ım na generov´an´ı vˇetˇs´ıho mnoˇzstv´ı DOM objektu, ˚ v tomto pˇr´ıpadˇe XML elementu. ˚ Bˇehem vyhodnocov´an´ı musel n´asˇ procesor pˇrev´est relativnˇe velk´e mnoˇzstv´ı celoˇc´ıselnych ´ poloˇzek na n-tice a vytvoˇrit mnoho d´ılˇc´ıch sekvenc´ı pro sestaven´ı obsahu vysledn ych ´ ´ elementu. ˚ Test 2: Generov´an´ı prvoˇc´ısel for $ i in 2 to 1000 where every $x in (2 to $ i − 1) s a t i s f i e s ( $ i mod $x != 0) return $ i
Procesor Saxon Xml Prime
1. bˇeh 115 ms 63 ms 187 ms
2. bˇeh 112 ms 15 ms 47 ms
sekvence n-tice tabulka integer double string
Req 500 669 999 000 2 000 57 8521 0 0
New 1 999 3 994 4 1 999 0 0
boolean Xml element Xml atribut Xml text Xml dokument Xml koment´arˇ
Req 79 021 0 0 0 0 0
New 1 0 0 0 0 0
V tomto pˇr´ıpadˇe byl testov´an zanoˇreny´ kvantifikovany´ vyraz. Ve druh´em bˇehu procesory Saxon ´ a Xml Prime pravdˇepodobnˇe l´epe vyuˇzily pˇredalokovan´e pamˇeti. Test 3: Jednoduch´y XPath se jmenn´ym testem a navigac´ı na descendant-or-self / / item
Procesor Saxon Xml Prime
1. bˇeh 21 ms 47 ms 109 ms
2. bˇeh 20 ms 0 ms 0 ms
sekvence n-tice tabulka integer double string
Req 1 0 0 0 0 0
New 1 0 0 0 0 0
boolean Xml element Xml atribut Xml text Xml dokument Xml koment´arˇ
Req 0 0 0 0 0 0
New 0 0 0 0 0 0
Z tabulky vzniklych ı) sekvence. Vˇsechny ´ instanc´ı je vidˇet, zˇ e bylo potˇreba pouze jedin´e (vystupn´ ´ XML uzly byly vytvoˇreny bˇehem parsov´an´ı XML. Uzlu˚ item je v dokumentu celkem 6 586.
64
Test 4: Iterov´an´ı sekvenc´ı poloˇzek for $item in / / item return $item
Procesor Saxon Xml Prime
1. bˇeh 30 ms 47 ms 109 ms
2. bˇeh 23 ms 0 ms 0 ms
sekvence n-tice tabulka integer double string
Req 6 588 13 172 2 0 0 0
New 6 588 13 172 2 0 0 0
boolean Xml element Xml atribut Xml text Xml dokument Xml koment´arˇ
Req 0 0 0 0 0 0
New 0 0 0 0 0 0
Jedn´a se o podobny´ dotaz jako v pˇredchoz´ım pˇr´ıpadˇe. Zde je ovˇsem rozd´ıl v tom, zˇ e procesor mus´ı poloˇzky ze vstupn´ı sekvence z duvodu FLWOR vyrazu pˇrev´est na n-tice. Pˇredchoz´ı dotaz ˚ ´ byl v procesorech Saxon a Xml Prime pravdˇepodobnˇe normalizov´an, takˇze XPath musel byt ´ pˇreveden na FLWOR. To by mohlo vysvˇetlovat, proˇc jsou vysledky u Saxonu a Xml Prime ´ v porovn´an´ı s pˇredchoz´ım testem velmi podobn´e, zat´ımco u naˇseho procesor je pozorovateln´a mal´a zmˇena.
Test 5: FLWOR v kombinaci s XPath for $item in / / item where $item / @id = ”item1853” return $item
Procesor Saxon Xml Prime
1. bˇeh 31 ms 109 ms 156 ms
2. bˇeh 25 ms 0 ms 0 ms
sekvence n-tice tabulka integer double string
Req 6 589 13 172 2 0 0 0
New 3 13 172 2 0 0 0
boolean Xml element Xml atribut Xml text Xml dokument Xml koment´arˇ
Req 6 586 0 0 0 0 0
New 1 0 0 0 0 0
Tento test ukazuje na rychlostn´ı pˇrevahu naˇseho procesoru pˇri prvn´ım bˇehu a naopak ztr´atu pˇri druh´em bˇehu. Saxon a Xml Prime zˇrejmˇe dok´azˇ ´ı vyuˇz´ıt nˇejakych ´ informac´ı z pˇredchoz´ıho bˇehu dotazu.
65
Test 6: Dotaz s kvantifikovan´ym v´yrazem for $item in / / item [ location = ”United S t a t e s ”] where some $cat in $item / incategory / @category s a t i s f i e s $cat = ”category418” return $item
Procesor Saxon Xml Prime
1. bˇeh 69 ms 125 ms 187 ms
2. bˇeh 57 ms 31 ms 31 ms
Req 21 284 59 394 9 791 0 0 0
sekvence n-tice tabulka integer double string
New 4 912 22 978 7 0 0 0
boolean Xml element Xml atribut Xml text Xml dokument Xml koment´arˇ
Req 29 653 0 0 0 0 0
New 1 0 0 0 0 0
Testovac´ı dotaz 6 prezentuje moˇznosti kvantifikovanych u. ´ vyraz ´ ˚ Prvn´ı bˇeh byl pˇribliˇznˇe dvakr´at kratˇs´ı oproti Saxonu a XmlPrime, ve druh´em bˇehu ale byla ztr´ata.
Test 7: Uk´azka pouˇzit´ı pˇr´ım´ych konstruktoru˚ distinct ( for $item in / / item [ location = ”United S t a t e s ”] l e t $location := $item / location / t e x t ( ) l e t $quantity := $item / quantity / t e x t ( ) c a s t as double order by $quantity return - Location : { $location } , Price : { $quantity ∗ 24.57 }
)
Procesor Saxon Xml Prime
1. bˇeh 194 ms 359 ms 375 ms
2. bˇeh 110 ms 140 ms 78 ms
sekvence n-tice tabulky integer double string
Req 193 209 52 316 7 0 9 786 0
New 186 623 52 316 7 0 9 786 0
boolean Xml element Xml atribut Xml text Xml dokument Xml koment´arˇ
Req 6 586 4 893 0 19 572 0 0
New 1 4 893 0 19 572 0 0
Dotaz ukazuje pouˇzit´ı pˇr´ımych konstruktoru˚ prokl´adanych vnoˇrenymi vypoˇ ´ ´ ´ ´ cty. Jedn´a se o vypoˇ ´ cet ceny poloˇzky na z´akladˇe jednotkov´e ceny a mnoˇzstv´ı.
66
Test 8: Uk´azka poˇc´ıt´an´ı souhrnu˚ for $region in / s i t e / regions for $item in $region / / item l e t $count := count ( $item / / incategory ) order by $count return
Procesor Saxon Xml Prime
1. bˇeh 168 ms 218 ms 421 ms
2. bˇeh 82 ms 78 ms 125 ms
Req 245 840 39 518 6 6 586 0 0
sekvence n-tice tabulka integer double string
New 219 496 39 518 6 6 586 0 0
boolean Xml element Xml atribut Xml text Xml dokument Xml koment´arˇ
Req 0 6 586 13 172 0 0 0
New 0 6 586 13 172 0 0 0
Tento dotaz ukazuje jednak pouˇzit´ı dvou klauzul´ı for a jednak praktick´e poˇc´ıt´an´ı souhrnu˚ pomoc´ı funkce count.
Test 9: Poˇc´ıt´an´ı souhrnu˚ s generov´an´ım XML <summary> { for $location in d i s t i n c t ( / / location / t e x t ( ) ) l e t $count := count ( / / item [ location = $location ] ) return - { $location } location > {$count } count>
}
Procesor Saxon Xml Prime
1. bˇeh 9 565 ms 1 687 ms 343 ms
2. bˇeh 8 094 ms 1 531 ms 79 ms
sekvence n-tice tabulka integer double string
Req 1 537 562 3 056 832 467 232 0 0
New 9 610 3 056 832 467 232 0 0
boolean Xml element Xml atribut Xml text Xml dokument Xml koment´arˇ
Req 1 527 952 697 0 930 0 0
New 1 697 0 930 0 0
V tomto testu se bohuˇzel n´asˇ procesor uk´azal jako neefektivn´ı v porovn´an´ı se Saxonem a Xml Prime. Sp´ısˇ e neˇz na sˇ patnou implementaci toto ukazuje na chybˇej´ıc´ı optimalizaci. Ke zlepˇsen´ı by mˇelo v´est zaveden´ı oper´atoru GroupBy (kapitola 3.4.6). Srovn´an´ı s procesorem Xml Prime ale nemus´ı byt e korektn´ı, jelikoˇz testov´an´ım se ukazuje, zˇ e Xml Prime prov´ad´ı skuteˇcn´e ´ uplnˇ ´ vyhodnocen´ı nˇekterych eho XML stromu dotazu aˇz pˇri fyzick´em cˇ ten´ı ´ zanoˇrenych ´ cˇ a´ st´ı vysledn´ ´ hodnot. Obsahy uzlu˚ location a count zustaly pravdˇepodobnˇe nevypoˇcten´e. ˚
67
Test 10: Uk´azka podm´ınˇen´ych v´yrazu˚ for $item in / / item l e t $info := i f ( $item / location = ”United S t a t e s ”) then $item / payment else $item / quantity l e t $name := $item /name return
Procesor Saxon Xml Prime
1. bˇeh 116 ms 187 ms 390 ms
2. bˇeh 79 ms 62 ms 109 ms
Req 59 276 39 516 4 0 0 0
sekvence n-tice tabulka integer double string
New 39 518 39 516 4 0 0 0
boolean Xml element Xml atribut Xml text Xml dokument Xml koment´arˇ
Req 6 586 6 586 13 172 0 0 0
New 1 6 586 13 172 0 0 0
Uk´azka m´a sp´ısˇ e prezentovat moˇznost pouˇzit´ı podm´ınˇenych u. ´ vyraz ´ ˚
Test 11: Pouˇzit´ı konstrukce typeswitch for $item in ( 1 , ”a ” , 2 . 7 8 , ” true ” c a s t as boolean , 10) l e t $typeInfo := typeswitch ( $item ) case s t r i n g return ” s t r i n g ” case integer return ” integer ” case double return ”double ” case boolean return ”boolean ” default return ”undefined ” return $typeInfo
Procesor Saxon Xml Prime
1. bˇeh 0 ms 31 ms 140 ms
2. bˇeh 0 ms 0 ms 0 ms
sekvence n-tice tabulka integer double string
Req 17 30 3 0 0 0
New 17 30 3 0 0 0
boolean Xml element Xml atribut Xml text Xml dokument Xml koment´arˇ
Req 13 0 0 0 0 0
New 2 0 0 0 0 0
Jedn´a se o velmi jednoduchy´ dotaz, ktery´ sp´ısˇ e demonstruje pouˇzit´ı konstrukce typeswitch. V naˇsem procesoru je testov´an´ı datovych ´ typu˚ podporov´ano pouze cˇ a´ steˇcnˇe – je moˇzn´e testovat poloˇzky na typ skal´arn´ı hodnoty. Relativnˇe zaj´ımav´e je cˇ asov´e srovn´an´ı, kter´e ukazuje na reˇzijn´ı z´aleˇzitosti ohlednˇe kaˇzd´eho dotazu.
68
Test 12: Uk´azka generov´an´ı pˇrehledov´eho XML for $location in d i s t i n c t ( / / location / t e x t ( ) ) return { $location } location > { for $item in / / item [ location = $location ] return }
Procesor Saxon Xml Prime
1. bˇeh 9 905 ms 1 750 ms 734 ms
2. bˇeh 8 140 ms 1 547 ms 344 ms
sekvence n-tice tabulka integer double string
Req 1 570 952 3 069 540 930 0 0 0
New 29 828 3 069 540 930 0 0 0
boolean Xml element Xml atribut Xml text Xml dokument Xml koment´arˇ
Req 1 527 952 7 282 6 586 1 160 0 0
New 1 7 282 6 586 1 160 0 0
Jedn´a se podobnˇe problematicky´ dotaz jako v testu 9. Zde je opˇet patrn´a vysok´a ztr´ata na Saxon a Xml Prime. Dotaz ukazuje moˇznost generov´an´ı sloˇzitˇejˇs´ıho souhrnov´eho XML.
Test 13: Pouˇzit´ı tˇr´ızen´ı ve FLWOR v´yrazu for $item in / / item l e t $name := $item /name/ t e x t ( ) order by $name return $item
Procesor Saxon Xml Prime
1. bˇeh 87 ms 203 ms 219 ms
2. bˇeh 64 ms 78 ms 16 ms
sekvence n-tice tabulka integer double string
Req 19 760 39 516 4 0 0 0
New 19 760 39 516 4 0 0 0
boolean Xml element Xml atribut Xml text Xml dokument Xml koment´arˇ
Req 0 0 0 0 0 0
New 0 0 0 0 0 0
Posledn´ım testem je uk´azka tˇr´ızen´ı poloˇzek ve FLWOR vyrazu. V souˇcasn´e implementaci se ´ pro tˇr´ızen´ı pouˇz´ıv´a algoritmus Quick sort. Pro lexikografick´e tˇr´ızen´ı by minim´alnˇe st´aly za vyzkouˇsen´ı i jin´e algoritmy, napˇr. Radix sort.
69
5.1.1
Shrnut´ı cˇ asovych ´ srovn´an´ı
Testov´an´ım se uk´azalo, zˇ e n´asˇ procesor ve vˇetˇsinˇe pˇr´ıpadu˚ pod´av´a srovnateln´e nebo dokonce lepˇs´ı vysledky neˇz existuj´ıc´ı implementace. Grafick´e porovn´an´ı vysledk u˚ je zn´azornˇeno na obr. 29. Na ´ ´ druhou stranu byly i dotazy (9 a 12), kde byla evidentn´ı velk´a ztr´ata. Tato ztr´ata ale sp´ısˇ e neˇz na moˇznost sˇ patn´e implementace datovych ´ struktur ukazuje na chybˇej´ıc´ı optimalizaci spojuj´ıc´ı vnitˇrn´ı zanoˇreny´ FLWOR s vnˇejˇs´ım FLWOR nebo XPath. U procesoru˚ Saxon a Xml Prime je potˇreba zohlednit jejich dlouholety´ vyvoj (Xml Prime od roku 2009, Saxon od r. 1998) a spolupr´aci vˇetˇs´ıho ´ mnoˇzstv´ı lid´ı nejen na samotn´e implementaci, ale tak´e na testov´an´ı. Tato implementace minim´alnˇe otev´ır´a moˇznosti k dalˇs´ım optimalizac´ım. Dalˇs´ı moˇznosti zlepˇsen´ı efektivity se skryvaj´ ´ ı napˇr´ıklad v pouˇz´ıv´an´ı sofistikovanˇejˇs´ıch metod pro evaluaci XPath vyraz u, ´ ˚ kdy jednotliv´e cˇ a´ sti nejsou zpracov´av´any postupnˇe, ale na XPath je pohl´ızˇ eno jako na celek (kap. 3.4.6). Zaj´ımavou moˇznost´ı by mohl byt ´ napˇr. dalˇs´ı pˇreklad z pl´anu vykon´av´an´ı pˇr´ımo do strojov´eho kodu. ´
[ms]
[ms]
1000
12000
900 10000
800
700
8000
600
500
6000
400 4000
300 200
2000
100 0
0 Test 1
Test 2
Test 3
Procesor 1
Test 4
Procesor 2
Test 5
Saxon 1
Test 6
Test 7
Saxon 2
Test 8
Xml Prime 1
Test 10
Test 11
Test 13
Xml Prime 2
Test 9
Test 12
Problematické dotazy
Obr´azek 29: Srovn´an´ı cˇ asu˚ jednotlivych ´ procesoru˚
5.2
Vliv optimalizac´ı na d´elku bˇehu
N´asleduj´ıc´ı dva testy jsou zamˇerˇ eny na vliv optimalizac´ı nadefinovanych ´ v kapitole 3.4 na dobu vyhodnocov´an´ı.
70
Test 14: Optimalizace spojen´ım kroku˚ XPath Tento test ukazuje srovn´an´ı doby vykon´av´an´ı bez a s optimalizac´ı spojen´ım kroku˚ XPath (kap. 3.4.5). Jako uk´azkovy´ dotaz slouˇz´ı dotaz z testu 8.
for $region in / s i t e / regions for $item in $region / / item l e t $count := count ( $item / / incategory ) order by $count return
Bez optimalizace S optimalizac´ı
1. bˇeh 298 ms 168 ms
2. bˇeh 192 ms 82 ms
Z vysledk u˚ je viditelny´ podstatny´ rozd´ıl, zejm´ena pˇri druh´em bˇehu dotazu. ´
Test 15: Optimalizace odstranˇen´ım MapConcat a MapToItem V tomto testu je srovn´ana doba vykon´av´an´ı bez a s optimalizac´ı odstranˇen´ım MapConcat a MapToItem (kap. 3.4.1 a 3.4.2). Jako uk´azkovy´ dotaz je vyuˇzit dotaz z testu 2.
for $ i in 2 to 1000 where every $x in (2 to $ i − 1) s a t i s f i e s ( $ i mod $x != 0) return $ i
Bez optimalizace S optimalizac´ı
1. bˇeh 258 ms 115 ms
2. bˇeh 255 ms 112 ms
Z vysledk u˚ je pozorovateln´e t´emˇerˇ dvojn´asobn´e zlepˇsen´ı vykonu procesoru. ´ ´
71
6
Z´avˇer
Vysledkem pr´ace je funkˇcn´ı algebraicky´ XQuery procesor, ktery´ vych´az´ı ze specifikace W3C, ´ podporuje z´akladn´ı konstrukce jazyka XQuery od aritmetickych operac´ı pˇres logick´e operace, ´ pr´aci se sekvencemi pomoc´ı FLWOR a XPath vyraz u˚ aˇz po konstrukce jako alternativy a vˇetven´ı ´ dle datov´eho typu.
6.1
Vlastn´ı pˇr´ınos a moˇznosti rozˇs´ırˇen´ı
Vlastn´ım pˇr´ınosem t´eto pr´ace je pˇredevˇs´ım modul´arnˇe navrˇzeny´ syst´em, jehoˇz cˇ a´ sti mohou byt ´ v budoucnu d´ale rozˇsiˇrov´any vˇetˇs´ım tymem lid´ı. Naimplementovany´ procesor pˇristupuje ke ´ kompilaci XQuery dotazu˚ bez pˇredchoz´ı normalizace, coˇz muˇ ˚ ze usnadnit napˇr. vyhled´av´an´ı stromovych ´ vzoru˚ pro efektivn´ı vykon´av´an´ı na indexovanych ´ datab´az´ıch. D´ale se zde objevuj´ı specifick´e optimalizace (kapitola 3.4) a n´avrhy algoritmu˚ na rˇ eˇsen´ı navigac´ı v XML dokumentech (kapitola 4.8.3). Tato pr´ace otev´ır´a velk´e moˇznosti pro vyvoj a testov´an´ı ruzn optimalizaˇcn´ıch postupu˚ ´ ˚ ych ´ a fyzickych algoritmu˚ rˇ eˇs´ıc´ıch funkˇcnost jednotlivych oper´atoru. ´ ´ ˚ Re´alnym ´ c´ılem je vyuˇz´ıv´an´ı TPQ pro vyhodnocov´an´ı vyraz u˚ FLWOR podle [14]. Pˇr´ınosem je tak´e samotny´ naimplementovany´ ´ procesor, ktery´ je pro bˇezˇ n´e uˇ ´ cely prakticky pouˇzitelny. ´
6.2
Osobn´ı zhodnocen´ı
Jelikoˇz se jiˇz delˇs´ı dobu prakticky pohybuji v oblasti vyvoje informaˇcn´ıch syst´emu˚ (bakal´arˇ sk´a ´ pr´ace [12]) od n´avrhu a tvorby datab´az´ı, pˇres implementaci GUI, aˇz po komunikaci s koncovymi ´ z´akazn´ıky, bylo mym vybrat si takov´e t´ema, kter´e by mi umoˇznilo nahl´ednout do pozad´ı ´ umyslem ´ technologi´ı, kter´e v´ıce nebo m´enˇe pouˇz´ıv´am. Puvodn´ ım z´amˇerem bylo vytvoˇrit funkˇcn´ı procesor ˚ SQL, avˇsak vzhledem k relativn´ı nasycenosti trhu standardn´ımi relaˇcn´ımi datab´azovymi stroji ´ byla volba XQuery minim´alnˇe z hlediska studia zaj´ımavˇejˇs´ı. Nejsloˇzitˇejˇs´ım ukolem na cel´e pr´aci bylo zorientovat se ve velk´em mnoˇzstv´ı informac´ı ohlednˇe ´ XML technologi´ı. Jak bylo v kapitole 2.3.4 uvedeno, XQuery uzce souvis´ı s jinymi dotazovac´ımi ´ ´ jazyky, takˇze krom studia standardu XQuery bylo potˇreba nahl´ızˇ et tak´e do specifikac´ı XPath a XML. Podrobn´e detailn´ı zkoum´an´ı vˇsech tˇechto standardu˚ by vyˇzadovalo mnohem delˇs´ı dobu a spolupr´aci vˇetˇs´ıho mnoˇzstv´ı lid´ı. To je duvodem, proˇc se tento procesor muˇ ˚ ˚ ze od specifikace liˇsit.
72
Reference [1] W3C. W3Schools [online].
1999-2012
[cit.
2012-02-05].
Dostupn´e
z:
[2] CLINICAL & BIOMEDICAL COMPUTING LTD. XML Prime [online]. 2009-2012 [cit. 201204-09]. Dostupn´e z: [3] W3C. Extensible Markup Language (XML) 1.1 (Second Edition) [online]. 2006 [cit. 2012-01-24]. Dostupn´e z: [4] W3C. XML Path Language (XPath) 2.0 (Second Edition) [online]. 2010 [cit. 2012-02-10]. Dostupn´e z: [5] W3C. XQuery 1.0: An XML Query Language (Second Edition) [online]. 2010 [cit. 2012-02-03]. Dostupn´e z: [6] W3C. XQuery 1.0 and XPath 2.0 Data Model (XDM) (Second Edition) [online]. 2010 [cit. 201203-20]. Dostupn´e z: [7] W3C. XQuery 1.0 and XPath 2.0 Formal Semantics (Second Edition) [online]. 2010 [cit. 201203-20]. Dostupn´e z: [8] WIKIPEDIE. Lexik´aln´ı anal´yza [online]. 2011
[cit.
2012-01-27].
Dostupn´e
z:
ˇ ˇ – Technick´a [9] BRUSKA, Filip. Normalizace XQuery dotazu. ˚ Ostrava, 2010. Diplomov´a pr´ace. VSB univerzita Ostrava. [10] KAY, Michael H. SAXON: The XSLT and XQuery Processor [online]. 2011 [cit. 2012-02-05]. Dostupn´e z: [11] A simple proof for the turing-completeness of xslt and xquery [online]. 2006 [cit. 2012-04-11]. Dostupn´e z: ´ S, ˇ Petr. Absolvov´an´ı individu´aln´ı odborn´e praxe [online]. Ostrava, 2010 [cit. 2012-04-11]. [12] LUKA ˇ – Technick´a univerzita Ostrava. Bakal´arˇ sk´a pr´ace. VSB [13] MANOLESCU, Ioana, PAPAKONSTANTINOU a Vasilis VASSALOS. Xml tuple algebra [online]. 2009 [cit. 2012-04-11]. Dostupn´e z: ˇ A ˇ ´ [14] MICHIELS, Philippe, George A. MIHAIL a J´erom SIMEON. Put ˆ tree pattern in your algebra [online]. 2007 [cit. 2012-04-11]. Dostupn´e
a z:
[15] ROBIE, Jonathan, Don CHAMBERLIN a Daniela FLORESCU. Quilt: An xml query language [online]. 2000 [cit. 2012-04-11]. Dostupn´e z:
73
´ Christopher, J´erom ´ ´ [16] RE, SIMEON a Mary FERNANDEZ. A complete and effiˆ cient algebraic compiler for xquery [online]. 2006 [cit. 2012-04-11]. Dostupn´e z: [17] XMark-An XML Benchmark Project
[online].
74
[cit.
2012-04-25].
Dostupn´e
z:
A
Vestavˇen´e funkce
add Dvouparametrov´a funkce pro sˇc´ıt´an´ı cˇ ´ıselnych ´ poloˇzek nebo spojov´an´ı textovych ´ rˇ etˇezcu. ˚ add(a, b) → c a
b
c
integer
integer
integer
souˇcet cˇ ´ısel
integer
double
double
souˇcet cˇ ´ısel
double
integer
double
souˇcet cˇ ´ısel
double
integer
double
souˇcet cˇ ´ısel
string
sequence
string
zˇretˇezen´ı po serializaci sekvence
string
string
string
zˇretˇezen´ı
sub Dvouparametrov´a funkce pro odˇc´ıt´an´ı cˇ ´ıselnych ´ poloˇzek. sub(a, b) → c a
b
c
integer
integer
integer
rozd´ıl cˇ ´ısel
integer
double
double
rozd´ıl cˇ ´ısel
double
integer
double
rozd´ıl cˇ ´ısel
double
integer
double
rozd´ıl cˇ ´ısel
mul Dvouparametrov´a funkce pro n´asoben´ı cˇ ´ıselnych ´ poloˇzek. mul(a, b) → c a
b
c
integer
integer
integer
souˇcin cˇ ´ısel
integer
double
double
souˇcin cˇ ´ısel
double
integer
double
souˇcin cˇ ´ısel
double
integer
double
souˇcin cˇ ´ısel
div Dvouparametrov´a funkce pro desetinn´e dˇelen´ı cˇ ´ıselnych ´ poloˇzek. div(a, b) → c
75
a
b
c
integer
integer
double
pod´ıl cˇ ´ısel
integer
double
double
pod´ıl cˇ ´ısel
double
integer
double
pod´ıl cˇ ´ısel
double
integer
double
pod´ıl cˇ ´ısel
idiv Dvouparametrov´a funkce pro celoˇc´ıseln´e dˇelen´ı cˇ ´ıselnych ´ poloˇzek. idiv(a, b) → c a
b
c
integer
integer
integer
pod´ıl cˇ ´ısel bez desetinn´e cˇ a´ sti
mod Dvouparametrov´a funkce pro zbytek po celoˇc´ıseln´em dˇelen´ı. mod(a, b) → c a
b
c
integer
integer
integer
zbytek po celoˇc´ıseln´em dˇelen´ı
veq, vneq Dvouparametrov´e funkce pro hodnotov´e porovn´av´an´ı. Funkce vneq vrac´ı vˇzdy negovany´ vysledek veq. ´ veq(a, b) → c, vneq(a, b) → c
76
a
b
c
integer
integer
boolean
porovn´an´ı celych ´ cˇ ´ısel
integer
double
boolean
porovn´an´ı cel´eho a desetinn´eho cˇ ´ısla
integer
boolean
boolean
porovn´an´ı cel´eho cˇ ´ısla a booleovsk´e hodnoty pˇreveden´e na 1 nebo 0
double
integer
boolean
porovn´an´ı desetinn´eho a cel´eho cˇ ´ısla
double
double
boolean
porovn´an´ı dvou desetinnych ´ cˇ ´ısel
string
string
boolean
porovn´an´ı celych ´ cˇ ´ısel
string
xml-attribute
boolean
porovn´an´ı textov´eho rˇ etˇezce a hodnoty atributu
string
xml-element
boolean
porovn´an´ı textov´eho rˇ etˇezce s textovym ´ obsahem elementu
string
xml-text
boolean
porovn´an´ı textov´eho rˇ etˇezce s obsahem textov´eho uzlu
string
xml-comment
boolean
porovn´an´ı textov´eho rˇ etˇezce s koment´arˇ em
xml-attribute
xml-attribute
boolean
porovn´an´ı hodnot dvou atributu˚
xml-attribute
string
boolean
porovn´an´ı hodnoty atributu a textov´eho rˇ etˇezce
xml-attribute
xml-element
boolean
porovn´an´ı hodnoty atributu s textovym ´ obsahem elementu
xml-attribute
xml-text
boolean
porovn´an´ı hodnoty atributu s obsahem textov´eho uzlu
xml-attribute
xml-comment
boolean
porovn´an´ı hodnoty atributu s koment´arˇ em
xml-element
xml-element
boolean
porovn´an´ı struktury celych ´ elemtnu˚ vˇcetnˇe obsahu
xml-element
xml-attribute
boolean
porovn´an´ı textov´eho obsahu elementu s hodnotou atributu
xml-element
string
boolean
porovn´an´ı textov´eho obsahu elementu s textovym ´ rˇ etˇezcem
xml-element
xml-text
boolean
porovn´an´ı textov´eho obsahu elementu s obsahem textov´eho uzlu
xml-element
xml-comment
boolean
porovn´an´ı textov´eho obsahu elementu s koment´arˇ em
xml-text
xml-text
boolean
porovn´an´ı textu˚ dvou textovych ´ uzlu˚
xml-text
xml-element
boolean
porovn´an´ı obsahu textov´eho uzlu s textovym ´ obsahem elementu
xml-text
xml-attribute
boolean
porovn´an´ı obsahu textov´eho uzlu s hodnotou atributu
xml-text
string
boolean
porovn´an´ı obsahu textov´eho uzlu s textovym ´ rˇ etˇezcem
xml-text
xml-comment
boolean
porovn´an´ı textov´eho obsahu textov´eho uzlu s koment´arˇ em
xml-comment
xml-comment
boolean
porovn´an´ı dvou koment´arˇ u˚
xml-comment
xml-text
boolean
porovn´an´ı koment´arˇ e a obsahu textov´eho uzlu
xml-comment
xml-element
boolean
porovn´an´ı koment´arˇ e s textovym ´ obsahem elementu
xml-comment
xml-attribute
boolean
porovn´an´ı koment´arˇ e s hodnotou atributu
xml-comment
string
boolean
porovn´an´ı koment´arˇ e s textovym ´ rˇ etˇezcem
vlt, vgt, vle, vge Dvouparametrov´e funkce pro hodnotov´e uspoˇra´ d´an´ı datovych ´ poloˇzek. Funkce vgt odpov´ıd´a <, vlt odpov´ıd´a >, vge odpov´ıd´a ≥, vle odpov´ıd´a ≤. vlt(a, b) → c, vgt(a, b) → c, vle(a, b) → c, vge(a, b) → c
77
a
b
c
integer
integer
boolean
uspoˇra´ d´an´ı celych ´ cˇ ´ısel
integer
double
boolean
uspoˇra´ d´an´ı cel´eho a desetinn´eho cˇ ´ısla
integer
boolean
boolean
uspoˇra´ d´an´ı cel´eho cˇ ´ısla a booleovsk´e hodnoty pˇreveden´e na 1 nebo 0
double
integer
boolean
uspoˇra´ d´an´ı desetinn´eho a cel´eho cˇ ´ısla
double
double
boolean
uspoˇra´ d´an´ı dvou desetinnych ´ cˇ ´ısel
string
string
boolean
uspoˇra´ d´an´ı celych ´ cˇ ´ısel
string
xml-attribute
boolean
lexikografick´e uspoˇra´ d´an´ı textov´eho rˇ etˇezce a hodnoty atributu
string
xml-element
boolean
lexikografick´e uspoˇra´ d´an´ı textov´eho rˇ etˇezce s textovym ´ obsahem elementu
string
xml-text
boolean
lexikografick´e uspoˇra´ d´an´ı textov´eho rˇ etˇezce s obsahem textov´eho uzlu
string
xml-comment
boolean
lexikografick´e uspoˇra´ d´an´ı textov´eho rˇ etˇezce s koment´arˇ em
xml-attribute
xml-attribute
boolean
lexikografick´e uspoˇra´ d´an´ı hodnot dvou atributu˚
xml-attribute
string
boolean
lexikografick´e uspoˇra´ d´an´ı hodnoty atributu a textov´eho rˇ etˇezce
xml-attribute
xml-element
boolean
lexikografick´e uspoˇra´ d´an´ı hodnoty atributu s textovym ´ obsahem elementu
xml-attribute
xml-text
boolean
lexikografick´e uspoˇra´ d´an´ı hodnoty atributu s obsahem textov´eho uzlu
xml-attribute
xml-comment
boolean
lexikografick´e uspoˇra´ d´an´ı hodnoty atributu s koment´arˇ em
xml-element
xml-element
boolean
lexikografick´e uspoˇra´ d´an´ı textov´eho obsahu dvou elementu˚
xml-element
xml-attribute
boolean
lexikografick´e uspoˇra´ d´an´ı textov´eho obsahu elementu s hodnotou atributu
xml-element
string
boolean
lexikografick´e uspoˇra´ d´an´ı textov´eho obsahu elementu s textovym ´ rˇ etˇezcem
xml-element
xml-text
boolean
lexikografick´e uspoˇra´ d´an´ı textov´eho obsahu elementu s obsahem textov´eho uzlu
xml-element
xml-comment
boolean
lexikografick´e uspoˇra´ d´an´ı textov´eho obsahu elementu s koment´arˇ em
xml-text
xml-text
boolean
lexikografick´e uspoˇra´ d´an´ı textu˚ dvou textovych ´ uzlu˚
xml-text
xml-element
boolean
lexikografick´e uspoˇra´ d´an´ı obsahu textov´eho uzlu s textovym ´ obsahem elementu
xml-text
xml-attribute
boolean
lexikografick´e uspoˇra´ d´an´ı obsahu textov´eho uzlu s hodnotou atributu
xml-text
string
boolean
lexikografick´e uspoˇra´ d´an´ı obsahu textov´eho uzlu s textovym ´ rˇ etˇezcem
xml-text
xml-comment
boolean
lexikografick´e uspoˇra´ d´an´ı textov´eho obsahu textov´eho uzlu s koment´arˇ em
xml-comment
xml-comment
boolean
lexikografick´e uspoˇra´ d´an´ı dvou koment´arˇ u˚
xml-comment
xml-text
boolean
lexikografick´e uspoˇra´ d´an´ı koment´arˇ e a obsahu textov´eho uzlu
xml-comment
xml-element
boolean
lexikografick´e uspoˇra´ d´an´ı koment´arˇ e s textovym ´ obsahem elementu
xml-comment
xml-attribute
boolean
lexikografick´e uspoˇra´ d´an´ı koment´arˇ e s hodnotou atributu
xml-comment
string
boolean
lexikografick´e uspoˇra´ d´an´ı koment´arˇ e s textovym ´ rˇ etˇezcem
eq, eq Dvouparametrov´e funkce pro obecn´e porovn´av´an´ı. Pro jednoprvkov´e sekvence pracuj´ı funkce stejnˇe jako veq a vneq, pro v´ıceprvkov´e sekvence vrac´ı funkce pravdivou hodnotu, pokud porovn´an´ı vyhov´ı alesponˇ jedn´e dvojici poloˇzek z obou sekvenc´ı. eq(a, b) → c, neq(a, b) → c a
b
c
sequence
sequence
boolean
obecn´e porovn´an´ı sekvenc´ı
78
lt, gt, le, ge Dvouparametrov´e funkce pro obecn´e porovn´av´an´ı. Pro jednoprvkov´e sekvence pracuj´ı funkce stejnˇe jako vlt, vgt, vle a vge, pro v´ıceprvkov´e sekvence vrac´ı funkce pravdivou hodnotu, pokud porovn´an´ı vyhov´ı alesponˇ jedn´e dvojici poloˇzek z obou sekvenc´ı. lt(a, b) → c, gt(a, b) → c, le(a, b) → c, ge(a, b) → c a
b
c
sequence
sequence
boolean
obecn´e porovn´an´ı sekvenc´ı
abs Absolutn´ı hodnota cˇ ´ıseln´e poloˇzky. abs(a) → b a
b
integer
integer
absolutn´ı hodnota cel´eho cˇ ´ısla
double
double
absolutn´ı hodnota desetinn´eho cˇ ´ısla
count Poˇcet poloˇzek v sekvenci. count(a) → b a
b
sequence
integer
poˇcet poloˇzek v sekvenci
position Pozice kontextov´eho uzlu v r´amci sekvence poloˇzek, ke kter´e n´aleˇz´ı (ˇc´ıslov´ano od 1). position() → a a integer
pozice kontextov´eho uzlu
position D´elka sekvence, kter´e n´aleˇz´ı kontextovy´ uzel. last() → a
79
a integer
pozice kontextov´eho uzlu
doc Naˇcten´ı extern´ıho XML dokumentu. Pro cˇ ten´ı XML a pˇrevod na DOM je vyuˇzit Xerces Parser. Funkce argumentem pˇreb´ır´a textovy´ rˇ etˇezec reprezentuj´ıc´ı cestu k souboru. doc( f ileName) → a f ileName
a
string
xml-document
naˇcteny´ XML dokument
root Funkce vrac´ı vstupn´ı XML dokument, ktery´ je naˇcten a zpracov´an jeˇstˇe pˇred zaˇca´ tkem vyhodnocov´an´ı dotazu. root() → a a xml-document
vstupn´ı XML dokument
predicate Funkce slouˇz´ı pro vyhodnocen´ı predik´atu˚ XPath vyraz u˚ (viz 3.3.3). ´ predicate(a) → b a
b
sequence
boolean
efektivn´ı booleovsk´a hodnota
integer
boolean
booleovsk´a hodnota informuj´ıc´ı, zda pozice kontextov´eho uzlu odpov´ıd´a cˇ ´ıslu a
boolean Funkce vrac´ı tzv. efektivn´ı booleovskou hodnotu (viz 3.3.3). boolean(a) → b a
b
sequence
boolean
efektivn´ı booleovsk´a hodnota
range Funkce utvoˇr´ı sekvenci cˇ ´ısel od a do b s krokem 1.
80
range(a, b) → c a
b
c
integer
integer
sequence
sekvence cˇ ´ısel od a do b
distinct Funkce na z´akladˇe porovn´an´ı (funkce eq) prov´ad´ı odstranˇen´ı duplicit ze sekvence. Doˇslo k rozˇs´ırˇ en´ı vˇsech tˇr´ıd datov´eho modelu o metodu vracej´ıc´ı hash kl´ıcˇ , coˇz umoˇznuje relativnˇe ˇ efektivn´ı cˇ innost eliminace duplicitn´ıch hodnot podobnˇe jako v oper´atoru TreeJoin. distinct(a) → b a
b
sequence
sequence
vystupn´ ı sekvence bez duplicitn´ıh hodnot ´
avg Funkce vrac´ı prumˇ ˚ ernou hodnotu ze sekvence, jej´ızˇ poloˇzky mus´ı byt ´ explicitnˇe pˇretypovateln´e na desetinn´e cˇ ´ıslo. avg(a) → b a
b
sequence
double
prumˇ ˚ erˇ n´a hodnota
sum Funkce vrac´ı souˇcet hodnot ze sekvence, jej´ızˇ poloˇzky mus´ı byt ´ explicitnˇe pˇretypovateln´e na desetinn´e cˇ ´ıslo. sum(a) → b a
b
sequence
double
Souˇcet
min Funkce vrac´ı minim´aln´ı hodnotu ze sekvence. Podm´ınkou je, aby byly prvky v sekvenci navz´ajem porovnateln´e. min(a) → b a
b
sequence
item
minim´aln´ı hodnota
81
min Funkce vrac´ı maxim´aln´ı hodnotu ze sekvence. Podm´ınkou je, aby byly prvky v sekvenci navz´ajem porovnateln´e. max(a) → b a
b
sequence
item
maxim´aln´ı hodnota
empty Funkce vrac´ı pravdivou booleovskou hodnotu, jestliˇze je sekvence pˇredan´a argumentem pr´azdn´a.
empty(a) → b a
b
sequence
boolean
pr´azdnost sekvence
not Jednoduch´a funkce pro zjiˇstˇen´ı negovan´e booleovsk´e hodnoty. not(a) → b a
b
boolean
boolean
negovan´a hodnota
82
B
Kompatibilita datovych ´ typu˚
I – implicitn´ı a explicitn´ı pˇretypov´an´ı t1 na t2
I1
I1
I1
I1
xml-document
I1 E E E4 I E4 E4 E4 E4
xml-text
I1 E E I E I I I I
xml-node
I1 E I E3 E E3 E3 E3 E3
xml-comment
I1 I E E2 E E2 E2 E2 E2
xml-attribute
double
I I I I I I I I I I
string
sequence boolean integer string double xml-attribute xml-comment xml-node xml-text xml-document
integer
↓ t1 , t2 →
boolean
sequence
E – explicitn´ı pˇretypov´an´ı t1 na t2
I I I I I
I
Tabulka 12: Kompatibilita datovych ´ typu˚ 1
– Za pˇredpokladu, zˇ e sekvence obsahuje jedinou poloˇzku.
2
– Za pˇredpokladu, zˇ e textovy´ rˇ etˇezec, hodnota atributu, koment´arˇ e, textov´eho uzlu nebo textov´eho obsahu elementu je “0”, “1”, “true” nebo “false”.
3
– Za pˇredpokladu, zˇ e textovy´ rˇ etˇezec, hodnota atributu, koment´arˇ e, textov´eho uzlu nebo textov´eho obsahu elementu reprezentuje cel´e cˇ ´ıslo.
4
– Za pˇredpokladu, zˇ e textovy´ rˇ etˇezec, hodnota atributu, koment´arˇ e, textov´eho uzlu nebo textov´eho obsahu elementu reprezentuje desetinn´e cˇ ´ıslo.
83
C
Spustitelny´ procesor
Samostatnˇe spustitelny´ procesor je moˇzn´e nal´ezt na pˇriloˇzen´em CD k t´eto pr´aci. Jeho obsluha je snadn´a: XQueryProcessor.exe <soubor XML> <souboru s dotazem> []
Specifikace vystupn´ ıho souboru je nepovinn´a, v pˇr´ıpadˇe, zˇ e vystup nen´ı definov´an, vyp´ısˇ e se ´ ´ vysledek dotazu pˇr´ımo na monitor. ´ Spustitelny´ soubor pouze demonstruje jedno z vyuˇzit´ı procesoru. Souˇca´ st´ı pˇriloˇzen´eho CD jsou zdrojov´e soubory s projektem pro Microsoft Visual Studio 2005. Praktick´e uplatnˇen´ı spoˇc´ıv´a ve vyuˇzit´ı techto zdrojovych souboru˚ jako komponenty pro implementaci jinych rozs´ahlejˇs´ıch ´ ´ projektu˚ vyuˇz´ıvaj´ıc´ıch moˇznosti vyhled´av´an´ı v XML. Obsah CD je bl´ızˇ e specifikov´an souborem ,,Obsah.pdf“, ktery´ je um´ıstˇen v koˇrenov´em adres´arˇ i.
84