1
SELECT xText.query (' let $planes := /planes/plane
return <results>
{
  for $x in $planes
  where $x/year >= 1970
  order by ($x/year)[1]
  return ($x/make, $x/model,$x/year )
}
</results>
')
FROM planes

In this code, what is the purpose of [1] in line order by ($x/year)[1]

I have tried to execute this code without using [1] behind order by clause. Then this error has occurred.

XQuery [planes.xtext.query()]: 'order by' requires a singleton (or empty sequence), found operand of type 'xtd:untypedAtomic*'

Mads Hansen
  • 63,927
  • 12
  • 112
  • 147

2 Answers2

2

XQuery 1.0 defined an option called "static type checking": if this option is in force, you need to write queries in such a way that the compiler can tell in advance ("statically") that the result will not be a type error. The operand of "order by" needs to be a singleton, and with static type checking in force, the compiler needs to be able to verify that it will be a singleton, which is why the [1] has been added. It would have been better to write exactly-one($x/year) because this doesn't only keep the compiler happy, it also demands a run-time check that $x/year is actually a singleton.

Very few XQuery vendors chose to implement static type checking, for very good reasons in my view: it makes queries harder to write, and it actually encourages you to write things like this example that do LESS checking than a system without this "feature".

In fact, as far as I know the only mainstream (non-academic) implementation that does static type checking is Microsoft's SQL Server.

Static type checking should not be confused with optimistic type checking where the compiler tells you about things that are bound to fail, but defers checking until run-time for things that might or might not be correct.

Actually the above is a bit of a guess. It's also possible that some <plane> elements have more than one child called <year>, and that you want to sort on the first of these. That would justify the [1] even on products that don't do static type checking.

Michael Kay
  • 156,231
  • 11
  • 92
  • 164
1

The [1] is a predicate that is selecting the first item in the sequence. It is equivalent to the expression [position() = 1]. A predicate in XPath acts kind of like a WHERE clause in SQL. The filter is applied, and anything that returns true is selected, the things that return false are not.

When you don't apply the predicate, you get the error. That error is saying that the order by expects a single item, or nothing (an empty sequence).

At least one of the plane has multiple year, so the predicate ensures that only the first one is used for the order by expression.

Mads Hansen
  • 63,927
  • 12
  • 112
  • 147