Documentation Home
MySQL 5.6 リファレンスマニュアル
Download this Manual
PDF (US Ltr) - 27.1Mb
PDF (A4) - 27.1Mb
EPUB - 7.5Mb
HTML Download (TGZ) - 7.2Mb
HTML Download (Zip) - 7.2Mb


24.3.2.3 UDF 引数の処理

args パラメータは、次に示すメンバーを持つ UDF_ARGS 構造体を指しています。

  • unsigned int arg_count

    引数の数。特定の数の引数を使用して関数を呼び出す必要がある場合は、初期化関数でこの値をチェックします。例:

    if (args->arg_count != 2)
    {
        strcpy(message,"XXX() requires two arguments");
        return 1;
    }
    

    配列であるその他の UDF_ARGS メンバー値の場合、配列参照はゼロベースです。つまり、0 から args->arg_count − 1 までのインデックス値を使用して配列メンバーを参照します。

  • enum Item_result *arg_type

    各引数の型を格納する配列へのポインタ。指定可能な型の値は、STRING_RESULTINT_RESULTREAL_RESULT、および DECIMAL_RESULT です。

    引数が予期している型であることを確認し、そうではない場合にエラーを返すには、初期化関数で arg_type 配列をチェックします。例:

    if (args->arg_type[0] != STRING_RESULT ||
        args->arg_type[1] != INT_RESULT)
    {
        strcpy(message,"XXX() requires a string and an integer");
        return 1;
    }
    

    DECIMAL_RESULT 型の引数は文字列として渡されるため、STRING_RESULT 値と同様にこれらを処理する必要があります。

    関数の引数が特定の型であることを要求する代わりに、初期化関数を使用して、arg_type 要素を必要な型に設定できます。これにより、MySQL が xxx() の各呼び出しで引数をそれらの型に強制的に変更します。たとえば、最初の 2 つの引数がそれぞれ文字列および整数になるように強制的に指定するには、xxx_init() で次の操作を実行します。

    args->arg_type[0] = STRING_RESULT;
    args->arg_type[1] = INT_RESULT;
    

    1.3DECIMAL カラム値などの正確値型の 10 進数引数は、DECIMAL_RESULT 型で渡されます。ただし、値は文字列として渡されます。数値を受け取るには、初期化関数を使用して、引数が REAL_RESULT 値に強制的に変更されるように指定します。

    args->arg_type[2] = REAL_RESULT;
    
  • char **args

    args->args は、関数に渡される引数の一般的な性質についての情報を初期化関数に通知します。定数引数 i の場合、args->args[i] は引数値を指しています。(値に正しくアクセスする方法については、以降の説明を参照してください。)非定数引数の場合、args->args[i]0 です。定数引数は、34*7-2SIN(3.14) などの定数のみを使用した式です。非定数引数は、行によって変化することがある値を参照する式のことであり、カラム名、非定数引数を指定して呼び出される関数などがあります。

    メイン関数への各呼び出しで、args->args には、現在処理されている行に関して渡される実際の引数が含まれています。

    引数 iNULL の場合、args->args[i] はゼロポインタ (0) です。引数が NULL ではない場合、関数は引数を次のように参照できます。

    • STRING_RESULT 型の引数は、文字列ポインタおよび長さとして指定し、バイナリデータまたは任意の長さのデータを処理できます。文字列の内容は args->args[i] として取得でき、文字列の長さは args->lengths[i] です。文字列がゼロで終わると想定しないでください。

    • INT_RESULT 型の引数の場合は、args->args[i]long long 値にキャストする必要があります。

      long long int_val;
      int_val = *((long long*) args->args[i]);
      
    • REAL_RESULT 型の引数の場合は、args->args[i]double 値にキャストする必要があります。

      double    real_val;
      real_val = *((double*) args->args[i]);
      
    • DECIMAL_RESULT 型の引数の場合、値は文字列として渡さるため、STRING_RESULT 値と同様に処理されるようにしてください。

    • ROW_RESULT 引数は実装されていません。

  • unsigned long *lengths

    初期化関数の場合、lengths 配列は各引数の最大文字列長を示しています。これらは変更しないでください。メイン関数の各呼び出しで、lengths には、現在処理されている行に関して渡されるすべての文字列引数の実際の長さが含まれています。INT_RESULT 型または REAL_RESULT 型の引数の場合は、lengths には (初期化関数の場合と同様に) 引数の最大長が含まれています。

  • char *maybe_null

    初期化関数において、maybe_null 配列は、各引数について引数値が NULL の場合があるかどうかを示します (ない場合は 0、およびある場合は 1)。

  • char **attributes

    args->attributes は UDF 引数の名前についての情報を通知します。引数 i の場合、属性名は args->attributes[i] の文字列として取得でき、属性の長さは args->attribute_lengths[i] です。文字列がゼロで終わると想定しないでください。

    デフォルトでは、UDF 引数の名前は引数を指定するために使用される式のテキストです。UDF の場合、引数にはオプションの [AS] alias_name 句が含まれていることもあり、この場合の引数名は alias_name です。このため、各引数の attributes 値は、エイリアスが指定されているかどうかに応じて異なります。

    UDF my_udf() が次のように呼び出されたとします。

    SELECT my_udf(expr1, expr2 AS alias1, expr3 alias2);
    

    この場合、attributes 配列および attribute_lengths 配列の値は次のようになります。

    args->attributes[0] = "expr1"
    args->attribute_lengths[0] = 5
    
    args->attributes[1] = "alias1"
    args->attribute_lengths[1] = 6
    
    args->attributes[2] = "alias2"
    args->attribute_lengths[2] = 6
    
  • unsigned long *attribute_lengths

    attribute_lengths 配列は、各属性名の長さを示しています。


