PayasR / paralite

0 stars 0 forks source link

UDXのselect文の出力が中途半端 #30

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
● ステータス:修正済み

● 現象
 ・UDXを使ったselect文(下記 
Ex.1)を実行すると、出力されるはずのデータが途中までしか
出力されない。

Ex.1)
$ paralite test.db "select document_id, F(text) from document with F='perl ss' 
OUTPUT_COL_DELIMITER '==' OUTPUT_RECORD_DELIMITER EMPTY_LINE"

● 再現手順
Ex.2) まず、環境を整える
$ paralite test.db < a.sql

$ cat a.sql
↓
create table document(document_id, text);
.import doc.dat document;

$ cat doc.dat
↓
32819|It is sunny today. I have a good mood.
82718|I am studying in the lab. I want to go outside and play pingpong.

$ cat ss
↓
#!/usr/bin/perl
while (my $l = <STDIN>) {
  chomp($l);
  my @s = split(/\.\s*/, $l);
  my $i = 1;
  foreach my $item (@s) {
    print $i, '==', $item, ".\n";
    ++$i;
  }
  print "\n";
}

Ex.3)
$ paralite test.db "select document_id, F(text) from document with F='perl ss' 
OUTPUT_COL_DELIMITER '==' OUTPUT_RECORD_DELIMITER EMPTY_LINE"
↓
32819|1|It is sunny today.
32819|2|I have a good mood.
82718|1|I am studying in the lab.
82718|2|I want to go.     # I want to go outside and play 
pingpong.と出力されるべき

What is the expected output? What do you see instead?
● 期待される出力
Ex.4) あるべき出力結果
$ paralite test.db "select document_id, F(text) from document with F='perl ss' 
OUTPUT_COL_DELIMITER '==' OUTPUT_RECORD_DELIMITER EMPTY_LINE"
↓
32819|1|It is sunny today.
32819|2|I have a good mood.
82718|1|I am studying in the lab.
82718|2|I want to go outside and play pingpong.

Please use labels and text to provide additional information.
● 原因
 ・sql.pyファイルの458行目「w_id, jobid = 
m[1:3]」でjobidを、461行目「bk = 
string.atoi(m[4])」でbkを取得する。
 jobidは出力する文字列のID(別名:データA-1)、bkは出力す�
��文字列のサイズ(別名:データA-2)。
 ・sql.pyファイルの595行目「self.reader = 
self.get_next_reader()」でself.readerを取得する。
 self.readerは、実際に出力する文字列がセットされているStr
ingIO オブジェクト(別名:データB)。
 
 ・566行目「def get_data_by_blocksize(self, jobid, 
bksize):」で、上記の3つのデータを使って、出力する文字列��
�形成する。 
 self.reader(データB)の文字列と、jobid(データA-1)とbksize
(データA-2)が示している文字列が異なる場合がある。
 
 ・self.reader(データB)を取得するときに、文字列のID(デ
ータA-1)と合致した文字列を取得するように変更した。
 (sql.py ファイルの def get_alt_next_reader(self, jobid):)

● 修正箇所
 ◆ bin/sql.py / def handle_read(self, event):
< before >
                for dataid in self.result:
                    if dataid not in data_status:
                        data_status[dataid] = []
                    for i in range(len(self.result[dataid])):
                        data_status[dataid].append((i, 1))
                self.data_status = data_status
                self.reader = self.get_next_reader()

< after >
                for dataid in self.result:
                    if dataid not in data_status:
                        data_status[dataid] = []
                    for i in range(len(self.result[dataid])):
                        data_status[dataid].append((i, 1))
                self.data_status = data_status
                # takizawa:Issue30: 下記1行をコメントアウト。下記の関数ではなく、get_alt_next_readerを使う。
                # self.reader = self.get_next_reader()

 ◆ bin/sql.py / def get_data_by_blocksize(self, jobid, bksize):
< before >
    def get_data_by_blocksize(self, jobid, bksize):
        if self.reader is None:
            return None

< after >
    def get_data_by_blocksize(self, jobid, bksize):
        # takizawa:Issue30: 下記1行を追加。下記の関数を実行することで、
        # 引数(jobid, bksize)と'self.reader'の組合せを確実にマッチさせる。
        self.reader = self.get_alt_next_reader(jobid)
        if self.reader is None:
            return None

 ◆ bin/sql.py / def get_data_by_blocksize(self, jobid, bksize):
< before >
            if self.reader is not None:
                self.reader.close()
            self.reader = None
            self.reader = self.get_next_reader()

< after >
            if self.reader is not None:
                self.reader.close()
            self.reader = None
            # takizawa:Issue30: 下記1行をコメントアウト。下記の関数ではなく、get_alt_next_readerを使うため。
            # self.reader = self.get_next_reader()

 ◆ bin/sql.py / def get_alt_next_reader(self, jobid):
< after >
    # takizawa:Issue30: 下記の関数を追加。
    '''
    "def get_next_reader(self):"を修正したもの。
    引数 "jobid"を持つことで、"jobid"に対応した"reader"を取得できる。
    '''
    def get_alt_next_reader(self, jobid):
        ''' 
        altered "def get_next_reader"
        You can indicate the specific "Reader" by "jobid".
        '''
        reader = None
        jobid = int(jobid)
        if jobid in self.data_status:
            for i in range(len(self.data_status[jobid])):
                sta = self.data_status[jobid][i]
                if sta[1] == 1:
                    data = self.result[jobid][i]
                    if isinstance(data, str):
                        # this is a file
                        reader = open(data, "rb")
                    else:
                        data.seek(0)
                        reader = data
                    sta = (i, 0)
                    self.data_status[jobid][i] = sta
                    return reader
        return None

● 
修正後の実際の出力('32819'の行と'82718'の行の順番が入れ替
わっている)
Ex.5)
$ paralite test.db "select document_id, F(text) from document with F='perl ss' 
OUTPUT_COL_DELIMITER '==' OUTPUT_RECORD_DELIMITER EMPTY_LINE"
↓
82718|1|I am studying in the lab.
82718|2|I want to go outside and play pingpong.
32819|1|It is sunny today.
32819|2|I have a good mood.

Original issue reported on code.google.com by wdb.taki...@gmail.com on 24 Dec 2014 at 2:43