Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:MUMPS СУБД. Практика применения и опыт программирования.pdf
X
- •Предисловие
- •Введение
- •Среда исполнения
- •Команды
- •Команды присваивания
- •Условные команды
- •Команды передачи управления
- •Команды ввода-вывода
- •Служебные команды
- •Постусловия
- •Операторы
- •Переменные
- •Числа и строки
- •Функции
- •$DATA
- •$GET
- •$ORDER
- •$NEXT
- •$QUERY
- •$NAME
- •$QLENGTH
- •$QSUBSCRIPT
- •$ASCII
- •$CHAR
- •$EXTRACT
- •$PIECE
- •$LENGTH
- •$REVERSE
- •$FIND
- •$TRANSLATE
- •$JUSTIFY
- •$FNUMBER
- •$TEXT
- •$RANDOM
- •$VIEW
- •$SELECT
- •$STACK
- •Списковые функции
- •Битовые функции
- •Модули
- •Рутины
- •Передача параметров
- •Неопределенные значения
- •Шаблоны
- •Косвенность
- •Косвенность имени
- •Косвенность индексов
- •Косвенность метки
- •Косвенность аргумента
- •Косвенность шаблона
- •Интерпретатор
- •Голая ссылка
- •Очередность выполнения
- •Очередность вычисления выражений
- •Очередность вычисления имен
- •Стекование $test
- •Комментарий
- •Стандарт и расширения
- •Глобалы
- •B-дерево
- •Кодирование индексов
- •Размер блока
- •Кеширование блоков
- •Структуры
- •Индексация
- •Группировка
- •Каноничность индексов
- •Маппинг
- •Индексация данных
- •Общие принципы
- •Механизм поддержки индекса
- •Простой индекс
- •Составной индекс
- •Покрывающий индекс
- •Кластерный индекс
- •Хеш-индекс
- •Битмап индекс (bitmap)
- •Битслайс индекс (bitslice)
- •Нормирование значений
- •Выборки по индексу
- •Многоиндексная выборка (zig-zag)
- •Дифференциальное индексирование
- •Индексация длинных атрибутов
- •Межтабличный индекс
- •Индекс с условием на вставку
- •Индекс на вычисляемый атрибут
- •Индекс поиска по фрагменту
- •Индексация для шаблона (like)
- •Индексация уникального атрибута
- •Массовое перестроение индексов
- •Операции с древовидными индексами
- •Операции с битовыми индексами
- •Сортировка по индексу
- •Статистики и кардинальность
- •Конкурентный доступ
- •Параллельность выполнения
- •Блокировки
- •Функция $INCREMENT
- •Транзакции
- •Блокировки в транзакциях
- •Функция $BIT
- •Дедлоки
- •Обработка ошибок
- •Состояние ошибки
- •ZTRAP
- •GT.M
- •MiniM
- •ETRAP
- •Определение
- •$ETRAP
- •$ECODE
- •$ESTACK
- •Ошибки в обработчике ошибок
- •$STACK()
- •Трассировка
- •BREAK
- •MiniM Debugger
- •Serenji Debugger
- •Внешний мир
- •Общие принципы
- •Терминальный интерфейс
- •Сокеты
- •HTTP клиент
- •Вебсервер на MUMPS
- •WebLink
- •Проблемы HTTP
- •Поверх HTTP
- •Подключаемые DLL (SO)
- •Файлы
- •Внешние процессы
- •Порты
- •Практика применения
- •Терминальный режим
- •Редакторы рутин
- •Экспорт и импорт
- •Препроцессор
- •Формат $HOROLOG
- •Опции устройств
- •$X и $Y
- •Возврат результатов
- •Возврат по значению ($$)
- •Возврат по ссылке
- •Запись в предопределенную переменную
- •Возврат значений косвенно
- •Итеративный возврат
- •Потоковый возврат
- •%Z - рутины
- •Планирование файлов
- •Память и сборка мусора

1.4. ЧИСЛА И СТРОКИ 71
ходимости. Арифметические и строковые операции могут выполняться
над значениями любых переменных и над результатами любых выражений.
Дополнительно к порядку приведения чисел действует правило получения булевского значения для различных условий и постусловий. Для
получения булевского значения, равного или 0 или 1, система приводит
аргумент сначала к числу, потом сравнивает его с нулем. Если получилось число равное 0, то результат 0, иначе (при любом другом) результат
равен 1. В частности, операция логического отрицания приводит свой
аргумент к булевской величине явно. Неявно к ней приводят операции
условных операторов, постусловий, соответствия шаблону, вычисление
значения бита.
Что интересно, двойное применение оператора логического отрицания к аргументу приводит арумент не к инвертированному, а к прямому
булевскому виду. Первый оператор приводит к булевскому, но инвертированному, второй еще раз инвертирует для получения прямого:
USER>w ’’12
1
USER>w ’’"string"
0
USER>w ’’"12 с половиной"
1
Такая операция двойного логического отрицания используется как
операция булевского нормирования - в силу того, что оператор отрицания возвращает строго предопределенные значения, нормирование также
получает строго определенные значения - 0 или 1, которые можно использовать и в арифметических и в строковых операциях.
Прямым эквивалентом операции приведения к булевской величине
является операция явного приведения к числу и сравнение с нулем:
USER>w +12’=0
1
USER>w +"string"’=0
0
USER>w +"12 с половиной"’=0
1
В отличие от других языков, в языке MUMPS число не всегда является самостоятельной лексемой, рассматриваемой только как синтаксическое число. Интерпретатор не только использует последовательности

72 ГЛАВА 1. СРЕДА ИСПОЛНЕНИЯ
цифр по контексту операции, но и анализирует исходный код по контексту команды и операции. В частности, последовательность цифр является синтаксически корректным именем метки, например при выполнении
команд
goto 123
do 123
лексема 123 означает не число как значение, а допустимое имя метки.
Что интересно, допускается также вариант очень похожий на сложе-
ние:
goto 123+4
В этом случае числом здесь является лексема 4, означающая смещение от метки с именем 123, а знак + синтаксически означает запись
смещения относительно метки. Так, в коде
do 123+4+5
лексемы 4 и 5 вычисляются как числа и программа вызывает подпрограмму с метки 123 со смещением 9 (сумма 4 и 5).
В большинстве случаев, конечно, разработчики на MUMPS не стремятся злоупотреблять особенностями синтаксиса, чтобы не сделать код
совершенно нечитабельным.
Другим случаем использования последовательностей цифр является
задание числа повторов для шаблонов, например
USER>w "a12"?1.2A1N1E
1
Здесь спецификацией шаблона является полная последовательность
символов "1.2A1N1E", причем последовательность "1.2" не означает число
1.2, а указывает число повторов (означает от 1 до 2 включительно).
1.5 Функции
Стандарт языка MUMPS предусматривает поддержку определенного набора системных функций. Системные функции - это встроенные в ядро интерпретатора операции обращения к данным, по преобразованию
строк, или выполняющие служебные действия.

1.5. ФУНКЦИИ 73
Синтаксически системные функции задаются именем, перед которым
указывается один символ $. Также как имена команд, имена системных функций используются в любом регистре и могут сокращаться до
аббревиатуры, за редким исключением это первая буква имени.
Если после имени функции не ставится пара скобок с аргументами,
то синтаксически это соответствует системным переменным, например
если пишется функция $PIECE в сокращенной форме ($P) без скобок,
это воспринимается транслятором как системная переменная. В частности, системная переменная $P действительно существует, ее полное имя
$PRINCIPAL.
В действительности многие системные переменные очень похожи на
функции без аргументов. Есть системные переменные, которые не изменяются все время жизни для всех процессов, например $SYSTEM.
Есть системные переменные, зависящие от процесса, но не изменяющие
значения, например $JOB. При этом есть системные переменные, которые могут изменять свое значение регулярно, например $HOROLOG.
Такие переменные уже большинством программистов воспринимаются
как функции, вычисляющие значение независимо от аргумента. Но в
языке MUMPS исторически принято различать переменные и функции,
и если функция не требует аргументов, то это переменная.
Более того, в терминологии языка закрепилось и различие между
пользовательскими функциями и пользовательскими переменными. Фактически же между ними нет разницы, пользовательские переменные это
то же самое что и пользовательские функции, если их можно вызвать
без аргументов и без скобок.
В круглых скобках после имени функции через запятую перечисляются аргументы функции. В отношении аргументов для стандартных
системных функций в языке есть соглашение что если аргумент не указывается, то его позиция не выделяется. Например, нельзя написать
опускание аргумента так:
$piece(str,,3)
Часть функций допускает опускание аргументов с конца, в частности
вместо
$piece(str,"~",)
нужно писать
$piece(str,"~")

74 ГЛАВА 1. СРЕДА ИСПОЛНЕНИЯ
Некоторые реализации MUMPS систем поддерживают расширенные
нестандартные системные функции, допускающие опускание аргумента,
в частности, функция $LB() при опускании аргумента конструирует в
списке в этой позиции специальный элемент списка с зарезервированным неопределенным значением.
Все системные функции определены так, что они возвращают некоторое значение, поэтому, даже если результат возврата не важен, его в
любом случае необходимо использовать, по крайней мере присвоить временной переменной или использовать результат как аргумент команды
if.
Весь набор системных функций можно разделить на несколько групп
по назначению функций:
1. Функции доступа к данным
2. Функции имен
3. Строковые функции
4. Служебные функции
Функции доступа к данным возвращают информацию о наличии значения переменных и наличии их индексов. К таким относятся функции:
1. $DATA - вернуть индикатор существования переменной и ее индексов.
2. $GET - вернуть значение переменной или значение по умолчанию
если переменная не существует.
3. $ORDER - вернуть следующее значение индекса на том же уровне.
4. $QUERY - вернуть следующее имя переменной независимо от уровня индексов.
1.5.1 $DATA
Функция $DATA ($D) принимает в аргументе имя переменной, локальной или глобальной, и возвращает одно из следующих значений:
1. 0 - ни эта переменная, ни ее дочерние не существуют
2. 1 - переменная существует, но дочерних не имеет

1.5. ФУНКЦИИ 75
3. 10 - переменная не существует, но дочерние (по меньшей мере один
дочерний элемент) есть
4. 11 - и эта переменная и ее дочерние (по меньшей мере один) существуют
Возвращаемое значение строго определено стандартом и может быть
использовано в арифметических операциях, что разработчики и используют при необходимости. В частности, проверка на то что имя существует независимо от существования дочерних:
$DATA(varname)#2
и проверка существования дочерних независимо от существования самой
переменной:
$DATA(varname)\10
Функция $DATA в некоторых реализациях MUMPS пожет быть применена также к структурным системным переменным. Например, в этом
случае можно проверить существование процесса:
$DATA(^$JOB(jobnumber))
Но в этом случае необходимо сверить с документацией на используемую MUMPS систему, поддерживается ли такой функционал.
У функции $DATA имеется побочный эффект - при обращении к
глобальной переменной независимо от существования или несуществования ее или ее дочерних переменных функция взводит индикатор голой ссылки в значение, равное имени переменной, к которой обратилась.
Эта особенность также может быть использована разработчиками, если
необходимо присвоить индикатору голой ссылки определенное имя, но
используемая реализация MUMPS системы или ее версия не поддерживает прямое присваивание системной переменной $ZREFERENCE.
Существуют реализации MUMPS систем, поддерживающие нестандартную двухаргументную форму функции $DATA - в качестве второго
аргумента необходимо указать имя переменной. В этом случае если переменная из первого аргумента имеет значение, то функция одновременно
присвоит это значение второй переменной:
USER>s a=123
USER>w $d(a,value)
1

