1.6 使用 NdbInterpretedCode

接下来的几节将提供有关使用 NdbInterpretedCode 方法执行不同类型操作的信息,包括资源使用情况。

用于将值加载到寄存器的 NdbInterpretedCode 方法

本节介绍的方法用于将常量值加载到 NdbInterpretedCode 程序寄存器中。下表显示了每种方法所需的空间

表 1.1 用于将常量值加载到 NdbInterpretedCode 程序寄存器中的 NdbInterpretedCode 方法,以及所需的缓冲区和请求消息空间。

方法 缓冲区(字) 请求消息(字)
load_const_null() 1 1
load_const_u16() 1 1
load_const_u32() 2 2
load_const_u64() 3 3

用于在寄存器和表列之间复制值的 NdbInterpretedCode 方法

NdbInterpretedCode 提供了两种用于在当前表行中的列和程序寄存器之间复制值的方法。read_attr() 方法用于将表列值复制到程序寄存器中;write_attr() 用于将值从程序寄存器复制到表列中。这两种方法都要求在为其调用方法的 NdbInterpretedCode 对象创建时指定要操作的表。

下表显示了每种方法所需的空间

表 1.2 用于在寄存器和表列之间复制值的 NdbInterpretedCode 方法,以及所需的缓冲区和请求消息空间。

方法 缓冲区(字) 请求消息(字)
read_attr() 1 1
write_attr() 1 1

有关更多信息,请参阅 NdbInterpretedCode::read_attr()NdbInterpretedCode::write_attr()

NdbInterpretedCode 寄存器算术方法

NdbInterpretedCode 提供了两种对寄存器执行算术运算的方法。使用 add_reg(),可以将两个寄存器的总和加载到另一个寄存器中;sub_reg() 允许将两个寄存器的差加载到另一个寄存器中。

下表显示了每种方法所需的空间

表 1.3 用于对寄存器执行算术运算的 NdbInterpretedCode 方法,以及所需的缓冲区和请求消息空间。

方法 缓冲区(字) 请求消息(字)
add_reg() 1 1
sub_reg() 1 1

有关更多信息,请参阅 NdbInterpretedCode::add_reg()NdbInterpretedCode::sub_reg()

NdbInterpretedCode:标签和分支

NdbInterpretedCode 类允许您在解释的程序中定义标签,并提供许多方法,可根据以下任何类型的条件执行跳转到这些标签的操作

  • 比较两个寄存器值

  • 比较列值和给定常量

  • 列值是否与给定模式匹配

要定义标签,请使用 def_label() 方法。

要执行到标签的无条件跳转,请使用 branch_label() 方法。

要根据寄存器值的比较结果执行到给定标签的跳转,请使用 branch_*() 方法之一(branch_ge()branch_gt()branch_le()branch_lt()branch_eq()branch_ne()branch_ne_null()branch_eq_null())。请参阅 基于寄存器的 NdbInterpretedCode 分支操作

要根据表列值的比较结果执行到给定标签的跳转,请使用 branch_col_*() 方法之一(branch_col_ge()branch_col_gt()branch_col_le()branch_col_lt()branch_col_eq()branch_col_ne()branch_col_ne_null()branch_col_eq_null())。请参阅 基于列的 NdbInterpretedCode 分支操作

要根据表列值的模式匹配结果执行跳转,请使用 branch_col_like()branch_col_notlike() 方法。请参阅 基于模式的 NdbInterpretedCode 分支操作

基于寄存器的 NdbInterpretedCode 分支操作

其中大多数用于根据寄存器到寄存器的比较结果进行分支。还有两种方法用于将寄存器值与 NULL 进行比较。所有这些方法都需要使用 def_label() 方法定义的标签作为参数。

可以将这些方法视为执行以下逻辑

if(register_value1 condition register_value2)
  goto Label

下表显示了每种方法所需的空间

表 1.4 基于寄存器的 NdbInterpretedCode 分支方法,以及所需的缓冲区和请求消息空间。

方法 缓冲区(字) 请求消息(字)
branch_ge() 1 1
branch_gt() 1 1
branch_le() 1 1
branch_lt() 1 1
branch_eq() 1 1
branch_ne() 1 1
branch_ne_null() 1 1
branch_eq_null() 1 1

基于列的 NdbInterpretedCode 分支操作

本节介绍的方法用于根据表列值和给定常量值之间的比较结果执行分支。这些方法中的每一种方法都期望使用要测试其值的列的属性 ID,而不是对 Column 对象的引用。

branch_col_eq_null()branch_col_ne_null() 之外,这些方法可以被视为执行以下逻辑

if(constant_value condition column_value)
  goto Label

在每种情况下(再次排除 branch_col_eq_null()branch_col_ne_null()),任意常量都是传递给方法的第一个参数。

下表显示了每种方法的空间要求,其中 L 表示常量值的长度

表 1.5 基于列的 NdbInterpretedCode 分支方法,以及所需的缓冲区和请求消息空间。

