Version 8 Documentation

Query Language Reference

Basic concepts

Functional programing

The goal of the SmartShape Query Language (aka “SSQL”) is to perform computations on large tree-like data sets, such as the scene tree of the 3D scene. As such, it aims at efficiency and seeks performance through massive lock-free parallelisation. This is why SSQL is a (pure) functional programing language.

As a functional programing languages, SSQL is different from other languages such as C or Javascript. Those differences include (but are not limited to):

  • there are no variables, only immutable constants
  • there are no for or while loops, only iterators

You can read more on functional programing on Wikipedia.

Use cases

SSQL evaluation is used to implement many features of the SmartShape platform. In many place, the API will accept and store SSQL programs instead of values in order to implement business logic in key areas of the platforms.

Features that rely on SSQL include (but are not limited to):

  • Scene tree nodes search
  • Annotations search
  • Behaviors
  • Layers
  • Rendering styles
  • Search forms
  • Attribute metadata matching
  • Attribute revision management

Notion of context

FIXME

Axis operators

children:, /

Executes a subquery on the direct children of the current node and returns every child that matches the subquery.

Note: This operator won’t match the currently evaluated node if used in conjunction with “parent”.

## Match the nodes that have children.
count(children:true) != 0
parent:, ..

Executes a subquery on the parents of the current node and returns every parent that matches the subquery.

## Match the nodes whose siblings have the attribute "TypeRemarque" equal to "Reprise".
## Note that the / operator won't match the currently evaluated node.
..children:(@"TypeRemarque"="Reprise")
ancestors:, ...

Executes a subquery on all the ancestors of the current node and returns every ancestor that matches the subquery.

.

The . operator references the current element that the query is being evaluated on. Useful for calling functions on it.

Qualifiers

Node qualifiers allow to access some properties of the currently evaluated node.

All the qualifiers can be used by using the long notation.

For some qualifiers, a short notation is available.

## Long notation
<qualifier name>:<value>
## Short notation
<qualifier shortcut><value>
name

Matches a node with a given name.

## Get the node named "Pillar 1"
name:"Pillar 1"
## Get all the nodes whose name begins with "Pillar"
name:"Pillar*"
attribute, @

Matches a node which contains a given attribute. This operator returns the value of the matched attribute, so it can be used to also match the value of the attribute.

## Get the nodes with a "Thickness" attribute.
attribute:"Thickness"
## Format the "Thickness" attribute value of the node to display it in a legend for instance.
concat(round(multiply(@"Thickness", 1000), 0), " mm")
layer, %

Matches a node belonging to a given layer.

Please note that this operator accepts only layer IDs.

## Match the nodes that belong to a given layer.
layer:5bf7ce66ec8d606d53c2fb91
%5bf7ce66ec8d606d53c2fb91
inherited-layer, %%

Matches a node that has an ancestor (or itself) belonging to a given layer. Please note that this operator accepts only layer IDs.

## Match the nodes that belong to a given layer or that have a parent belonging to a given layer.
inherited-layer:5bf7ce66ec8d606d53c2fb91
%%5bf7ce66ec8d606d53c2fb91
modifier

Matches a node that has a given modifier applied to it.

Accepted modifier types:

  • hidden
  • color
  • transparent
  • lock
## Match the nodes that have a "hidden" modifier applied to them.
modifier:hidden
inherited-modifier

Matches a node that has a given modifier applied to itself or its ancestors. See “modifier” for the list of accepted modifier types.

## Match the nodes that have a "hidden" modifier applied to them or their ancestors.
modifier:hidden
id

Matches a node with a specific id.

uuid

Matches a node with a specific uuid.

Legacy

Because SSQL was originally just a fancy list of operators for SmartShape’s scene search engine, some legacy behaviors still apply.

Node name matching

By default, String literals are evaluated as the regular expression match against the name of the context Node if any, or false otherwise.

For example, the program "groundfloor" will actually be evaluated to:

  • true if the current context Node has its name set to “groundfloor”;
  • false otherwise.

Since String literal values do not require to be encapsulated using the " operator, the groundfloor is strictly equivalent and will give the same result.

Implicit logical and

Unless explicitly specified otherwise, literal values are casted to Boolean and combined with the and operators.

For example, the "*42" @status=controlled program is strictly equivalent to "*42" and @status=controlled. As such, it will return:

  • true if the current context Node name ends with “42” and has a status attribute set to “controlled”;
  • false otherwise.

Types

Boolean

Boolean literal values are true and false.

