This chapter describes a lot of things that you need to know when
working on the MySQL code. If you plan to contribute to MySQL
development, want to have access to the bleeding-edge in-between
versions code, or just want to keep track of development, follow the
instructions in 「2.3.4 開発ソースツリーからのインストール」節.
If you are interested in MySQL internals, you should also subscribe
to our internals
mailing list. This list is relatively low
traffic. For details on how to subscribe, please see
「1.6.1.1 MySQL メーリングリスト」節.
All developers at MySQL AB are on the internals
list and we
help other people who are working on the MySQL code. Feel free to
use this list both to ask questions about the code and to send
patches that you would like to contribute to the MySQL project!
The MySQL server creates the following threads:
process_alarm()
to force timeouts on connections
that have been idle too long.
mysqld
is compiled with -DUSE_ALARM_THREAD
, a dedicated
thread that handles alarms is created. This is only used on some systems where
there are problems with sigwait()
or if one wants to use the
thr_alarm()
code in ones application without a dedicated signal
handling thread.
--flush_time=#
option, a dedicated thread is created
to flush all tables at the given interval.
INSERT DELAYED
gets its
own thread.
--master-host
, a slave replication thread will be
started to read and apply updates from the master.
mysqladmin processlist
only shows the connection, INSERT DELAYED
,
and replication threads.
Until recently, our main full-coverage test suite was based on proprietary
customer data and for that reason has not been publicly available. The only
publicly available part of our testing process consisted of the crash-me
test, a Perl DBI/DBD benchmark found in the sql-bench
directory, and
miscellaneous tests located in tests
directory. The lack of a
standardised publicly available test suite has made it difficult for our users,
as well developers, to do regression tests on the MySQL code. To
address this problem, we have created a new test system that is included in
the source and binary distributions starting in Version 3.23.29.
The current set of test cases doesn't test everything in MySQL, but it should catch most obvious bugs in the SQL processing code, OS/library issues, and is quite thorough in testing replication. Our eventual goal is to have the tests cover 100% of the code. We welcome contributions to our test suite. You may especially want to contribute tests that examine the functionality critical to your system, as this will ensure that all future MySQL releases will work well with your applications.
The test system consist of a test language interpreter
(mysqltest
), a shell script to run all
tests(mysql-test-run
), the actual test cases written in a special
test language, and their expected results. To run the test suite on
your system after a build, type make test
or
mysql-test/mysql-test-run
from the source root. If you have
installed a binary distribution, cd
to the install root
(eg. /usr/local/mysql
), and do scripts/mysql-test-run
.
All tests should succeed. If not, you should try to find out why and
report the problem if this is a bug in MySQL.
「9.1.2.3 Reporting Bugs in the MySQL Test Suite」節参照.
If you have a copy of mysqld
running on the machine where you want to
run the test suite you do not have to stop it, as long as it is not using
ports 9306
and 9307
. If one of those ports is taken, you should
edit mysql-test-run
and change the values of the master and/or slave
port to one that is available.
You can run one individual test case with
mysql-test/mysql-test-run test_name
.
If one test fails, you should test running mysql-test-run
with
the --force
option to check if any other tests fails.
You can use the mysqltest
language to write your own test cases.
Unfortunately, we have not yet written full documentation for it - we plan to
do this shortly. You can, however, look at our current test cases and use
them as an example. The following points should help you get started:
mysql-test/t/*.test
;
terminated statements and is similar to the
input of mysql
command-line client. A statement by default is a query
to be sent to MySQL server, unless it is recognised as internal
command (eg. sleep
).
SELECT
, SHOW
,
EXPLAIN
, etc., must be preceded with @/path/to/result/file
. The
file must contain the expected results. An easy way to generate the result
file is to run mysqltest -r < t/test-case-name.test
from
mysql-test
directory, and then edit the generated result files, if
needed, to adjust them to the expected output. In that case, be very careful
about not adding or deleting any invisible characters - make sure to only
change the text and/or delete lines. If you have to insert a line, make sure
the fields are separated with a hard tab, and there is a hard tab at the end.
You may want to use od -c
to make sure your text editor has not messed
anything up during edit. We, of course, hope that you will never have to edit
the output of mysqltest -r
as you only have to do it when you find a
bug.
mysql-test/r
directory and name them test_name.result
. If the
test produces more than one result, you should use test_name.a.result
,
test_name.b.result
, etc.
--error error-number
. The error number can be
a list of possible error numbers separated with ','
.
source include/master-slave.inc;
. To switch between
master and slave, use connection master;
and connection slave;
.
If you need to do something on an alternate connection, you can do
connection master1;
for the master, and connection slave1;
for
the slave.
let $1=1000; while ($1) { # do your queries here dec $1; }
sleep
command. It supports fractions
of a second, so you can do sleep 1.3;
, for example, to sleep 1.3
seconds.
mysql-test/t/test_name-slave.opt
. For
the master, put them in mysql-test/t/test_name-master.opt
.
If your MySQL version doesn't pass the test suite you should do the following:
mysqlbug
script
so that we can get information about your system and MySQL
version. 「1.6.1.3 バグや問題を報告する方法」節参照.
mysql-test-run
, as well as
contents of all .reject
files in mysql-test/r
directory.
cd mysql-test mysql-test-run --local test-nameIf this fails, then you should configure MySQL with
--with-debug
and run mysql-test-run
with the
--debug
option. If this also fails send the trace file
`var/tmp/master.trace' to ftp://support.mysql.com/pub/mysql/secret
so that we can examine it. Please remember to also include a full
description of your system, the version of the mysqld binary and how you
compiled it.
mysql-test-run
with the --force
option to
see if there is any other test that fails.
Result length mismatch
or Result
content mismatch
it means that the output of the test didn't match
exactly the expected output. This could be a bug in MySQL or
that your mysqld version produces slight different results under some
circumstances.
Failed test results are put in a file with the same base name as the
result file with the .reject
extension. If your test case is
failing, you should do a diff on the two files. If you cannot see how
they are different, examine both with od -c
and also check their
lengths.
mysql-test/var/log
directory for hints of what went wrong.
mysql-test-run
with the --gdb
and/or --debug
options.
「E.1.2 Creating Trace Files」節参照.
If you have not compiled MySQL for debugging you should probably
do that. Just specify the --with-debug
options to configure
!
「2.3 MySQL ソースディストリビューションのインストール」節参照.
There are two ways to add new functions to MySQL:
CREATE FUNCTION
と DROP FUNCTION
ステー
トメントを使用して、動的に追加、削除されます。
「9.2.1 CREATE FUNCTION/DROP FUNCTION
Syntax」節参照.
mysqld
サーバに統合され、恒久的に有効になります。
それぞれの方法には、有利な点と不利な点があります:
新しい関数を追加するためにどちらの方法を使用しても、ABS()
や
SOUNDEX()
のようなネイティブ関数と同じように使用することができま
す。
CREATE FUNCTION/DROP FUNCTION
SyntaxCREATE [AGGREGATE] FUNCTION function_name RETURNS {STRING|REAL|INTEGER} SONAME shared_library_name DROP FUNCTION function_name
A user-definable function (UDF) is a way to extend MySQL with a new
function that works like native (built in) MySQL functions such as
ABS()
and CONCAT()
.
AGGREGATE
is a new option for MySQL Version 3.23. An
AGGREGATE
function works exactly like a native MySQL
GROUP
function like SUM
or COUNT()
.
CREATE FUNCTION
saves the function's name, type, and shared library
name in the mysql.func
system table. You must have the
INSERT
and DELETE
privileges for the mysql
database
to create and drop functions.
All active functions are reloaded each time the server starts, unless
you start mysqld
with the --skip-grant-tables
option. In
this case, UDF initialisation is skipped and UDFs are unavailable.
(An active function is one that has been loaded with CREATE FUNCTION
and not removed with DROP FUNCTION
.)
For instructions on writing user-definable functions, see 「9.2 MySQL への新しい関数の追加」節. For the UDF mechanism to work, functions must be written in C or
C++, your operating system must support dynamic loading and you must have
compiled mysqld
dynamically (not statically).
Note that to make AGGREGATE
work, you must have a
mysql.func
table that contains the column type
. If this
is not the case, you should run the script
mysql_fix_privilege_tables
to get this fixed.
UDF 機構が動作するためには、関数は C か C++ で書かれる必要があり、OS が 動的ローディングをサポートする必要があります。MySQL ソース配布 は `sql/udf_example.cc' を含んでいて、これは5つの新しい関数を定義 しています。UDF の呼び出し方法がどのように働くかはこのファイルを参考にし てください。
For mysqld
to be able to use UDF functions, you should configure MySQL
with --with-mysqld-ldflags=-rdynamic
The reason is that to on
many platforms (including Linux) you can load a dynamic library (with
dlopen()
) from a static linked program, which you would get if
you are using --with-mysqld-ldflags=-all-static
If you want to
use an UDF that needs to access symbols from mysqld
(like the
methaphone
example in `sql/udf_example.cc' that uses
default_charset_info
), you must link the program with
-rdynamic
(see man dlopen
).
SQL ステートメントで使用したいそれぞれの関数について、対応する C (または
C++) 関数を定義すべきです。下の説明では、名前 ``xxx'' がサンプル関数名と
して使用されています。SQL と C/C++ 使用法を distinquish するために、
XXX()
(大文字) は SQL 関数呼び出しを表わし、xxx()
(小文字)
は C/C++ 関数呼び出しを表わします。
XXX()
のインタフェースを実装するために書く C/C++ 関数は:
xxx()
(必要)
SQL type | C/C++ type |
STRING | char *
|
INTEGER | long long
|
REAL | double
|
xxx_init()
(オプション)
xxx()
の初期化関数。これは次のように使用されます:
XXX()
の引数の数のチェック
REAL
関数では) 小数部の最大桁数の指定
NULL
になり得るかどうかの指定
xxx_deinit()
(オプション)
xxx()
の終了関数(deinitialization function)。これは初期化関数によっ
て割り当てられたメモリを解放すべきです。
SQL ステートメントが XXX()
を呼び出すとき、MySQL は引数
チェックやメモリ割り当てのように、必要なセットアップを行なわせるために、
初期化関数 xxx_init()
を呼び出します。xxx_init()
がエラー
を返す場合、SQL ステートメントはエラーメッセージと共に異常終了し、メイン
関数と終了関数は呼び出されません。そうでなければ、メイン関数
xxx()
が各行毎に呼び出されます。全ての行が処理された後、終了関数
xxx_deinit()
が、必要な掃除を行なうために、呼び出されます。
For aggregate functions (like SUM()
), you must also provide the
llowing functions:
xxx_reset()
(required)
xxx_add()
(required)
When using aggregate UDF functions MySQL works the following way:
xxx_init()
to let the aggregate function allocate the memory it
will need to store results.
GROUP BY
expression.
xxx_reset()
function.
xxx_add()
function.
xxx()
to get the result for the aggregate.
xxx_deinit()
to let the UDF free any memory it has allocated.
全ての関数はスレッド安全でなくてはいけません(メイン関数だけでなく、初期
化関数と終了関数も同様です)。これは変更されうるグローバル変数や静的変数
を割り当てることは許されないことを意味します! メモリが必要な場合は、
xxx_init()
で割り当て、xxx_deinit()
でそれを解放すべきです。
メイン関数は下に示すように宣言されるべきです。戻り値型と引数は、
CREATE FUNCTION
ステートメントで、SQL 関数 XXX()
の戻り値
をSTRING
, INTEGER
, REAL
のどれに宣言するかに依存し
て異なることに注意してください:
STRING
関数では:
char *xxx(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *length, char *is_null, char *error);
INTEGER
関数では:
long long xxx(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error);
REAL
関数では:
double xxx(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error);
初期化と終了関数は次のように宣言します
my_bool xxx_init(UDF_INIT *initid, UDF_ARGS *args, char *message); void xxx_deinit(UDF_INIT *initid);
initid
引数は3つの関数全てに渡されます。これは UDF_INIT
構造体を示し、関数間で情報を伝達するために使用されます。UDF_INIT
構造体のメンバは下に一覧します。初期化関数は変更したい全てのメンバを埋め
るべきです。(メンバにデフォルトを使用するには、未変更のままにしてくださ
い。)
my_bool maybe_null
xxx()
が NULL
を返す場合、xxx_init()
は
maybe_null
を 1
に設定すべきです。デフォルト値は、引数のい
ずれかが maybe_null
として宣言された場合、1
です。
unsigned int decimals
1.34
, 1.345
, 1.3
が渡された場合、
デフォルトは 3 です。1.345
が 3 桁の小数部を持つためです。)
unsigned int max_length
initid->decimals
で示される小数部の桁数を加えたものです。(数値関数では、長さは符号と小数
点文字を含みます。)
If you want to return a blob, you can set this to 65K or 16M; this
memory is not allocated but used to decide which column type to use if
there is a need to temporary store the data.
char *ptr
initid->ptr
を使用できます。
xxx_init()
では、メモリを獲得し、このポインタに割り当てます:
initid->ptr = allocated_memory;
xxx()
と xxx_deinit()
では、initid->ptr
を参照して、
メモリを使用または解放します。
Here follows a description of the different functions you need to define when you want to create an aggregate UDF function.
char *xxx_reset(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error);
This function is called when MySQL finds the first row in a new group. In the function you should reset any internal summary variables and then set the given argument as the first argument in the group.
In many cases this is implemented internally by reseting all variables
and then calling xxx_add()
.
char *xxx_add(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error);
This function is called for all rows that belongs to the same group, except for the first row. In this you should add the value in UDF_ARGS to your internal summary variable.
The xxx()
function should be declared identical as when you
define a simple UDF function. 「9.2.2.1 UDF Calling Sequences」節参照.
This function is called when all rows in the group has been processed.
You should normally never access the args
variable here but
return your value based on your internal summary variables.
All argument processing in xxx_reset()
and xxx_add()
should be done identically as for normal UDF functions. 「9.2.2.3 引数処理」節参照.
The return value handling in xxx()
should be done identically as
for a normal UDF. 「9.2.2.4 戻り値とエラー処理」節参照.
The pointer argument to is_null
and error
is the same for
all calls to xxx_reset()
, xxx_add()
and xxx()
.
You can use this to remember that you got an error or if the xxx()
function should return NULL
. Note that you should not store a string
into *error
! This is just a 1 byte flag!
is_null
is reset for each group (before calling xxx_reset()
.
error
is never reset.
If isnull
or error
are set after xxx()
then MySQL
will return NULL
as the result for the group function.
args
引数は次に示すメンバを持つ UDF_ARGS
構造体へのポイン
タです:
unsigned int arg_count
if (args->arg_count != 2) { strcpy(message,"XXX() requires two arguments"); return 1; }
enum Item_result *arg_type
STRING_RESULT
, INT_RESULT
,
REAL_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; }関数の引数が特定の型を要求するための代案として、初期化関数を使用して、
arg_type
要素を求める型に設定できます。これは MySQL に
xxx()
の各呼び出しにこれらの型を引数に強制するようにさせます。例
えば、最初の2つの引数に文字列と整数を強制するように指定するには、
xxx_init()
で次を行なってください:
args->arg_type[0] = STRING_RESULT; args->arg_type[1] = INT_RESULT;
char **args
args->args
は、関数が呼ばれる時の引数の一般的な特性について、情報
を初期化関数に伝達します。定数引数 i
について、
args->args[i]
は引数値のをポイントします。(値への正しいアクセス方
法については後述。)非定数引数について、args->args[i]
は 0
です。定数引数は定数だけを使用する表現で、3
, 4*7-2
,
SIN(3.14)
などです。非定数引数は行から行に変更される値を参照する
表現で、項目名や非定数引数で呼び出される関数などです。
メイン関数のそれぞれの呼び出しについて、args->args
は現在処理され
ている行に渡される実際の引数を含んでいます。
関数は次のように引数 i
を参照できます:
STRING_RESULT
型の引数は、バイナリデータまたは任意の長さのデータ
の処理を許すため、文字列ポインタ+長さとして与えられます。文字列内容は
args->args[i]
として有効で、文字列長は args->lengths[i]
で
す。文字列は NULL 終端とみなすべきではありません。
INT_RESULT
型の引数について、args->args[i]
を
long long
値にキャストする必要があります:
long long int_val; int_val = *((long long*) args->args[i]);
REAL_RESULT
, you must cast
args->args[i]
to a double
value:
double real_val; real_val = *((double*) args->args[i]);
unsigned long *lengths
lengths
配列は各引数についての最大文字列長を示し
ます。メイン関数の各呼び出しについては、lengths
は、現在処理され
ている行に渡される任意の文字列引数の実際の長さを含んでいます。
INT_RESULT
, REAL_RESULT
型の引数については、lengths
はまだ引数の最大長を含んでいます(初期化関数については)。
初期化関数は、エラーが無い場合は 0
を、そうでなければ 1
を
返すべきです。エラーが発生する場合は、xxx_init()
は NULL 終端エラー
メッセージを message
パラメータに格納すべきです。このメッセージは
クライアントに返されます。メッセージバッファは MYSQL_ERRMSG_SIZE
文字長ですが、80 文字より小さく保つように試みるべきです。標準的な端末画
面の幅にフィットするようにです。
メイン関数 xxx()
の返す値は long long
と double
関
数については関数値です。文字列関数については、result
と
length
引数で文字列が返されます。result
は少なくとも 255
バイト長のバッファです。これらに内容と戻り値の長さを設定してください。例
えば:
memcpy(result, "result string", 13); *length = 13;
The result
buffer that is passed to the calc function is 255 byte
big. If your result fits in this, you don't have to worry about memory
allocation for results.
あなたの文字列関数が 255 バイトよりも長い文字列を返す必要がある場合、
xxx_init()
関数または xxx()
関数内で malloc()
で領域
を割り当て、xxx_deinit()
関数でそれを解放する必要があります。将来の
xxx()
呼び出しによって再利用されるように、割り当てたメモリを
UDF_INIT
構造体の ptr
スロットに格納できます。
「9.2.2.1 UDF Calling Sequences」節参照.
メイン関数で NULL
値の戻り値を示すには、is_null
を
1
に設定してください:
*is_null = 1;
To indicate an error return in the main function, set the error
parameter to 1
:
*error = 1;
xxx()
が任意の行について *error
に 1
を設定する場合、
関数値は現在の行についてと、その後の XXX()
が呼び出されるステート
メントによって処理される任意の行について NULL
です。(xxx()
は続く行については呼び出しさえされません。) 注意: 3.22.10 より
前の MySQL バージョンでは、*error
と *is_null
の
両方に設定すべきです:
*error = 1; *is_null = 1;
UDF を実装するファイルはサーバが動作するホスト上でコンパイルされインストー ルされないければなりません。この処理はサンプル UDF ファイル `udf_example.cc' について次に説明します。これは MySQL ソー ス配布に含まれています。このファイルは次の関数を含みます:
metaphon()
は文字列引数の metaphon 文字列を返します。これは時には
soundex 文字列ですが、さらに英語用に調整されています。
myfunc_double()
は引数の文字の ASCII 値の合計を引数の長さの合計で
割った値を返します。
myfunc_int()
は引数の長さの合計を返します。
sequence([const int])
returns an sequence starting from the given
number or 1 if no number has been given.
lookup()
はホスト名の IP 番号を返します。
reverse_lookup()
は IP 番号のホスト名を返します。この関数は文字列
"xxx.xxx.xxx.xxx"
または4つの数値とともに呼ばれます。
動的ロード可能ファイルは、次のような何らかのコマンドを使用して、共有オブ ジェクトファイルとしてコンパイルされるべきです:
shell> gcc -shared -o udf_example.so myfunc.cc
MySQL ソースツリーの `sql' ディレクトリ内で次のコマンドを 実行することにより、システムのコンパイラオプションを簡単に正しく見つけ出 すことができます:
shell> make udf_example.o
make
が表示するものに似たコンパイルコマンドを実行すべきですが、行
末近くの -c
オプションを取り除いて、-o udf_example.so
を行
末につけてください。(いくつかのシステムでは、コマンドに -c
を残す
必要があります。)
UDF を含む共有オブジェクトをコンパイルすると、それをインストールしてその
ことを MySQL に知らせる必要があります。`udf_example.cc' か
らの共有オブジェクトのコンパイルは、`udf_example.so' のような何かの
ファイル名を提供します(実際の名前はプラットフォームによって変わります)。
このファイルを `/usr/lib' のような ld
が探すどこかのディレク
トリにコピーしてください。多くのシステムでは、LD_LIBRARY
または
LD_LIBRARY_PATH
環境変数を設定して、UDF 関数ファイルがあるディレ
クトリを示すことができます。dlopen
マニュアルページはシステム上で
使用すべき変数を教えてくれます。これを mysql.server
または
safe_mysqld
スタートアップスクリプトに設定し、
mysqld
を再起動すべきです。
ライブラリがインストールされた後、mysqld
に新しい関数について次の
コマンドで通知すべきです:
mysql> CREATE FUNCTION metaphon RETURNS STRING SONAME "udf_example.so"; mysql> CREATE FUNCTION myfunc_double RETURNS REAL SONAME "udf_example.so"; mysql> CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "udf_example.so"; mysql> CREATE FUNCTION lookup RETURNS STRING SONAME "udf_example.so"; mysql> CREATE FUNCTION reverse_lookup -> RETURNS STRING SONAME "udf_example.so"; mysql> CREATE AGGREGATE FUNCTION avgcost -> RETURNS REAL SONAME "udf_example.so";
関数は DROP FUNCTION
を使用して削除できます:
mysql> DROP FUNCTION metaphon; mysql> DROP FUNCTION myfunc_double; mysql> DROP FUNCTION myfunc_int; mysql> DROP FUNCTION lookup; mysql> DROP FUNCTION reverse_lookup; mysql> DROP FUNCTION avgcost;
CREATE FUNCTION
と DROP FUNCTION
ステートメントは
mysql
データベース内のシステムテーブル func
を更新します。
関数の名前、型、共有ライブラリ名はテーブルに保存されます。作成と破棄機能
のためには、mysql
データベースに INSERT
と
DELETE
権限を持つ必要があります。
既に生成してある関数を追加するために CREATE FUNCTION
を使用すべき
ではありません。関数の再インストールが必要な場合は、DROP FUNCTION
でそれを削除し、それから CREATE FUNCTION
で再インストールすべきで
す。例えば、関数の新しいバージョンの再コンパイルをした場合、
mysqld
が新しいバージョンを得るために、これを行なう必要があるでしょ
う。そうでなければ、サーバは古いバージョンの使用を継続します。
mysqld
を --skip-grant-tables
オプションで起動しなくても、
有効な関数はサーバの開始毎に再読み込みされます。この場合、UDF 初期化は飛
ばされ、UDF が無効になります。(有効な関数は CREATE FUNCTION
でロー
ドされているもので、DROP FUNCTION
で削除されていないものです。)
ネイティブ関数を追加するためのプロシジャを以下に示します。バイナリ配布に はネイティブ関数を追加できないことに注意してください。プロシジャは MySQL ソースコードの変更を必要とするためです。MySQL を ソース配布から自分でコンパイルする必要があります。また、MySQL の他のバージョンに移行する場合(例えば、新しいバージョンがリリースされた 時)、新しいバージョンでこのプロシジャを繰り返す必要があります。
新しいネイティブ MySQL 関数を追加するためには、次のステップに従っ てください:
sql_functions[]
配列内で関数名を定義している `lex.h' に1行
追加してください。
sql_functions[]
array and add a function that creates a function
object in `item_create.cc'. Take a look at "ABS"
and
create_funcs_abs()
for an example of this.
If the function prototype is complicated (for example takes a variable number
of arguments), you should add two lines to `sql_yacc.yy'.
一つは、yacc
が定義す
べきプリプロセッサシンボルを指示します(これはファイルの先頭に追加すべき
です)。それから関数パラメータを定義し、これらのパラメータとともに
``item'' を simple_expr
パース規則に追加します。例えば、これがど
のように動作するかを見るには、`sql_yacc.yy' 内の ATAN
の
全ての出来事をチェックしてください。
Item_num_func
または Item_str_func
から継承するクラス
を宣言してください。
double Item_func_newname::val() longlong Item_func_newname::val_int() String *Item_func_newname::Str(String *str)If you inherit your object from any of the standard items (like
Item_num_func
you probably only have to define one of the above
functions and let the parent object take care of the other functions.
For example, the Item_str_func
class defines a val()
function
that executes atof()
on the value returned by ::str()
.
void Item_func_newname::fix_length_and_dec()この関数は与えられた引数に基づいて少なくとも
max_length
を計算す
べきです。max_length
は関数が返し得る文字の最大数です。この関数は、
メイン関数が NULL
値を返すことがない場合は、maybe_null = 0
も設定すべきです。関数は、引数の maybe_null
変数をチェックするこ
とで、関数の任意の引数が NULL
を返しうるかどうかをチェックできま
す。
You
can take a look at Item_func_mod::fix_length_and_dec
for a
typical example of how to do this.
全ての関数はスレッド安全である必要があります (In other words, don't use any global or static variables in the functions without protecting them with mutexes).
If you want to return NULL
, from ::val()
, ::val_int()
or ::str()
you should set null_value
to 1 and return 0.
::str()
オブジェクト関数については、次のいくつかの追加検討事項があ
ります:
String *str
引数は、結果を保持するために使用される文字列バッファ
を提供します。
(For more information about the String
type,
take a look at the `sql_string.h' file.)
::str()
function should return the string that holds the result or
(char*) 0
if the result is NULL
.
MySQL ではC++で書かれたプロシージャを定義することが
できます。 これらのプロシージャを使うとデータが
クライアントに送信される前にクエリー内でデータにアクセス、
修正することが可能です。 データの修正は列単位、あるいは
グループ単位(GROUP BY
)で行えます。
プロシージャを使って何ができるかをご覧いただくために、 MySQL バージョン3.23を使ったサンプルを用意しました。
さらに Contrib ディレクトリにある 'mylua'
を参考にされることをお薦めします。 「B Contributed Programs」節参照。
myluaではLUA言語を使って、
ランタイム時にプロシージャを mysqld
にロードすることができます。
Additionally we recommend you to take a look at mylua
.
With this you can use the LUA language to load a procedure at
runtime into mysqld
.
analyse([max elements,[max memory]])
このプロシージャは `sql/sql_analyse.cc' によって定義されています。 クエリーの結果を調べ、 分析結果を返します:
max elements
(デフォルト値は256)とは、 一つの行において
analyse
プロシージャが認識する値の数(重複するものは除く)の
最大値です。 最大エレメント数は analyse
プロシージャがその行に
最適なデータ型が ENUM
型であるかどうかを判別するために使
われます。
max memory
(デフォルト値は8192)とは、 analyse
プロシージャが
1つの行に含まれる重複しない全ての値を探し出す際に、 1つの行に
割り当てるメモリーの最大サイズです。
SELECT ... FROM ... WHERE ... PROCEDURE ANALYSE([max elements,[max memory]])
今のところ、 この項目にはソースコードしかありません。
プロシージャに関する全ての情報は以下のファイルにありますのでご覧下さい:
Go to the first, previous, next, last section, table of contents.