方法 缓冲区(字) 请求消息(字)
branch_col_eq_null() 2 2
branch_col_ne_null() 2 2
branch_col_eq() 2 2 + CEIL(L / 8)
branch_col_ne() 2 2 + CEIL(L / 8)
branch_col_lt() 2 2 + CEIL(L / 8)
branch_col_le() 2 2 + CEIL(L / 8)
branch_col_gt() 2 2 + CEIL(L / 8)
branch_col_ge() 2 2 + CEIL(L / 8)

注意

表达式 CEIL(L / 8) 是保存要比较的常量值所需的完整 8 字节字数。

基于模式的 NdbInterpretedCode 分支操作

NdbInterpretedCode 类提供了两种方法,可用于根据包含字符数据(即 CHARVARCHARBINARYVARBINARY 列)的列与正则表达式模式之间的比较结果执行分支。

正则表达式支持的模式语法与 MySQL 服务器的 LIKENOT LIKE 运算符支持的语法相同,包括 _% 元字符。有关这些内容的更多信息,请参见 字符串比较函数和运算符

注意

这与 NdbScanFilter 支持的正则表达式模式语法相同;有关更多信息,请参见 NdbScanFilter::cmp()

在实例化 NdbInterpretedCode 对象时,必须提供要操作的表。即使该列实际上是 VARCHAR,正则表达式模式也应该是纯 CHAR 格式(换句话说,不应该有前导长度字节)。

这些函数的行为如下所示

if (column_value [NOT] LIKE pattern)
  goto Label;

下表显示了这些方法的空间要求,其中 L 表示常量的长度

表 1.6 基于模式的 NdbInterpretedCode 分支方法,以及所需的缓冲区和请求消息空间。

方法 缓冲区(字) 请求消息(字)
branch_col_like() 2 2 + CEIL(L / 8)
branch_col_notlike() 2 2 + CEIL(L / 8)

注意

表达式 CEIL(L / 8) 是保存要比较的常量值所需的完整 8 字节字的数量。

NdbInterpretedCode 位比较操作

这些指令用于根据 BIT 列值和位掩码模式之间的逻辑 AND 比较结果进行分支。

使用这些方法要求在构造 NdbInterpretedCode 对象时提供要操作的表。掩码值的大小应与要比较的位列的大小相同。BIT 值作为 32 位字传入和传出 NDB API,位从最低有效位到最高有效位依次设置。执行指令的平台的字节序控制哪个字节包含最低有效位。在 x86 上,这是第一个字节(字节 0);在 SPARC 和 PPC 上,它是最后一个字节。

此处列出的每个方法的缓冲区长度和请求长度都需要等于 2 个字加上向上舍入到最接近的整数字的列宽的空间

NdbInterpretedCode 结果处理方法

本节中介绍的方法用于告诉解释器当前行的处理已完成,以及(在扫描的情况下)是否将此行包含在扫描结果中。

下表显示了这些方法的空间要求,其中 L 表示常量的长度

表 1.7 NdbInterpretedCode 结果处理方法,以及所需的缓冲区和请求消息空间。

方法 缓冲区(字) 请求消息(字)
interpret_exit_ok() 1 1
interpret_exit_nok() 1 1
interpret_exit_last_row() 1 1

NdbInterpretedCode 便捷方法

本节中介绍的方法可用于将多条指令(使用特定寄存器)插入到解释程序中。

重要

除了更新表列外,这些方法还使用解释器寄存器 6 和 7,将寄存器 6 中的任何现有内容替换为原始列值,并将寄存器 7 中的任何现有内容替换为修改后的列值。在实例化调用该方法的 NdbInterpretedCode 对象时,必须事先定义表本身。

下表显示了这些方法的空间要求,其中 L 表示常量的长度

表 1.8 NdbInterpretedCode 便捷方法,以及所需的缓冲区和请求消息空间。

方法 缓冲区(字) 请求消息(字)
add_val() 4 1;如果提供的值 >= 216:2;如果 >= 232:3
sub_val() 4 1;如果提供的值 >= 216:2;如果 >= 232:3

将子例程与 NdbInterpretedCode 一起使用

NdbInterpretedCode 支持从解释程序中调用的子例程,每个子例程都由唯一的编号标识。子例程只能在所有主程序指令之后定义。

重要

用于标识子例程的编号必须是连续的;但是,它们不必按任何特定顺序排列。

  • 子例程的开头是通过调用 def_sub() 方法来指示的;

  • ret_sub() 终止子例程;调用 def_sub() 之后的所有指令都属于该子例程,直到使用此方法终止它为止。

  • 子例程是使用 call_sub() 方法调用的。

子例程完成后,程序将从调用该子例程的指令之后的指令继续执行。子例程也可以从其他子例程中调用;目前,最大子例程堆栈深度为 32。

NdbInterpretedCode 实用方法

此处列出了 NdbInterpretedCode 提供的一些其他实用方法