SSQL supports implicit coercion of other types to “truthy” and “falsy” boolean values:

  • an empty String is evaluated as false
  • the 0 Number is evaluated as false, every other Number is evaluated as true

String

String literal values are made of any string of characters that do not match any reserved keyword. Ambiguity can be resolved by using quotes:

For example:

  • false is not a String literal (it’s a Boolean literal), but "false" is
  • 42f is a String literal
  • 42 is not a String literal (it’s a Number literal), but "42" is

  • String operators

  • String functions

Number

SSQL Number values are 64bit floating precision numerical values.

Integers are also represented using the Number type.

Array

SSQL support compound arrays: each Array can store values of mixed types.

Array values have no literal notation. Instead,Array values are created using the array() function.

Variables

Operators

Logical operators

Boolean operators

The &&, and ||, or, ! and not operators are available and work as expected.

Comparison operators

The =, !=, >, <, >= and <= operators are available and work as expected.

String operators

Globbing and quoting

You can use globbing (*) and quoting (" ") to fine-tune your query.

* characters match any character sequence:

## Match nodes whose name contains "basement_" then anything then "_ext"
## like "basement_room_a_ext" for instance.
basement_*_ext

" " characters match exactly the character sequence:

## Match all nodes whose name is exactly "groundfloor_entrance"
## unlike "groundfloor_entrance_door" for instance.
"groundfloor_entrance"

Math operators

Math operators are not available. Use math functions instead.

Array operators

[<

Matches the first element of an array with a given text.

## Match the nodes whose "progress" attribute contains "done" as its first value.
@progress[<"done"

>]

Matches the last element of an array with a given text.

## Match the nodes whose "progress" array attribute contains "done" as its last value.
@progress>]"done"

[*]

Matches any element of an array with a given text.

## Match the nodes whose "progress" array attribute contains the value "done" at any index.
@progress[*]"done"

Functions

String functions

replace(string: String, pattern: String, replacement: String) : String

Replaces matches for pattern in string with replacement.

concat(leftString: String, rightString: String) : String

Concatenates two strings together.

## Concatenate the "Status" attribute of the node with another String.
concat("Status : ", @"Status")

Math functions

round(num: Number, precision: Number) : Number

Computes number rounded to precision.

floor(num: Number) : Number

Computes number rounded down to 0.

add(a: Number, b: Number) : Number

Returns a + b.

multiply(a: Number, b: Number) : Number

Returns a * b.

divide(dividend: Number, divisor: Number) : Number

Returns dividend / divisor.

dot(vec1: Array, vec2: Array) : Number

Returns the dot product between vec1 and vec2.

vec1 and vec2 must be arrays of numbers of length 3.

Array functions

array(value1: Any, value2: Any, …) : Array

Creates an array containing each value passed in argument in the same order they are passed in.

min(values: Array) : Number

Returns the minimum value of an array.

max(values: Array)

Returns the maximum value of an array.

range(value: Number, min: Number, max: Number, numRanges: Number) : Number

FIXME

inRange(value: Number, min: Number, max: Number, rangeIndex: Number, numRanges: Number) : Number

Returns whether value is in the range numbered rangeIndex, given that the range [min, max] is divided into numRanges ranges of the same size.

rangeIndex is expected to be in the range [0, numRanges[.

## All nodes whose size is in the range [1, 10].
inRange(@size, 1, 10, 0, 1)

indexOf(values: Array, value: Any) : Number

Returns the index at which value is stored in the values array.

indexOf(array(2, 14, 3), 3)

sort(values: Array) : Array

Returns the values array sorted in ascending order. This method performs a stable sort, that is, it preserves the original sort order of equal elements.

unique(values: Array) : Array

Returns a duplicate-free version of the values array. Only the first occurrence of each element is kept. The order of result values is determined by the order they occur in the array.

nth(values: Array, index: Number) : Any

Returns the element of values at index index.

array(value1: Any, value2: Any, …) : Array

Creates an array containing each value passed in argument in the same order they are passed in.

map(values: Array, query: Query) : Array

Creates an array of values by running query over each element of values and returns the resulting array.

apply(element: Any, query: Query) : Any

Runs query on element. Returns the return value of query.

all(values: Array) : Boolean

Returns true if all elements of values are truthy, false otherwise.

count(values: Array) : Number

Counts the number of elements of an array.

## Counts the number of children of the current node.
count(/*)
Last updated on 27 Mar 2019

SmartShape Documentation v8.1.0, powered by Hugo.