Контекстные ссылки

Контекстная ссылка выглядит таким образом:

contextMask { :contextEntityReference [: ...] }

contextMask является маской контекстов, чьи сущности (переменные или функции) будут использоваться для построения таблиц, по которым будет выполнен запрос. Данная маска может быть простым именем контекста (без каких-либо специальных символов) или разрешаться в некоторые контексты.

contextEntityReference указывает на переменную контекста, группу переменных или функцию. Выглядит это данным образом:

{ contextVariableName | contextVariableGroupName.* | contextFunctionName ( contextFunctionParameters ) }

Вертикальные черты указывают альтернативы - фактически они не включены в contextEntityReference. Далее приведен простой пример контекстной ссылки:

users.admin:childInfo

данная ссылка указывает значение переменной childInfo из контекста users.admin.

Двоеточие (:) используется для разделения маски контекста и сущности. "Сущность" - придуманное название переменной или функции. Итак вы задаете маску (т.е. "куда" вы направляетесь), затем ставите двоеточие, чтобы обозначить сущность (т.е. "что" вы хотите найти в месте назначения). Вы даже можете использовать специальный символ после двоеточия для ссылки на группу переменных (такую как user.charlie.devices.sensor:remote.*, которая даст все настройки (переменные) в группе датчиков устройства, принадлежащего пользователю charlie).

Каждая контекстная ссылка может сочетать маски контекста и несколько ссылок на сущности (даже разных типов):

users.*:userInfo:variableGroup.*:status()

Данная сылка указывает значение переменной userInfo. Все переменные, принадлежащие группе variableGroup и выходу функции status, вызываются без параметров. Значения извлекаются из всех контекстов, относящихся к маске users.*, т.е. контекстов всех видимых пользователей в системе с правами доступа пользователя, выполняющего запрос.

Построение исходных таблиц из контекстных ссылок

Во время выполнения запроса сперва каждая контекстная ссылка используется для построения одной таблицы, по которой будет выполнен запрос. Построение данной таблицы представляет собой сложный процесс из нескольких шагов:

  • Маска контекста разрешается в список контекстов к ней относящихся и доступных пользователю, выполняющему запрос (согласно его правам доступа).
  • Процессор запроса выбирает и кэширует значения переменных, на которые указывают контекстные ссылки. Он также вызывает все связанные функции с параметрами, заданными в тексте запроса, и кэширует выходные данные функций.
  • Формируется список полей для конечной таблицы согласно правилам. Если контекстная ссылка ссылается только на одну переменную или функцию, конечная таблица будет иметь столько же полей, сколько их содержит переменная или вывод функции. Если контекстная ссылка ссылается на несколько переменных или функций, формат конечной таблицы будет включать все поля, которые есть в переменных или в выводе функции. Исключение оставляет случай, когда значение или вывод функции содержит более одной записи. В такой ситуации таблица будет иметь только одно поле для данной переменной/функции. Данное поле будет содержать вложенную таблицу со значением переменной или вывода функции
  • Таблица заполняется данными. Обычно одна запись создается для каждого контекста, соответствующего маске контекстной ссылки. Но если ссылка ссылается только на одну переменную/функцию и ее значение/вывод содержит несколько записей, все эти записи включены в конечную таблицу (т.е. таблица будет содержать не одну запись, а запись будет представлена в виде вложенной таблицы, что не имеет смысла).
  • Нажмите сюда, чтобы узнать, где контекстные ссылки могут применяться в синтаксисе языка запросов.

    Определение параметров функции

    Когда функция контекста вызывается во время разрешения контекстной ссылки, ей необходимо иметь входные параметры. Данные параметров определены в списке, содержащем строковые параметры. Параметры входят в одну длинную строку и разделяются запятыми (",").

    Более подробную информацию о том, как список разделенных запятыми параметров конвертируются в таблицу данных, см. здесь. Таблица данных построена в соответствии с форматом ввода функции.

    Ключевые поля

    При  создании таблиц, соответствующих контекстной ссылке, система создает индексы для определенных полей. Данные индексы существенно ускоряют процесс обработки запроса. Индексы создаются автоматически для всех ключевых полей, т.е. для тех, у которых выстален флажок Ключевое в формате таблицы.

    Если для выполнения вашего запроса, такого как запрос, ссылающийся на соединения, требуется большое количество времени, или же этот запрос негативно влияет на производительность, попробуйте изменить структуру исходных значений, чтобы нужные поля стали ключевыми. В этом случае для них автоматически будут созданы индексы, а производительность запросов многократно возрастет.

    Специальные поля

    Каждая таблица, построенная из контекстной ссылки, содержит три дополнительных поля: CONTEXT_ID, PARENT_ID и RECORD_INDEX. Данные поля добавляются процессором обработки запроса.  

    CONTEXT_ID содержит полное имя контекста, в котором возникла определенная запись.

    PARENT_ID содержит полное имя контекста-родителя того контекста, в котором возникла определенная запись.

    RECORD_INDEX - это номер записи в таблице данных, из которой эта запись была взята.

    Ссылка на данные поля осуществляется через раздел ГДЕ. Однако данные поля скрыты. Они невидимы в результатах запроса.

    Ссылаться на данные из специальных полей можно в любом запросе. См. использование объединений для примера, как это сделать.

    Имейте в виду, что имена специальных полей должны точно определяться в запросе ВЫБРАТЬ при использовании редактируемых результатов запроса. Для получения более подробной информации обратитесь к статье поля обратной записи.

    Использование алиасов таблиц в качестве переменных контекста запроса в контекстных ссылках

    Алиас таблицы, определенный для ссылок на результаты запроса, может использоваться как переменная контекста в контекстной ссылке в другом запросе. В этом случае контекстная ссылка выглядит так:

    queryContextPath.queryContextName:tableAlies

    Например, вы создали контекст запроса с именем sineHistory. Допустим, цель данного контекста - извлекать историю переменной sine виртуального устройства virtual, которое расположено в users.admin.devices (обратите внимание, что должно быть указано время хранения истории для соответствующей переменной, чтобы активировать хранение ее истории). Текст запроса выглядит таким образом:

    SELECT * FROM utilities:variableHistory("users.admin.devices.virtual", "sine") AS data1

    Можно использовать созданный алиас data1 для ссылки на результаты запроса sineHistory в другом запросе. Предположим, что вы создали другой контекст запроса с именем sineHistoryLast20. В результате следующего запроса sineHistoryLast20 вернет последние 20 записей истории:

    SELECT * FROM users.admin.queries.sineHistory:data1 AS data2 LIMIT 20

    Таким образом, контекст запроса sineHistory используется в качестве внешнего "подзапроса" для контекста sineHistoryLast20.

    Обратите внимание, что в отличие от алиасов таблицы, нельзя ссылаться на функцию выполнить одного контекста запроса в другом контексте запрос. Формат выхода функции execute динамический (не содержит каких-либо предопределенных полей), поэтому запрос, ссылающийся только на эту функцию, вернет пустую таблицу (см. п.3 в разделе Построение исходных таблиц из контекстных ссылок выше).

    Примеры контекстных ссылок

    Предположим, что у вас два контекста, path.name и path.name2. Маска контекста path.* подходит для обоих.

    path.name имеет две переменные:

    var1:

    stringField

    "test string"

    var2:

    integerField

    booleanField

    123

    TRUE

    Данный контекст также определяет функцию func1, которая возвращает следующее значение:

    floatField

    integerField

    45.6

    456

    78.9

    789

    path.name2 имеет те же имена переменных, но уже с другими значениями:

    var1:

    stringField

    "string in 2nd context"

    var2:

    integerField

    booleanField

    555

    FALSE

    Данный контекст также определяет функцию func1, которая возвращает следующее значение:

    floatField

    integerField

    11.1

    666

    22.2

    777

    33.3

    888

    Пример 1

    Контекстная ссылка: path.name:var2

    Таблица, построенная из простой контекстной ссылки, будет в точности совпадать со значением var2:

    var2$integerField

    var2$booleanField

    123

    TRUE

    Имейте в виду, что имена полей в полученной таблице включают переменные, из которых было взято каждое поле (см. выше var2). Это упрощает ссылку на данные поля, используя ссылки на поля.

    Пример 2

    Контекстная ссылка: path.name:var1:var2

    Данная ссылка разрешится в таблицу с тремя полями, одно из значения var1, остальные из значения var2. Они включены в одну строку, т.к. обе переменные принадлежат одному и тому же контексту.

    var1$stringField

    var2$integerField

    var2$booleanField

    "test string"

    123

    TRUE

    Пример 3

    Контекстная ссылка: path.*:var1:var2

    Данная ссылка указывает на маску контекста, поэтому она разрешится в таблицу с тремя полями, как и в предыдущем примере, но уже с двумя записями, по одной на каждый контекст:

    var1$stringField

    var2$integerField

    var2$booleanField

    "test string"

    123

    TRUE

    "string in 2nd context"

    555

    FALSE

    Пример 4

    Контекстная ссылка: path.*:func1

    Данная ссылка указывает на одну сущность (функцию) со значением, содержащим множество записей, поэтому итоговая таблица будет иметь те же поля, что и вывод функции. Общее число записей в таблице равно 5, т.к. две записи получены из значения func1 в path.name, а три остальные из значения func1 в path.name2.

    func1$floatField

    func1$integerField

    45.6

    456

    78.9

    789

    11.1

    666

    22.2

    777

    33.3

    888

    Пример 5

    Контекстная ссылка: path.*:var1:func1

    Поскольку ссылки на сущности (переменная var1 и функция func1) ссылаются на многострочные значения func1, они будут находиться во вложенных таблицах. Невозможно ссылаться на поля в таких таблицах, используя ссылки на поля.

    var1$stringField

    func1

    "test string"

    [Nested table with the value of "func1" in "path.name"]

    "string in 2nd context"

    [Nested table with the value of "func1" in "path.name2"]