76 ГЛАВА 1. СРЕДА ИСПОЛНЕНИЯ
USER>w
a=123
value=123
Этот функционал является нестандартным и поведение индикатора
голой ссылки в случае использования во втором аргументе глобальной
переменной необходимо сверять с документацией на используемую версию MUMPS системы. Наиболее ожидаемым поведением в этом случае
может быть присваивание второй переменной после получения индикатора существования и присваивание индикатору голой ссылки именно
второго имени.
1.5.2 $GET
Функция $GET ($G) возвращает значение для указанной переменной.
Функция имеет две формы вызова - одноаргументную и двухаргументную:
$GET(varname)
$GET(varname,defvalue)
Если переменная с заданным именем имеет значение, то оно возвращается независимо от формы функции и ее второго аргумента. Если эта
переменная не имеет значения, то в первом случае для нее возвращается
пустая строка, а во втором случае - значение указанное как значение по
умолчанию, defvalue.
Также как и функция $DATA, функция $GET имеет побочный эффект - при обращении к глобальной переменной вне зависимости от ее
существования функция $GET взводит индикатор голой ссылки в значение, равное имени глобальной переменной.
Традиционным применением функции $GET является код, не использующий предварительную инициализацию
f i=1:1:12 s total=$get(total)+i
не проверяющий существование переменной
f i=1:1:12 s total=$get(total)+$get(^gbl(i))
или обращающийся к параметрам функции которые могут получить неопределенное значение
func(param)
s param=$get(param,0)
...

1.5. ФУНКЦИИ 77
1.5.3 $ORDER
Функция $ORDER ($O) возвращает следующее значение индекса в порядке их существования у переменной или пустую строку если следующего индекса не существует.
Для функции необходимо передать локальное или глобальное имя,
указав нужное число индексов. Функция будет возвращать следующий
индекс (если он существует) на уровне последнего указанного индекса.
USER>s a(1)=1
USER>s a(2)=1
USER>s a(3)=1
USER>s a(4)=1
USER>s a(2,1)=1
USER>s a(2,2)=1
USER>s a(3,1)=1
USER>s a(4,1)=1
USER>s n=""
USER>f s n=$o(a(n)) q:n="" w n,!
1
2
3
4
Функция возвращает значение индекса в обоих вариантах - если существует такая переменная или если существуют ее дочерние переменные. Нужно понимать, что если функция $ORDER вернула следующий
индекс, то этот индекс означает следующий в понимании переменной
как дерева, но само значение не обязано существовать.
У функции $ORDER существует две формы - одноаргументная и
двухаргументная. Одноаргументная форма возвращает следующий индекс в порядке возрастания. Двухаргументная форма принимает вторым
аргументом индикатор направления, который может принимать только
одно из следующих значений:
1. 1 - перечислить по возрастанию

78 ГЛАВА 1. СРЕДА ИСПОЛНЕНИЯ
2. -1 - перечислить по убыванию
Любые другие значения в настоящее время зарезервированы для бу-
дущего использования и их использование должно генерировать ошибку.
Существуют реализации MUMPS систем, которые поддерживают применение функции $ORDER также и к структурной системной переменной. Этот функционал относится к нестандартному, поэтому такую возможность нужно проверить в документации. Если поддерживается, то,
например, можно перечислить имеющиеся в MUMPS системе процессы
s job="" f s job=$o(^$J(job)) q:job="" w job,!
или открытые устройства
s dev="" f s dev=$o(^$D(dev)) q:dev="" w dev,!
Существуют реализации MUMPS систем, поддерживающие нестандартную трехаргументную форму функции $ORDER. В этом случае в
качестве третьего аргумента указывается переменная, которой необходимо присвоить значение переменной если оно существовало. Если значения с точно таким именем не существовало, то возвращается только
значение индекса, но присваивание не производится. Например, такой
функционал поддерживается Cach´e:
USER>s a(1)=1,a(2,1)=21,a(3)=3,a(4)=4
USER>s n="" f s n=$o(a(n),1,v) q:n="" w v,!
1
1
3
4
USER>s n="" f s n=$o(a(n),1,v) q:n="" w n,!
1
2
3
4
Здесь видно, что для индекса a(2) его значение возвращается, но
присваивание не выполняется.
В отношении функции $ORDER побочный эффект взведения индикатора голой ссылки в случае обращения к глобалу определен более
сложно - если следующее значение индекса существует, то индикатор
голой ссылки взводится в это значение. Если не существует, то в то

