Commit 7202c21b authored by Michael Widenius's avatar Michael Widenius

Merge of patch lp:~ahiguti100/maria/handlersocket-fix-78 by Akira Higuchi

A bugfix of HandlerSocket is not applied to mariadb yet
parent 53d44ad1
...@@ -66,7 +66,7 @@ Here is a list of other language bindings: ...@@ -66,7 +66,7 @@ Here is a list of other language bindings:
https://github.com/koichik/node-handlersocket https://github.com/koichik/node-handlersocket
The home of HandlerSocket is here: The home of HandlerSocket is here:
https://github.com/ahiguti/HandlerSocket-Plugin-for-MySQL https://github.com/DeNADev/HandlerSocket-Plugin-for-MySQL
More documents are available in docs-en/ and docs-ja/ directories. More documents are available in docs-en/ and docs-ja/ directories.
...@@ -17,10 +17,11 @@ crash, etc). ...@@ -17,10 +17,11 @@ crash, etc).
$ ./autogen.sh $ ./autogen.sh
$ ./configure --with-mysql-source=/work/mysql-5.1.50 --with-mysql-bindir=/work/mysql-5.1.50-linux-x86_64-glibc23/bin --with-mysql-plugindir=/work/mysql-5.1.50-linux-x86_64-glibc23/lib/plugin $ ./configure --with-mysql-source=/work/mysql-5.1.50 --with-mysql-bindir=/work/mysql-5.1.50-linux-x86_64-glibc23/bin --with-mysql-plugindir=/work/mysql-5.1.50-linux-x86_64-glibc23/lib/plugin
--with-mysql-source refers to the top of MySQL source directory, --with-mysql-source refers to the top of MySQL source directory (which
--with-mysql-bindir refers to where MySQL binary executables (i.e. contains the VERSION file or the configure.in file), --with-mysql-bindir
mysql_config) are located, and --with-mysql-plugindir refers to a plugin refers to where MySQL binary executables (i.e. mysql_config) are located,
directory where plugin libraries (*.so) are installed. and --with-mysql-plugindir refers to a plugin directory where plugin
libraries (*.so) are installed.
$ make $ make
$ sudo make install $ sudo make install
......
...@@ -93,7 +93,6 @@ The execute_single method can be used for inserting records also. ...@@ -93,7 +93,6 @@ The execute_single method can be used for inserting records also.
my $res = $hs->execute_single(3, '+', [ 'foo', 'bar', 'baz' ]); my $res = $hs->execute_single(3, '+', [ 'foo', 'bar', 'baz' ]);
die $hs->get_error() if $res->[0] != 0; die $hs->get_error() if $res->[0] != 0;
my $num_inserted_rows = $res->[1];
The 3rd argument must be an arrayref whose elements correspond to The 3rd argument must be an arrayref whose elements correspond to
the 5th argument for the corresponding open_index call. If there the 5th argument for the corresponding open_index call. If there
...@@ -116,6 +115,15 @@ executing them separatedly. ...@@ -116,6 +115,15 @@ executing them separatedly.
# ... # ...
} }
-----------------------------------------------------------------
If handlersocket is configured to authenticate client connections
(ie., handlersocket_plain_secret or handlersocket_plain_secret_wr
is set), a client must call 'auth' method before any other
methods.
my $res = $hs->auth('password');
die $hs->get_error() if $res->[0] != 0;
----------------------------------------------------------------- -----------------------------------------------------------------
When an error is occured, the first element of the returned When an error is occured, the first element of the returned
arrayref becomes a non-zero value. A negative value indicates arrayref becomes a non-zero value. A negative value indicates
......
...@@ -29,7 +29,7 @@ Request and Response ...@@ -29,7 +29,7 @@ Request and Response
lines) at one time, and receive responses for them at one time. lines) at one time, and receive responses for them at one time.
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
'open_index' request Opening index
The 'open_index' request has the following syntax. The 'open_index' request has the following syntax.
...@@ -74,23 +74,21 @@ FILETER is a sequence of the following parameters. ...@@ -74,23 +74,21 @@ FILETER is a sequence of the following parameters.
HandlerSocket supports '=', '>', '>=', '<', and '<='. HandlerSocket supports '=', '>', '>=', '<', and '<='.
- <vlen> indicates the length of the trailing parameters <v1> ... <vn>. This - <vlen> indicates the length of the trailing parameters <v1> ... <vn>. This
must be smaller than or equal to the number of index columns specified by must be smaller than or equal to the number of index columns specified by
the <columns> parameter of the corresponding 'open_index' request. the <indexname> parameter of the corresponding 'open_index' request.
- <v1> ... <vn> specify the index column values to fetch. - <v1> ... <vn> specify the index column values to fetch.
- LIM is optional. <limit> and <offset> are numbers. When omitted, it works - LIM is optional. <limit> and <offset> are numbers. When omitted, it works
as if 1 and 0 are specified. These parameter works like LIMIT of SQL. as if 1 and 0 are specified. These parameter works like LIMIT of SQL.
These values don't include the number of records skipped by a filter. These values don't include the number of records skipped by a filter.
- IN is optional. It works like WHERE ... IN syntax of SQL. <icol> must be - IN is optional. It works like WHERE ... IN syntax of SQL. <icol> must be
smaller than or equal to the number of index columns specified by the smaller than the number of index columns specified by the <indexname>
<columns> parameter of the corresponding 'open_index' request. If IN is parameter of the corresponding 'open_index' request. If IN is specified in
specified in a find request, the <icol>-th parameter value of <v1> ... a find request, the <icol>-th parameter value of <v1> ... <vn> is ignored.
<vn> is ignored.
smaller than or equal to the number of index columns specified by the
- FILTERs are optional. A FILTER specifies a filter. <ftyp> is either 'F' - FILTERs are optional. A FILTER specifies a filter. <ftyp> is either 'F'
(filter) or 'W' (while). <fop> specifies the comparison operation to use. (filter) or 'W' (while). <fop> specifies the comparison operation to use.
<fcol> must be smaller than or equal to the number of columns specified by <fcol> must be smaller than the number of columns specified by the
the <fcolumns> parameter of the corresponding 'open_index' request. <fcolumns> parameter of the corresponding 'open_index' request. Multiple
Multiple filters can be specified, and work as the logical AND of them. filters can be specified, and work as the logical AND of them. The
The difference of 'F' and 'W' is that, when a record does not meet the difference of 'F' and 'W' is that, when a record does not meet the
specified condition, 'F' simply skips the record, and 'W' stops the loop. specified condition, 'F' simply skips the record, and 'W' stops the loop.
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
...@@ -112,8 +110,8 @@ MOD is a sequence of the following parameters. ...@@ -112,8 +110,8 @@ MOD is a sequence of the following parameters.
<mk> must be smaller than or equal to the length of <columns> specified by <mk> must be smaller than or equal to the length of <columns> specified by
the corresponding 'open_index' request. If <mop> is 'D', these parameters the corresponding 'open_index' request. If <mop> is 'D', these parameters
are ignored. If <mop> is '+' or '-', values must be numeric. If <mop> is are ignored. If <mop> is '+' or '-', values must be numeric. If <mop> is
'-' and it attempts to change column values from negative to positive or '-' and it attempts to change a column value from negative to positive or
positive to negative, it is not modified. positive to negative, the column value is not modified.
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
Inserting data Inserting data
...@@ -187,6 +185,8 @@ syntax. ...@@ -187,6 +185,8 @@ syntax.
0 1 <nummod> 0 1 <nummod>
- <nummod> is the number of modified rows. - <nummod> is the number of modified rows.
- As an exception, if the '?' suffix is specified in <mop>, a response has
the syntax of a response for 'find' instead.
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
Response for 'insert' Response for 'insert'
...@@ -196,3 +196,10 @@ syntax. ...@@ -196,3 +196,10 @@ syntax.
0 1 0 1
----------------------------------------------------------------------------
Response for 'auth'
If 'auth' is succeeded, HanderSocket returns a line of the following syntax.
0 1
...@@ -8,7 +8,8 @@ HandlerSocketプラグインのビルド方法(RPMを使わない方法) ...@@ -8,7 +8,8 @@ HandlerSocketプラグインのビルド方法(RPMを使わない方法)
$ ./configure --with-mysql-source=/work/mysql-5.1.50 --with-mysql-bindir=/work/mysql-5.1.50-linux-x86_64-glibc23/bin --with-mysql-plugindir=/work/mysql-5.1.50-linux-x86_64-glibc23/lib/plugin $ ./configure --with-mysql-source=/work/mysql-5.1.50 --with-mysql-bindir=/work/mysql-5.1.50-linux-x86_64-glibc23/bin --with-mysql-plugindir=/work/mysql-5.1.50-linux-x86_64-glibc23/lib/plugin
ここで--with-mysql-sourceにはMySQLのソースコードのトップディレク ここで--with-mysql-sourceにはMySQLのソースコードのトップディレク
トリを指定します。--with-mysql-bindirにはインストール済みのMySQL トリを指定します(そこにVERSIONファイルかconfigure.inファイルがなく
てはなりません)。--with-mysql-bindirにはインストール済みのMySQL
のmysql_configコマンドが有るディレクトリを指定します。 のmysql_configコマンドが有るディレクトリを指定します。
その後以下のようにビルド・インストールします。 その後以下のようにビルド・インストールします。
......
...@@ -86,7 +86,6 @@ execute_singleメソッドは列の挿入にも使用できます。 ...@@ -86,7 +86,6 @@ execute_singleメソッドは列の挿入にも使用できます。
my $res = $hs->execute_single(3, '+', [ 'foo', 'bar', 'baz' ]); my $res = $hs->execute_single(3, '+', [ 'foo', 'bar', 'baz' ]);
die $hs->get_error() if $res->[0] != 0; die $hs->get_error() if $res->[0] != 0;
my $num_inserted_rows = $res->[1];
第3引数は、対応するopen_index呼び出しの第5引数の列リストと同じだ 第3引数は、対応するopen_index呼び出しの第5引数の列リストと同じだ
けの長さの配列への参照でなければなりません。open_index呼び出しの けの長さの配列への参照でなければなりません。open_index呼び出しの
...@@ -109,6 +108,15 @@ execute_multiメソッドを使えば、複数のリクエストを一つの呼 ...@@ -109,6 +108,15 @@ execute_multiメソッドを使えば、複数のリクエストを一つの呼
# ... # ...
} }
-----------------------------------------------------------------
もしhandlersocketが接続を認証するように設定されている
(handlersocket_plain_secret又はhandlersocket_plain_secret_wrがセッ
トされている)ならば、クライアントは他のメソッド呼び出しの前にauth
メソッドを呼び出す必要があります。
my $res = $hs->auth('password');
die $hs->get_error() if $res->[0] != 0;
----------------------------------------------------------------- -----------------------------------------------------------------
エラーが起こると返値の配列参照の最初の要素が0以外になります。負の エラーが起こると返値の配列参照の最初の要素が0以外になります。負の
数の場合はI/Oエラーが起こったことを示し、その場合はその 数の場合はI/Oエラーが起こったことを示し、その場合はその
......
----------------------------------------------------------------- ----------------------------------------------------------------------------
handlersocketの通信プロトコル handlersocketの通信プロトコル
----------------------------------------------------------------- ----------------------------------------------------------------------------
構文 基本的な構文
コマンド行は改行(LF)で終わる。 HandlerSocketのプロトコルは行ベース。各行は改行文字(0x0a)で終わる。
コマンド行は複数のトークンからなり、トークン間はTABで区切られる。 各行は複数のトークンからなり、トークン間はTAB文字(0x09)で区切られる。
・トークンはNULLトークンか、文字列トークンのいずれか。 ・トークンはNULLトークンか、文字列トークンのいずれか。
・NULLトークンは単一のNUL文字であらわされる。 ・NULLトークンは単一のNUL文字(0x00)であらわされる。
・文字列トークンは、0バイト以上の文字列であらわされる。ただし0x10 ・文字列トークンは、0バイト以上の文字列であらわされる。ただし0x10未満の文字
未満の文字については0x01を前置し、0x40を加えたコードであらわさ については0x01を前置し、0x40を加えたコードであらわされる。それ以外の文字は
れる。それ以外の文字はその文字自身のコードであらわされる。 その文字自身のコードであらわされる。
----------------------------------------------------------------- ----------------------------------------------------------------------------
リクエストとレスポンス リクエストとレスポンス
・接続が確立した直後の状態では、まずクライアントがコマンド行を送 ・HandlerSocketのプロトコルは単純なリクエスト・レスポンスプロトコルになって
る。(リクエスト) いる。接続が確立した後は、まずクライアントがリクエストを送る。
・サーバはクライアントが送ったリクエストと丁度同じ数のコマンド行 ・サーバは、クライアントが送ったリクエストと丁度同じ数の行(レスポンス)を返
を返す。(レスポンス) す。
・リクエストはパイプライン化してよい。つまりクライアントは前に ・リクエストはパイプライン化してよい。つまりクライアントは前に送ったリクエス
送ったリクエストに対する返事を待たずに次のリクエストを送っても トに対する返事(レスポンス)を待たずに次のリクエストを送ってもよい。
よい。
----------------------------------------------------------------------------
----------------------------------------------------------------- インデックスを開く
リクエスト
open_index命令は次のような構文を持つ。
・open_index命令は次のような構文を持つ。
'P' indexid dbname tablename indexname fieldlist P <indexid> <dbname> <tablename> <indexname> <columns> [<fcolumns>]
indexidは開いている索引に付けられる番号で、同一接続上で後に実行
する命令の、対象索引を指定するために使われる。dbname、tablename、 - <indexid>は数字で、同一接続上で後に実行する命令の、対象索引を指定するため
indexnameはそれぞれ開きたいDB、テーブル、索引の名前。索引の名前 に使われる。
として"PRIMARY"を指定するとプライマリキーが開かれる。fieldlist - <dbname>, <tablename>, <indexname>は文字列で、それぞれDB名、テーブル名、
はカンマ区切りの列名のリスト。 索引の名前を指定する。<indexname>として「PRIMARY」を指定するとプライマリ
・find命令は次のような構文を持つ。 キーが開かれる。
indexid op nflds v1 ... vn limit offset - <columns>はカンマ区切りの列名のリスト。
indexidは実行対象の索引を指定する。opは索引検索の演算子(後述)。 - <fcolumns>はカンマ区切りの列名のリスト。これは省略することができる。
v1からvnは可変長で、その個数はnflds。nfldsはindexidで指定された
open_index命令のindexnameの索引のfieldlistのフィールド数に等し このopen_index命令が実行されると、HandlerSocketプラグインは指定されたDB、
いか小さくなくてはならない。m2からmkは可変長で、その個数は テーブル、索引を開く。開かれた索引は接続が閉じられるまで開かれたままになる。
indexidで指定されたopen_index命令が発行された際のfieldlistに一 開かれた索引は<indexid>の数字で識別される。もし既に<indexid>に指定された番号
致しなければならない。コマンド行のlimit以降は省略できる。limit の索引が既に開かれている場合は古いほうが閉じられる。この<indexid>はなるべく
とoffsetは、検索条件に合致する列のうちレスポンスに返す列数の上 小さな数字を使ったほうが効率が良い。
限と、スキップする列数。limitとoffsetを省略した場合はそれぞれ1
と0が指定されたときと同じ動作をする。find命令はレスポンスとして、 ----------------------------------------------------------------------------
条件に合致した列のリストを返す。opとして指定できる演算子は次の データ取得
とおり。
'=' - v1 ... vnと一致するものを取得 find命令は次のような構文を持つ。
'>' - v1 ... vnより大きいものを昇順に取得
'>=' - v1 ... vnに一致するか大きいものを昇順に取得 <indexid> <op> <vlen> <v1> ... <vn> [LIM] [IN] [FILTER ...]
'<' - v1 ... vnより小さいものを降順に取得
'<=' - v1 ... vnに一致するか等しいものを降順に取得 LIMは次のようなパラメータの並び
nfldsが1より大きい(v1 ... vnが2個以上)ときは辞書式順序で比較さ
れる。 <limit> <offset>
・find_modify命令は次のような構文を持つ。
indexid op nflds v1 ... vn limit offset modop m1 ... mk INは次のようなパラメータの並び
modopより前の部分はfind命令と同等で、これによって操作対象の行を
指定する。その操作対象の行に対しmodopで指定された変更処理を実行 @ <icol> <ivlen> <iv1> ... <ivn>
する。m1 ... mkは可変長で、省略できる。modopは次いずれか。
'U' - indexidで指定されたopen_index命令のfieldlist列 FILTERは次のようなパラメータの並び
の内容を、m1 ... mkの値で更新する。
'D' - 対象の行を削除する。m1 ... mkの値は無視される。 <ftyp> <fop> <fcol> <fval>
・insert命令はのような構文を持つ。
indexid '+' nflds v1 ... vn - <indexid>は数字で、これは同じ接続上で過去に実行したopen_index命令に指定さ
indexidで指定されたテーブルに、列を挿入する。v1 ... vnは可変長 れた数字でなければならない。
で、その個数はnflds。nfldsはindexidで指定されたopen_index命令の - <op>は比較演算子で、現在のバージョンでは '=', '>', '>=', '<', '<=' をサ
indexnameの索引のfieldlistのフィールド数に等しいか小さくなくて ポートしている。
はならない。 - <vlen>は後に続くパラメータ<v1> ... <vn>の長さ。この値は対応するopen_index
命令の<indexname>パラメータで指定された索引のキー列の数と同じか小さいもの
----------------------------------------------------------------- でなければならない。
レスポンス - <v1> ... <vn>は取得するべきキーの値を指定するパラメータ。
- LIMは省略できる。<limit>と<offset>は数字で、これはSQLのLIMITと同じように
・open_index命令が成功したとき、レスポンスは次の構文を持つ。 はたらく。省略した場合は1と0を指定した場合と同じ動作をする。FILTERによっ
'0' '1' て読み飛ばされたレコードは<limit>と<offset>にカウントされない。
・find命令が成功したとき、レスポンスは次の構文を持つ。 - INは省略できる。指定されると、これはSQLの WHERE ... IN のように動作する。
'0' nflds v1 ... vn <icol>は対応するopen_index命令の<indexname>パラメータで指定された索引の
nfldsは結果セットの列の数をあらわす。v1 ... vnは可変長で、その キー列の数より小さいものでなければならない。INが指定されたときは、find命
長さはnfldsの整数倍。v1 ... vnは空のこともあり、それは条件に合 令の<v1> ... <vn>のうち<icol>番目の値は無視される。
致するレコードが存在しなかったことをあらわす。結果セットが複数 - FILTERは省略できる。これは行取得の際のフィルタを指定する。<ftyp>は
行になったときはv1 ... vnの長さがnfldsの2倍以上となり、最初の 'F'(filter)か'W'(while)のいずれかでなければならない。<fop>は比較演算子。
行から順にv1 ... vnにセットされる。 <fcol>は数字で、これは対応するopen_index命令の<fcolumns>で指定された列の
・modify命令が成功したとき、レスポンスは次の構文を持つ。 数より小さいものでなければならない。複数のフィルタを指定することもでき、
'0' '1' nummod その場合は各フィルタのANDと解釈される。'F'と'W'の違いは、条件にあてはま
nummodは変更が施された行数。nummodが0のときは変更された行が無 らない行があったときに'F'は単にそれをスキップするが、'W'はその時点でルー
かったことをあらわす。 プを抜けるという点。
・insert命令が成功したとき、レスポンスは次の構文を持つ。
'0' '1' ----------------------------------------------------------------------------
・命令が失敗したとき、レスポンスは命令に関わらず次の構文を持つ。 更新と削除
err '1' message
errは0以外の数値で、エラーコードをあらわす。messageは人間可読な find_modify命令は次のような構文を持つ。
エラーメッセージ。ただしmessageが無いこともある。
<indexid> <op> <vlen> <v1> ... <vn> [LIM] [IN] [FILTER ...] MOD
MODは次のようなパラメータの並び
<mop> <m1> ... <mk>
- <mop>は'U', '+', '-', 'D', 'U?', '+?', '-?', 'D?'のいずれか。'?'が付いた
ものは付いていないものとほぼ同じ動作をするが、付いていないものがレスポン
スとして更新された行の数を返すのに対し、付いているものは更新される前の行
の内容を返す点のみが異なる。'U'は更新、'D'は削除、'+'はインクリメント、
'-'はデクリメントを実行する。
- <m1> ... <mk>はセットされる各列の値。<m1> ... <mk>の長さは対応する
open_index命令の<columns>の長さと等しいか小さくなければならない。<mop>が
'D'のときはこれらのパラメータは無視される。<mop>が'+'か'-'のときは、これら
の値は数値でなければならない。<mop>が'-'で、それが負数から正数、または正数
から負数へ列の値を変更するようなものであった場合は、値は変更されない。
----------------------------------------------------------------------------
行の挿入
insert命令は次のような構文を持つ。
<indexid> + <vlen> <v1> ... <vn>
- <vlen>は後に続くパラメータ<v1> ... <vn>の長さ。これは対応するopen_indexの
<columns>の長さに等しいか小さくなければならない。
- <v1> ... <vn>はセットされる各列の値。指定されないかった列についてはその列
のデフォルト値がセットされる。
----------------------------------------------------------------------------
認証
auth命令は次のような構文を持つ。
A <atyp> <akey>
- <atyp>は現在のバージョンでは'1'のみが有効。
- 指定された<akey>が、サーバの設定の'handlersocket_plain_secret'や
'handlersocket_plain_secret_wr'に指定された文字列と一致した場合にのみ認証
は成功する。
- HandlerSocketの認証が有効になっているときは、この'auth'が成功しない限りそ
れ以外の命令は全て失敗する。
----------------------------------------------------------------------------
open_indexに対するレスポンス
open_index命令が成功したとき、レスポンスは次の構文を持つ。
0 1
----------------------------------------------------------------------------
findに対するレスポンス
find命令が成功したとき、レスポンスは次の構文を持つ。
0 <numcolumns> <r1> ... <rn>
- <numcolumns>はfind命令の対応するopen_index命令に指定した<columns>の長さに
一致する。
- <r1> ... <rn>は結果セット。もしN行がfind命令で見つかったなら、<r1> ...
<rn>の長さは ( <numcolumns> * N )になる。
----------------------------------------------------------------------------
find_modifyに対するレスポンス
find_modify命令が成功したとき、レスポンスは次の構文を持つ。
0 1 <nummod>
- <nummod>は変更された行の数。
- 例外として、<mop>が'?'の付いたものであった場合には、find命令に対するレスポ
ンスと同じ構文のレスポンスを返す。
----------------------------------------------------------------------------
insertに対するレスポンス
insert命令が成功したとき、レスポンスは次の構文を持つ。
0 1
----------------------------------------------------------------------------
authに対するレスポンス
auth命令が成功したとき、レスポンスは次の構文を持つ。
0 1
...@@ -658,7 +658,7 @@ dbcontext::cmd_insert_internal(dbcallback_i& cb, const prep_stmt& pst, ...@@ -658,7 +658,7 @@ dbcontext::cmd_insert_internal(dbcallback_i& cb, const prep_stmt& pst,
empty_record(table); empty_record(table);
memset(buf, 0, table->s->null_bytes); /* clear null flags */ memset(buf, 0, table->s->null_bytes); /* clear null flags */
const prep_stmt::fields_type& rf = pst.get_ret_fields(); const prep_stmt::fields_type& rf = pst.get_ret_fields();
const size_t n = rf.size(); const size_t n = std::min(rf.size(), fvalslen);
for (size_t i = 0; i < n; ++i) { for (size_t i = 0; i < n; ++i) {
uint32_t fn = rf[i]; uint32_t fn = rf[i];
Field *const fld = table->field[fn]; Field *const fld = table->field[fn];
......
...@@ -151,7 +151,7 @@ sv_get_string_ref(SV *sv) ...@@ -151,7 +151,7 @@ sv_get_string_ref(SV *sv)
static IV static IV
sv_get_iv(SV *sv) sv_get_iv(SV *sv)
{ {
if (sv == 0 || !SvIOK(sv)) { if (sv == 0 || ( !SvIOK(sv) && !SvPOK(sv) ) ) {
return 0; return 0;
} }
return SvIV(sv); return SvIV(sv);
......
#!/bin/bash #!/bin/bash
TESTS="01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23"; TESTS="01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24";
source ../common/compat.sh source ../common/compat.sh
......
...@@ -27,7 +27,7 @@ srand(999); ...@@ -27,7 +27,7 @@ srand(999);
my %valmap = (); my %valmap = ();
my $sth = $dbh->prepare("insert into $table values (?,?,?)"); my $sth = $dbh->prepare("insert ignore into $table values (?,?,?)");
for (my $i = 0; $i < $tablesize; ++$i) { for (my $i = 0; $i < $tablesize; ++$i) {
my $k = $i; my $k = $i;
my ($s1, $s2) = ("", ""); my ($s1, $s2) = ("", "");
......
...@@ -60,7 +60,7 @@ sub test_one { ...@@ -60,7 +60,7 @@ sub test_one {
$dbh->do( $dbh->do(
"create table $table (" . "create table $table (" .
"k $typ, " . "k $typ, " .
"v1 varchar(2047), " . "v1 varchar(1000), " .
"v2 $typ, " . "v2 $typ, " .
"primary key(k$keylen_str), " . "primary key(k$keylen_str), " .
"index i1(v1), index i2(v2$keylen_str, v1(300))) " . "index i1(v1), index i2(v2$keylen_str, v1(300))) " .
......
...@@ -113,7 +113,7 @@ sub test_one { ...@@ -113,7 +113,7 @@ sub test_one {
"(k1 int not null, k2 int not null, " . "(k1 int not null, k2 int not null, " .
"v1 int not null, v2 $typ default null, " . "v1 int not null, v2 $typ default null, " .
"primary key (k1, k2) ) engine = innodb"); "primary key (k1, k2) ) engine = innodb");
my $sth = $dbh->prepare("insert into $table values (?,?,?,?)"); my $sth = $dbh->prepare("insert ignore into $table values (?,?,?,?)");
for (my $i = 0; $i < $tablesize; ++$i) { for (my $i = 0; $i < $tablesize; ++$i) {
my $j = 0; my $j = 0;
for my $v (@$values) { for my $v (@$values) {
......
#!/usr/bin/perl
# vim:sw=2:ai
# test for issue #78
BEGIN {
push @INC, "../common/";
};
use strict;
use warnings;
use hstest;
my $dbh = hstest::init_testdb();
my $table = 'hstesttbl';
my $tablesize = 100;
$dbh->do(
"create table $table (" .
"id bigint(20) not null auto_increment, " .
"t1 timestamp not null default current_timestamp, " .
"primary key (id)" .
") engine = innodb");
srand(999);
my %valmap = ();
my $hs = hstest::get_hs_connection(undef, 9999);
my $dbname = $hstest::conf{dbname};
$hs->open_index(0, $dbname, $table, 'PRIMARY', 'id,t1');
my $res = $hs->execute_single(0, '+', [ 321 ], 0, 0);
die $hs->get_error() if $res->[0] != 0;
print "HS\n";
print join(' ', @$res) . "\n";
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment