py4sci

Table Of Contents

Previous topic

2. Expressions

Next topic

4. Operators

3. HTSQL Query Syntax

Generic syntax of HTSQL query is described in following syntax diagrams. Refer to How to read syntax diagrams section to learn understanding them.

3.1. Syntax Diagrams

query (description):

[ credentials_clause ]
{ [ command_call ]... |
  path_clause [ command_call ]... [ filter_clause ] }

( credentials_clause - command_call - path_clause - filter_clause )

credentials_clause:

"/~" perspective

path_clause:

"/" tree_clause [";" "/" tree_clause ]...

( tree_clause )

tree_clause (description):

segment_clause [ "/" segment_clause ]... [ "(" tree_clause [ ";" tree_clause ]... ")" ]

( segment_clause )

segment_clause (description):

[ "*" ]
[ table_qualifier [ locator_clause ] ]
[ selector_clause ]
[ filter_clause ]

( locator_clause - selector_clause - filter_clause )

selector_clause (description):

"{" selection [ "," selection ]... "}"

( selection )

selection (description):

[ expression ]
{ [ { "+" | "-" } ] [ "^" ] |
  selector_clause [ { "+" | "-" } ] [ "^" ] [ filter_clause ] }

( selector_clause - filter_clause )

filter_clause (description):

"?" { condition | assignment } [ "&" assignment ]...

( assignment )

locator_clause (description):

"[" location [ "," location ]... [ ";" tag ] "]"

( location )

location (description):

label [ "." label ]...

( label )

label (description):

{ "*" | literal | sub_locator_clause | variable }

( sublocator_clause )

sublocator_clause (description):