1.5. ФУНКЦИИ 79
имя, к которому обратились первоначально. Таким образом, побочный
результат зависит от того, существуют данные или нет, в отличие от
функций $DATA и $GET.
Первоначально в стандарте языка MUMPS функции $ORDER не было, она появилась только в 1984-м году, и в этой редакции была принята
одноаргументная форма. Двухаргументная форма, с возможностью прохода по убыванию, появилась лишь в стандарте языка 1995-го года. В
настоящее время все современные реализации MUMPS систем поддерживают эту функцию в полной мере.
В техническом отношении реализация функции $ORDER, в особенности реализация прохода назад, или в направлении обратном компрессии ключей, относится к наиболее сложным для выполнения на блоках
B* - деревьев. Существуют также СУБД, в которых для аналогичных к
функции $ORDER операций в документации делаются отдельные оговорки о необходимости применения опций asc или desc для индексов
во избежание существенного падения производительности, включая рекомендацию строить оба варианта индексов для случая если выборка с
сортировкой по индексу критична для прикладной системы.
Современные MUMPS системы выполняют функцию $ORDER как
в прямом направлении сортировки, так и в обратном, с примерно сопоставимой производительностью. Насколько показывает опыт применения
$ORDER в различных MUMPS системах, если падение производительности и можно определить, то оно ни разу не оказалось заметным либо
существенным.
1.5.4 $NEXT
До введения в стандарт языка функции $ORDER в языке использовалась функция $NEXT, в одноаргументной форме. В стандарте 1990-го
года эта функция была объявлена нерекомендованной к применению, и в
стандарте 1995-го года отсутствует. В настоящее время существуют реализации MUMPS систем, которые не поддерживают функцию $NEXT
и которые поддерживают для совместимости.
Функция $NEXT может вернуть следующее значение индекса только по возрастанию и в случае, если следующее значение индекса не
существует, то функция возвращает значение -1.
Для числовых индексов такое поведение неудобно тем, что для случая если функция вернула значение -1 необходимо различать, является
ли это значение следующим существующим или это индикатор несуществования, с помощью функции $DATA.

80 ГЛАВА 1. СРЕДА ИСПОЛНЕНИЯ
Последующее определение функции $ORDER уже учитывало тот
факт, что в MUMPS системах по умолчанию значения индексов равные пустой строке (пустые индексы) не разрешены. В случае же, если
в настройках MUMPS системы пустые индексы разрешены, то такую
операцию по дополнительной проверке также необходимо выполнять.
Большинство прикладных систем, как существующих так и разрабатываемых, опираются на соглашение о настройках по умолчанию и о
неиспользовании пустых индексов.
1.5.5 $QUERY
Функция $QUERY ($Q) принимает имя переменной и возвращает следующее существующее для этой переменной имя в порядке сортировки.
Особенность функции в том, что ей можно указать в аргументе имя,
но нельзя принять само имя как значение. Поэтому функция возвращает
строку с именем переменной. В случае если следующего имени функция
не нашла, она возвращает пустую строку.
Такое соглашение о возврате значения приводит к использованию
косвенности имени при итерациях. Если начальное значение имени может быть указано явно как имя переменной, то последующая итерация
уже должна использовать строку с именем. Чтобы перевести строку в
само имя, используется косвенность. Примерный типовой код применения функции $QUERY:
USER>s a(1)=1,a(2,2)=22,a(3,3,3)=333,a(4)=4
USER>s name=$na(a)
USER>f s name=$q(@name) q:name="" w name,!
a(1)
a(2,2)
a(3,3,3)
a(4)
В отличие от функции $ORDER функция $QUERY не рассматривает
переменную как дерево, а использует как набор сортированных записей
вида ключ - значение, но ключ может быть произвольным и составным.
Если функция $QUERY используется в одноаргументной форме, то
она перечисляет переменную в направлении возрастания индексов в порядке их сортировки.
Функция $QUERY поддерживает так же, как и функция $ORDER,
двухаргументную форму. Второй аргумент задает направление перечисления имен - если аргумент вычислен как значение 1, то функция пе-
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
