58.2. Создание нестандартных планов сканирования #
Нестандартное сканирование представляется в окончательном дереве плана в виде следующей структуры:
typedef struct CustomScan { Scan scan; uint32 flags; List *custom_plans; List *custom_exprs; List *custom_private; List *custom_scan_tlist; Bitmapset *custom_relids; const CustomScanMethods *methods; } CustomScan;
Объект в поле scan
должен быть инициализирован, как и для любого другого сканирования, и включать оценки стоимости, целевые списки, условия и т. д. Поле flags
содержит битовую маску с тем же значением, что и в CustomPath
. В поле custom_plans
могут быть сохранены дочерние узлы Plan
. В custom_exprs
могут быть сохранены деревья выражений, которые будут исправляться кодом в setrefs.c
и subselect.c
, а в custom_private
следует сохранить другие внутренние данные, которые будут использоваться только самим провайдером нестандартного сканирования. Поле custom_scan_tlist
может содержать NIL при сканировании базового отношения, что будет показывать, что нестандартное сканирование возвращает кортежи, соответствующие типу строк базового отношения. В противном случае оно должно указывать на целевой список, описывающий фактические кортежи. Список custom_scan_tlist
должен устанавливаться при соединениях и может задаваться при сканировании, если провайдер сканирования может вычислять какие-либо выражения без переменных. Поле custom_relids
заполняется ядром и задаёт набор отношений (индексов в списке отношений), которые обрабатывает данный узел сканирования; когда имеет место сканирование, а не соединение, в этом списке будет всего один элемент. Поле methods
должно указывать на объект (обычно статически размещённый), реализующий требуемые методы нестандартного сканирования, которые подробнее описываются ниже.
Когда CustomScan
сканирует одно отношение, в scan.scanrelid
должен задаваться индекс сканируемой таблицы в списке отношений. Когда он заменяет соединение, поле scan.scanrelid
должно быть нулевым.
Деревья планов должны поддерживать возможность копирования функцией copyObject
, так что все данные, сохранённые в «дополнительных» полях, должны быть узлами, которые может обработать эта функция. Более того, провайдеры нестандартного сканирования не могут заменять структуру CustomScan
расширенной структурой, её содержащей, что возможно с CustomPath
или CustomScanState
.
58.2.1. Обработчики плана нестандартного сканирования #
Node *(*CreateCustomScanState) (CustomScan *cscan);
Выделяет структуру CustomScanState
для заданного объекта CustomScan
. Фактически выделенная область будет обычно больше, чем требуется для самой структуры CustomScanState
, так как многие провайдеры могут включать её в расширенную структуру в качестве первого поля. В возвращаемом значении должны быть подходящим образом заполнены тег узла и поле methods
, но другие поля на данном этапе должны быть обнулены; после того как ExecInitCustomScan
произведёт базовую инициализацию, будет вызван обработчик BeginCustomScan
, в котором провайдер нестандартного сканирования может выполнить все остальные требуемые действия.
51.33. pg_opclass
The catalog pg_opclass
defines index access method operator classes. Each operator class defines semantics for index columns of a particular data type and a particular index access method. An operator class essentially specifies that a particular operator family is applicable to a particular indexable column data type. The set of operators from the family that are actually usable with the indexed column are whichever ones accept the column's data type as their left-hand input.
Operator classes are described at length in Section 37.16.
Table 51.33. pg_opclass
Columns
Column Type Description |
---|
Row identifier |
Index access method operator class is for |
Name of this operator class |
Namespace of this operator class |
Owner of the operator class |
Operator family containing the operator class |
Data type that the operator class indexes |
True if this operator class is the default for |
Type of data stored in index, or zero if same as |
An operator class's opcmethod
must match the opfmethod
of its containing operator family. Also, there must be no more than one pg_opclass
row having opcdefault
true for any given combination of opcmethod
and opcintype
.