User Comments
  Posted by Ben Christensen on April 15, 2009
Here is the code for the ***_add() function that works for me in an aggregate function to get the correct arguments (ints and strings) for each row.

The documentation above clearly explains how to get an int (long long), but I had to play around for a bit to get a string to be retrieved properly (since I'm not a C programmer and it wasn't obvious and most attempts ended up with corrupted data). Perhaps this code can help another programmer used to Java, C# etc trying to get started with a UDF in C.

The output from this via the fprintf commands will go into the MySQL error log.

NOTE: This code is not ready to go into prod ... it allocates memory (malloc) but does not clean it up.

void
show_row_arguments_add(UDF_INIT* initid, UDF_ARGS* args, char* is_null __attribute__((unused)), char* message __attribute__((unused))) {

fprintf(stderr, "------------------------------------------\n");

int numArgs = args->arg_count;
int i = 0;
while (i < numArgs) {

if (args->args[i]) {

if (args->arg_type[i] == 0) {

unsigned long argLength = args->lengths[i];
char *stringText = args->args[i];

char* myValue = NULL;
myValue = (char *)malloc(argLength);

strncpy(myValue, stringText,argLength);

fprintf(stderr, "args->args[%d] = %s - ", i, myValue);
fprintf(stderr, "STRING_RESULT \n");

}
else if (args->arg_type[i] == 1) {
fprintf(stderr, "args->args[%d] = %d - ", i, args->args[i]);
fprintf(stderr, "REAL_RESULT \n");
}
else if (args->arg_type[i] == 2) {
long long int_val;
int_val = *((long long*) args->args[i]);
fprintf(stderr, "args->args[%d] = %d - ", i, int_val);
fprintf(stderr, "INT_RESULT \n");
}
}
else {
fprintf(stderr, "args->args[%d] = null \n", i);
}
i++;
}

}

---------------------

A simple test with this could use the following table:

CREATE TABLE `test` (
`grp` int(11) DEFAULT NULL,
`a` varchar(50) DEFAULT NULL,
`b` varchar(50) DEFAULT NULL,
`c` int(11) DEFAULT NULL,
`d` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8

insert into test values (1, 'HP', null, 1, 1);
insert into test values (1, 'Laser', null, 1, 1);
insert into test values (1, 'Printer', null, 1, 1);
insert into test values (1, null, ' COLOR' , 1, 1);

select show_row_arguments(a, b, c, d) from test group by grp;

You would see the following in the logs:

------------------------------------------
args->args[0] = HP - STRING_RESULT
args->args[1] = null
args->args[2] = 1 - INT_RESULT
args->args[3] = 1 - INT_RESULT
------------------------------------------
args->args[0] = Laser - STRING_RESULT
args->args[1] = null
args->args[2] = 1 - INT_RESULT
args->args[3] = 1 - INT_RESULT
------------------------------------------
args->args[0] = Printer - STRING_RESULT
args->args[1] = null
args->args[2] = 1 - INT_RESULT
args->args[3] = 1 - INT_RESULT
------------------------------------------
args->args[0] = null
args->args[1] = COLOR - STRING_RESULT
args->args[2] = 1 - INT_RESULT
args->args[3] = 1 - INT_RESULT

Sign Up Login You must be logged in to post a comment.