1 / 51

Static Typing in XQuery

Static Typing in XQuery. Based on Xquery from the Experts [Katz], chap 4 Presented by Iris Rudner. Intro. Xquery implementations must support dynamic typing, and may support static typing.

leona
Télécharger la présentation

Static Typing in XQuery

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

E N D

Presentation Transcript


  1. Static Typing in XQuery Based on Xquery from the Experts [Katz], chap 4 Presented by Iris Rudner

  2. Intro • Xquery implementations must support dynamic typing, and may support static typing. • Objective: How to use the Xquery type system to write type-safe queries, how to understand and resolve type errors and how to work around the type system when necessary.

  3. The Benefits of Static Typing • Can help by detecting common type errors during static analysis instead of being discovered only when the program is run. • A type error occurs when the type of an expression is not compatible with the type required by the context in which the expression is used.

  4. The Benefits of Static Typing (cont.) • Static typing is conservative. For example: expression of type element(surgeon) | element(plumber) in a context requiring element(surgeon) • Static typing allows to detect all type errors. Cannot detect errors such as divide-by-zero or array-bounds-overflow.

  5. An Xquery Programming Scenario <xs:schema targetNamespace=http://example.com.auction xmlns:xs=http://www.w3.org/2001/XMLSchema xmlns="http://www.example.com/auction"> <xs:element name="auction"><xs:complexType><xs:sequence><xs:element name="users"/><xs:element name="articles"/><xs:element name="bids"/></xs:sequence></xs:complexType> </xs:element><xs:element name="users"><xs:complexType><xs:element ref="user" maxOccurs="unbounded"/></xs:complexType> </xs:element> XML Schema for the Relational Auction Data:

  6. <xs:element name="articles"><xs:complexType><xs:element ref="article" maxOccurs="unbounded"/></xs:complexType> </xs:element> <xs:element name="bids"> <xs:complexType><xs:element ref="bid" maxOccurs="unbounded"/></xs:complexType> </xs:element><xs:element name="rating" type="xs:string"/><xs:element name="user" type="User"/><xs:complexType name="User"><xs:sequence><xs:element name="name"><xs:complexType name=""><xs:element name="first" type="xs:string" minOccurs="0"/><xs:element name="last" type="xs:string"/></xs:complexType></xs:element><xs:element ref="rating" minOccurs="0"/></xs:sequence><xs:attribute name="id" type="xs:ID" use="required"/></xs:complexType>

  7. <xs:attribute name="idref" type="xs:IDREF"/><xs:element name="article" type="Article"/> <xs:complexType name="Article"><xs:sequence><xs:element name="name" type="xs:string"/> <xs:element name="seller"><xs:complexType><xs:attribute ref="idref" use="required"/></xs:complexType></xs:element><xs:element name="start_date" type="xs:date"/><xs:element name="end_date" type="xs:date"/><xs:element name="reserve_price" type="xs:decimal"/><xs:element name="description" type="Freeform" minOccurs="0"/> </xs:sequence><xs:attribute name="id" type="xs:ID" use="required"/> </xs:complexType> … etc.

  8. Relational Auction (partial) Data in XML: <auction xmlns="http://example.com/auction"><users> <user id ="U01"><name><first>Tom</first> <last>Jones</last></name> <rating>B</rating> </user> </users> <articles> <article id ="1001"> <name>Red Bicycle</name> <seller idref ="U01"/> <start_date>1999-01-05</start_date><end_date>1999-01-20</end_date> <reserve_price>40</reserve_price> </article> </articles> <bids><bid><userid idref ="U02"/> <articleno idref ="1001"/> <amount>45</amount> <date>1999-01-11</date> </bid> </bids> </auction >

  9. The desired output is an XHTML document that can be rendered by a browser :

  10. XML Schema for XHTML: <xs:schema targetNamespace="http://www.w3.org/2001/xhtml" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns ="http://www.w3.org/2001/xhtml"> <xs:element name="html" type="html.type"/> <xs:complexType name="html.type"> <xs:sequence> <xs:element ref="head"/> <xs:element ref="body"/> </xs:sequence> </xs:complexType> <xs:element name="head" type="head.type"/> <xs:complexType name="head.type"> <xs:element ref="title"/> </xs:complexType> <xs:element name="title" type="title.type"/> <xs:complexType name="title.type" mixed="true"/>

  11. XML Schema for XHTML – cont. : <xs:element name="body" type="Block.type"/> <xs:complexType name="Block.type" mixed="true"> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element ref="h1"/> <xs:element ref="p"/> <xs:element ref="table"/> </xs:choice> </xs:complexType> … <xs:element name="tr" type="tr.type"/> <xs:complexType name="tr.name"> <xs:choice maxOccurs="unbounded"> <xs:element ref="th"/> <xs:element ref="td"/> </xs:choice> </xs:complexType> <xs:element name="th" type="Block.type"/> <xs:element name="td" type="Block.type"/> </xs:schema>

  12. Xquery: [1] default element namespace = "http://www.example.com/auction" [2] declare namespace x = "http://www.w3.org/1999/xhtml" [3] define variable $base := xs:anyURI("http://www.example.com/auction/") [4] define function makeURI ($resource as xs:string) as xs:anyURI { [5] xs:anyURI(fn:concat(xs:string($base), $resource)) [6] } [7] let $auction := $input/auction [8] return [9] <x:html> [10] <x:body> [11] <x:h1>Auctions</x:h1> [12] <x:table> [13] <x:td> [14] <x:th>Item Name</x:th> [15] <x:th>Seller</x:th> [16] <x:th>Last Bid</x:th> [17] <x:th>Closes On</x:th> [18] </x:td> [19]{ [20] for $article in $auction/articles/article[start_date <= date()]

  13. Xquery – cont. : [21]let $last_bid := $auction/bids/bid[articleno/@idref = $article/@id][last()] [22] return [23]<x:td> [24] <x:tr> [25] <x:a href="{makeURI($article/@id) }"> { data($article/anme) } </x:a> [26] </x:tr> [27] <x:tr> [28] <x:a href="{ makeURI($article//@idref) }">{ [29] fn:data($auction/users/user[@id = $article//@idref]/name) [30] } </x:a> [31] </x:tr> [32] <x:tr>{ fn:data($last_bid/amount) }</x:tr> [33] <x:tr>{ fn:data($last_bid/date) }</x:tr> [34] </x:td> [35] } [36] </x:table> [37] </x:body> [38] </x:html>

  14. Debugging Why is the table such a mess ???

  15. A closer look at the query: tr and td tags are inverted [12] …<x:table> [13] <x:td> [14] <x:th>Item Name</x:th> ….. [18] </x:td> … [22] return [23]<x:td> [24] <x:tr> [25] <x:a href="{makeURI($article/@id) }"> {data($article/anme) } </x:a> [26] </x:tr> [27] <x:tr> [28] <x:a href="{ makeURI($article//@idref) }">{ [29] fn:data($auction/users/user[@id = $article//@idref]/name) [30] } </x:a> [31] </x:tr> [32] <x:tr>{ fn:data($last_bid/amount) }</x:tr> [33] <x:tr>{ fn:data($last_bid/date) }</x:tr> [34] </x:td> [35] } ….

  16. Debugging – cont. Where are the Item Names ???

  17. Debugging – cont. [25] <x:a href="{makeURI($article/@id) }"> {data($article/anme) } </x:a> should be: [25] <x:a href="{makeURI($article/@id) }"> {data($article/name) } </x:a>

  18. Debugging – cont. Are we done ???

  19. Debugging – cont. Xquery – link to seller’s details : … [28] <x:a href="{ makeURI($article//@idref) }"> … Lets see which descendants of article has an idref attribute …

  20. XML Schema: <xs:element name="article" type="Article"/><xs:complexType name="Article"><xs:sequence><xs:element name="name" type="xs:string"/><xs:element name="seller"><xs:complexType><xs:attribute ref="idref" use="required"/></xs:complexType></xs:element>… <xs:element name="description" type="Freeform" minOccurs="0"/> </xs:sequence><xs:attribute name="id" type="xs:ID" use="required"/></xs:complexType><xs:complexType name="Freeform" mixed="true"><xs:anyAttribute processContents="skip"/><xs:any processContents="skip" minOccurs="0" maxOccurs="unbounded"/> </xs:complexType> xs:anyType possibly: Line [28]: Run-time type error. Argument to function ‘makeURI’ contains more than one value.

  21. Debugging – cont. correction: [28] <x:a href="{ makeURI($article/seller/@idref) }"> It took us 4 cycles of debugging by running the query and then changing the query…

  22. Validation • It is important to validate the formats of the input and output documents. • To enable validation – explicitly import the schemas of the input and output, and explicitly validate the input data. • No need to explicitly validate the output data, because element constructors validate the elements they create.

  23. Validation – cont. [1] import schemadefault element namespace = "http://www.example.com/auction“ at “auction.xsd” [2] import schema namespace x = "http://www.w3.org/1999/xhtml" at “xhtml.xsd” [2a] default validation strict … [7] let $auction :=validate { $input } Requires a declaration for the element The query will raise a run-time error of the input document does not conform to the auction schema or if the output document does not conform to the XHTML schema.

  24. When running our query we get the error message: Validation error: Missing ‘x:head’ element in x:html element. Lets look at the XHTML schema: …<xs:complexType name="html.type"> <xs:sequence> <xs:element ref="head"/> <xs:element ref="body"/> </xs:sequence> </xs:complexType> <xs:element name="head" type="head.type"/> <xs:complexType name="head.type"> <xs:element ref="title"/>… Whereas the query: … [9] <x:html> [10] <x:body>….

  25. Validation – cont. How would validation affect our earlier debugging cycles? • Detects the inverted tr and td tags. • Fails to detect the misspelled element name. • Fails to detect the error which occurs for input data in which description elements contain idref attributes.

  26. Static Typing • Validation detects the presence of certain types of error in the format of the data. Static typing guarantees their absence. • It can spot errors during static analysis rather than at run-time. • It can detect many errors at once. • Not dependant on the input.

  27. Static Typing The result of static typing our query: Line [10]: Element ‘x:body: encountered where element ‘x:head’ expected. Line [13]: Element ‘x:td: encountered where element ‘x:tr’ expected. Line [23]: Element ‘x:td: encountered where element ‘x:tr’ expected. Line [25]: Expression ‘$article/anme’ is always empty. Line [28]: Argument to function ‘makeURI’ has actual type (attribute(@idref) | attribute(@idref, xs:anySimpleType) )+ instead of expected type ‘xs:string’.

  28. Getting Started with Types Coming up: How the type system assigns a type to different kinds of expressions. Including: literals & operators, variables, function calls, conditionals, paths, FLWORs and element constructors.

  29. XML Schema and Xquery types • Xquery’s type system is based on XML Schema. • But, it is simpler and more concise, for the sake of type checking. More on the relationship between XML Schema and Xquery’s type system in the following lecture (chap 5).

  30. XML Schema and Xquery types <xs:element name="user" type="User"/> • In XML Schema, element declarations may be global, at the top level, or local, nested within a type declaration. formal type notation: XML Schema – global element: define element user of type User define element rating of type xs:string <xs:element name="rating" type="xs:string"/>

  31. XML Schema and Xquery types – cont. XML Schema – local elements, unnamed types & complex types: formal type notation: <xs:complexType name="User"> <xs:sequence> <xs:element name="name"> <xs:complexType name=""><xs:element name="first“ type="xs:string“ minOccurs="0"/><xs:element name="last" type="xs:string"/> </xs:complexType> </xs:element> <xs:element ref="rating" minOccurs="0"/> </xs:sequence> <xs:attribute name="id" type="xs:ID" use="required"/> </xs:complexType> define type User { attribute id of type xs:ID , element name of type AnonymousType1, element rating ? } define type AnonymousType1{ element first of type xs:string ? , element last of type xs:string }

  32. XML Schema and Xquery types – cont. <xs:simpleType name="IntegerList"> <xs:list itemType="xs:integer"/> </xs:simpleType> formal type notation: XML Schema – simple type: define type IntegerList {xs:integer + } In the formal type notation: • List types are formed using ?, + & *. • Union types are formed using the choice operator | .

  33. formal type notation – type declarations for NewUser: XML Schema – the NewUser type derived by restriction of the type User: define type NewUser restricts User { attribute id of type xs:ID , element name of type AnonymousType2 , element rating } define type AnonymousType2 { element first of type xs:string , element last of type xs:string } define element newuser of type NewUser <xs:complexType name="NewUser"> <xs:complexContent> <xs:restriction base="User"> <xs:sequence> <xs:element name="name"> <xs:complexType> <xs:element name="first" type="xs:string"/> <xs:element name="last" type="xs:string"/> </xs:complexType> </xs:element> <xs:element name="rating" type="xs:string"/> </xs:sequence> <xs:attribute name="id" type="xs:ID" use="required"/> </xs:restriction> </xs:complexContent> </xs:complexType> <xs:element name="newuser" type="NewUser"/>

  34. XML Schema and Xquery types – cont. • Can be applied to either a user or newuser element: define function user-name($user as element(*,user)) as xs:string {…} • All types are derived from xs:anyType. • All simple types are derived from xs:anySimpleType.

  35. Values • Xquery expression evaluates to a value in the Xquery data model. • Every Value is a sequence of individual items. • An item is either an atomic value or a node. • Every atomic value, element node and attribute node has an associated Xquery type. • The process of XML Schema validation specifies how elements and attributes are labeled with types.

  36. Values – cont. Xquery values representation: XML input document: <user id ="U02"> <name> <first>Mary</first> <last>Doe</last> </name> <rating>A</rating> </user> element user of type User { attribute id of type xs:ID { “U02” } , element name of type AnonymousType1{ element first of type xs:string {“Mary”}, element last of type xs:string {“Doe”}, } , element rating of type xs:string { “A” } } If we apply fn:data to the first element, we get the value xs:string(“Mary”).

  37. Relating Values and Types • Types are used ay analysis time and at evaluation time. • At evaluation time, the value of a query depends upon the types that label values. • It’s possible to refer to type labels explicitly: //element(*, x:Block.type) • Both evaluation and type assignment proceed bottom-up.

  38. Literals and Operators How does the static type system assigns types to expressions? • Literals: “hello” has type xs:string 42 has type xs:integer 42.00 has type xs:decimal 4.2e1 has type xs:double • arithmetic operations: 42 + 69 has type xs: integer 42 + 69.00 has type xs: decimal order of promotion: xs:integer -> xs:decimal ->xs:float -> xs:double

  39. Variables • Implicit: let $z := 1+2 return $z+$z has type xs:integer • Explicit: let $x as xs:integer := 1+2 return $x+$x has type xs:integer let $x as xs:decimal := 1+2 return $x+$x has type xs: decimal let $x as xs:double := 1+2 return $x+$x is a static type error let $x := xs:double(1+2) return $x+$x has type xs:double xs:integer is not a subtype of xs:double

  40. Functions • function signature: • function call: fn:concat( $op1 as xs:string ? , $op2 as xs:string ? ) as xs:string fn:concat(“http://www.example.com/auction/”, “1001”) has type xs:string fn:concat( () , “1001”) has type xs:string The argument type must derive from the required type or can be promoted to it: fn:concat(10e1, “1001”) is a static type error

  41. Conditionals if ($x<$y) then 3 else 4 has type xs:integer if ($x<$y) then “three” else 4.00 has type ( xs:string | xs:decimal ) unlike arithmetic operators, there’s no notion of promotion: if ($x<$y) then 4.2e1 else 69 has type ( xs:double | xs:integer ) unless arithmetic is performed on an operand expression of type ‘union’: (if ($x<$y) then 4.2e1 else 69) + 0.5 has type ( xs:double | xs:decimal )

  42. Path Expressions assume $auction has type element(auction) : $auction/articles has type element(articles) $auction/articles/article has type element(articles)+ $auction/itesm/article is a static type error (has type empty()) $auction/(articles | users) has type ( element(articles) | element(users) )+ $auction/(articles | users) doesn’t have type (element(users) , element(articles) )

  43. Predicates $auction/articles/article[start_date <= date()] has type element(article)* $auction/articles/article[@id = $id] has type element(article)* exactly-one($auction/articles/article[@id = $id]) has type element(article) zero-or-one($auction/articles/article[@id = $id]) has type element(article)? one-or-more($auction/articles/article[@id = $id]) has type element(article)+

  44. FLWOR Expressions assume $articles has type element(article)+ : for $article in $articles return $article/end_date - $article/start_date has type xdt:dayTimeDuration+ for $article in $articles[start_date <= current_date()] return $article/end_date - $article/start_date has type xdt:dayTimeDuration*

  45. Element Construction • Objective: how to construct data. • Simplest way – include literal XML data in a query : <article id ="1001"><name>Red Bycicle</name><seller idref ="U01"/><start_date>1999-01-05</start_date><end_date>1999-01-20</end_date> <reserve_price>40</reserve_price> </article> has type element(article) At evaluation time, the element is constructed and then validated.

  46. Element Construction – cont. • Using computed data in a constructor: define function bargain ($a as element(article)) as element(article) { <article> { $a/@id, $a/name, $a/seller, <start_date>{ fn:current-date() }</start_date><end_date>{ fn:current-date() + ($a/end_date - $a/start_date) }</end_date><reserve_price>{ $a/reserve_price * 0.80 }</reserve_price> }</article> } has type element(article)

  47. Element Construction – cont. • Using computed data in a constructor – bad example: define function bargain ($a as element(article)) as element(article) { <article> { $a/name, $a/seller, <start_date>{ fn:current-date() }</start_date><end_date>{ $a/end_date - $a/start_date }</end_date><reserve_price>{ $a/reserve_price * 0.80 }</reserve_price> }</article> } the type system detects 2 errors. no id attribute type expected for end_date element is xs:date. the type of the expression is xs:dayTimeDuration.

  48. Validation Context • validation context specified by lexical scope of constructors: validated in global context let $first := "Mary" , $last := "Doe" , $rating := "A“ return <user id="U02"><name> { if (fn:string-length($first) > 10) then () else <first>{ $first }</first> } <last>{ $last }</last></name> { if ($rating > "C") then () else <rating>{ $rating }</rating> } </user> validated in user/name context validated in user context

  49. Validation Context – cont. • validation context specified explicitly in validate expression: let $first := validate context user/name { <first>Mary</first> }, $last := validate context user/name { <last>Doe</last> }, $rating := validate context user { <rating>A</rating> } return <user id="U02"><name> { if (fn:string-length($first) > 10) then () else $first, $last }</name> if ($rating > "C") then () else $rating }</user> the first, last & rating elements are no longer lexically nested within the user and name elements => validation context must be explicitly given.

More Related