{ locator_clause |
  "(" location [ "," location ]... [ ";" tag ] ")"

( location )

command_call (description):

{ "/" command "(" [ argument_list ] ")" |
  "." command [ "(" argument_list ")" ] }

( argument_list )

argument_list (description):

[ argument [ "," argument ]... ] [ name "=" argument [ name "=" argument ]... ]

( argument )

argument:

{ constant | query }

( query )

3.2. Query

tree_clause(s) define database objects and structures, which commands in commands_clause are applyed to. If more than one tree_clause is specified, more than one dataset is passed to the specified commands.

commands_clause may be omitted, but there are two implicit commands, that apply if not overridden:
  • select() command defines operation executed
  • html() command (called formatter as well) defines response format

If more than one tree_clauses are specified, the filter_clause relates only to the last tree. This way filter_clause on the top level is syntactical equivalent to filter_clause within the top segment of the last tree. This is shown in example:

/organization;/project/select()?start_date !== null()
  is equivalent for
/organization;/project?start_date !== null()/select()

3.3. Credentials

3.4. Hints

Query may contain optional predefined symbols, which are called hints.

3.5. Tree Path

3.5.1. tree_clause

Tree is a set of consecutive segment declarations with possible branching on the bottom level.

Consecutive segments mean, that context tables of all these segments are linked with each other with foregin key references, and HTSQL for each row of separate segment will return all linked rows of nextcoming segments in hierarchical way.

Top level segment generates main dataset, while subsegments generate embedded datasets. This way resulting tree is built. For example:

/organization{id()}?is_active/project{id()}/person{id()}.xml
--->
  <htsql:result root="http://localhost:8081" base="http://localhost:8081">
    <op:organization htsql:id="lake-carmen" id="lake-carmen">
      <op:project htsql:id="lt-711" id="lt-711"/>
      <op:project htsql:id="lt-802" id="lt-802">
        <op:person htsql:id="lakeside.amy" id="lakeside.amy"/>
        <op:person htsql:id="meyers.hill" id="meyers.hill"/>
        <op:person htsql:id="meyers.jack" id="meyers.jack"/>
        <op:person htsql:id="meyers.jim" id="meyers.jim"/>
      </op:project>
    </op:organization>
    <op:organization htsql:id="meyers" id="meyers"/>
    <op:organization htsql:id="meyers_elec" id="meyers_elec"/>
    <op:organization htsql:id="stewart" id="stewart"/>
  </htsql:result>

XML illustrates well hierarchical structure of result.

tree_clause may contain several embedded trees, braced and separated with “;”. This construction is called branching and results in several sets of linked rows:

/organization{id()}?!is_active/(project{id()};person{id()}).xml
--->
  <htsql:result root="http://localhost:8081" base="http://localhost:8081">
    <op:organization htsql:id="acorn" id="acorn">
      <op:project htsql:id="la-102" id="la-102"/>
      <op:person htsql:id="acorn.hideo" id="acorn.hideo"/>
    </op:organization>
    <op:organization htsql:id="lake-apts" id="lake-apts">
      <op:project htsql:id="la-334" id="la-334"/>
      <op:person htsql:id="lake-apts.tom" id="lake-apts.tom"/>
    </op:organization>
    <op:organization htsql:id="smith" id="smith">
      <op:project htsql:id="smak" id="smak"/>
      <op:project htsql:id="smbl" id="smbl"/>
      <op:project htsql:id="smen" id="smen"/>
      <op:person htsql:id="smith.jack" id="smith.jack"/>
      <op:person htsql:id="smith.jose" id="smith.jose"/>
      <op:person htsql:id="smith.maggy" id="smith.maggy"/>
    </op:organization>
  </htsql:result>

3.5.2. segment_clause

Segment is a construction, that generates single dataset: set of rows with defined structure.

table_qualifier defines aspect context for a segment. If not specified scalar context is considered. Expressions within selector_clause and filter_clause are evaluated in this context.

`*` hint tells SQL generator to perform inner join with the parent segment. The result of this hint is that rows of parent segment, containing no rows of current segment will not be returned:

/organization{id()}?is_active/*project{id()}/*person{id()}.xml
--->
  <htsql:result root="http://localhost:8081" base="http://localhost:8081">
    <op:organization htsql:id="lake-carmen" id="lake-carmen">
      <op:project htsql:id="lt-802" id="lt-802">
        <op:person htsql:id="lakeside.amy" id="lakeside.amy"/>
        <op:person htsql:id="meyers.hill" id="meyers.hill"/>
        <op:person htsql:id="meyers.jack" id="meyers.jack"/>
        <op:person htsql:id="meyers.jim" id="meyers.jim"/>
      </op:project>
    </op:organization>
  </htsql:result>

Obviously, this hint makes sence only for subsegments of a tree.

3.6. Selector

3.6.1. selector_clause

Selector specifies structure of returned rows and contains set of comma-separated selection constructions. Each selection defines one or more (is case of subselector usage) columns of resulting dataset.

3.6.2. selection

Selection may be simple or contain subselector.

Simple selection in an expression, that is used to calculate values of specific result column. The expression must be strictly singular.

Selection with subselector may define more than one resulting columns, depending on how many selections subselector contains. Subselector is just a syntactical shortcut to define several columns at once: forehand expression is a context for expressions within subselector:

context { expr1, expr2 }
  is equivalent for
context.expr1, context.expr2

Like in example:

/project{id(), name, organization{id(), name}}
  is equivalent for
/project{id(), name, organization{id(), name}}

Context for subselector may be any valid singular or plural expression:

/organization{id(), project{count(), first(name)}}
  is equivalent for
/organization{id(), project.count(), project.first(name)}

/organization{(name+' **')[1:]{this(), length()}}
  is equivalent for
/organization{(name+' **')[1:].this(), (name+' **')[1:].length()}
But the whole selection with subselector must also be strictly singular:
  • context and subselector expressions must be all singular
  • in case of plural context subselector must contain only aggregate expressions

When context for subselector is plural, selection may have optional filter_clause, which is called in this case a sieve. It defines a condition for a plural expression to filter rows before aggregate functions within a subselector will be applied.

/organization{id(), project{count()}} —>

acorn 1 lake-apts 1 lake-carmen 2 lakeside 0 meyers 0 meyers_elec 0 smith 3 stewart 0

/organization{id(), project{count()}?status=’completed’} —>

acorn 1 lake-apts 1 lake-carmen 0 lakeside 0 meyers 0 meyers_elec 0 smith 2 stewart 0

Several hints can be used in selection clause:

  • +” hint sorts result by this selection in ascending order. With subselector hint sorts result by all selections in subselector.
  • -” hint sorts result by this selection in descending order. With subselector hint sorts result by all selections in subselector.
  • ^” hint groups result by this selection. If one of selections is marked with such hint, all others within selector must be aggregates or also be marked for grouping.

3.7. Filter

3.7.1. filter_clause

Filter is a conditional expression layed upon rows of segment dataset or plural expression to exclude rows, which don’t satisfy the condition. Filter expression is also called predicate expression.

If filter expression is not boolean, an implicit cast is performed. Refer to Boolean conversion for details.

If filter expression is plural, implicit exists function is applies.

When data modification command is specified in a query, filter clause may contain assignments, which define new column values. It’s obvious, that assignments may be used only in aspect context:

/project[la-102]?status='completed'&name:=name+' xxx'/update()?description:=description+' ***'

In this example two assignments are placed in different filter clauses, but it doesn’t matter, since they are evaluated in the same aspect context. Single filter clause could be used as well, containing both assignments.

3.8. Locator

3.8.1. locator_clause

Locator is construction for selecting particular rows of a given table using primary key columns and is indentical to the more formal filter syntax:

/organization[meyers]
  is equivalent for
/op:organization?org_id='meyers'

When using this syntax, each value associated with a primary key column is called a label. As follows from an example, labels are compared via usual equality (not null-safe). Labels unlike other non-numeric literals may be unquoted.

Locator accepts several row locations, separated by comma “,”.

3.8.2. location

If primary key of specific table is composite, location is a dot-separated sequence of labels for each key column of a composite key:

/person[acorn.hideo]

3.8.3. label

Label defines a value for a specific key column. It may specify:
  • single value with a literal or a variable
  • set of values with a widlcard or a subselector

Wildcard `*` accepts any value of the column and subselector specifies set of specific values.

3.8.4. sublocator

Sublocator may be enclosed in square brackets (like ordinary locator) or in parenthesis.

3.9. Commands

Commands define actions executed within the htsql query.

3.9.1. command_call

Command call looks like a function: command name followed by parenthesis wich argument list. Command is prefixed with either slash “/” or dot “.”. The only difference is that with dot prefix command without arguments may be called without trailing parenthesis:

/organization/xml()
  is equivalent for
/organization.xml

3.9.2. argument_list

Command arguments are passed in order of declaration or by name in any order. By name arguments are passed in form of name=argument pairs, coming at the end of argument list, after all ordinary arguments.