PayasR / paralite

0 stars 0 forks source link

.analyze処理のコメントアウト #26

Open GoogleCodeExporter opened 9 years ago

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

● 修正の流れ
 ・マニュアルに載っている「クエリ解析」のクエリの書��
�方が、下記(Ex.1)の「.analyzeバージョン」と(Ex.2)の「--p
arse-planバージョン」があり、出力結果も同じだった。
 ・コードを見ると途中から同じ処理になるので、どちら��
�で統一することにした。
 ・「--parse-planバージョン」の方が余計な処理が少ないの��
�「.analyze」の処理を全てコメントアウトした。
 
 ・(Ex.2)クエリ内の「F=\"cmd\"」を「F='cmd'」でも使えるよ
うに、newparser.pyファイルのudxとcommand_line定義を修正した。
 
Ex.1) .analyzeバージョン
$ paralite a.db ".analyze 'select F(a) from x, y where x.a = y.b' with 
F=\"cmd\"" 

Ex.2) --parse-planバージョン
$ paralite a.db "select F(a) from x, y where x.a = y.b with F=\"cmd\"" 
--parse-plan

● 再現手順
Ex.3) まず、テーブルを2つ作成する
$ paralite a.db "create table x(a, b)"
$ paralite a.db "create table y(a, b)"

Ex.4) .analyzeバージョン
$ paralite a.db ".analyze 'select F(a) from x, y where x.a = y.b' with 
F=\"cmd\"" 
↓
 (- udx 0 expression=None input=['a'] output=['F(a)'] key=['a'] split_key=[] tables=[None] dest= data to one client udxes=['cmd'])

- (- join 1 expression=['x.a = y.b '] input=['x.a', 'y.b'] output=[] 
key=['x.a', 'y.b'] split_key=[] tables=['x', 'y'] dest=distribute data to 
clients is_sql=0 is_sub_plan=False)

-- (- sql 2 expression=select x.a from x  input=[] output=['x.a'] key=[] 
split_key=['x.a'] tables=['x'] dest=piplining data is_sql=None)

-- (- sql 3 expression=select y.b from y  input=[] output=['y.b'] key=[] 
split_key=['y.b'] tables=['y'] dest=piplining data is_sql=None)

Ex.5) --parse-planバージョン (F=\"cmd\")
$ paralite a.db "select F(a) from x, y where x.a = y.b with F=\"cmd\"" 
--parse-plan
↓
 (- udx 0 expression=None input=['a'] output=['F(a)'] key=['a'] split_key=[] tables=[None] dest= data to one client udxes=['cmd'])

- (- join 1 expression=['x.a = y.b '] input=['x.a', 'y.b'] output=[] 
key=['x.a', 'y.b'] split_key=[] tables=['x', 'y'] dest=distribute data to 
clients is_sql=0 is_sub_plan=False)

-- (- sql 2 expression=select x.a from x  input=[] output=['x.a'] key=[] 
split_key=['x.a'] tables=['x'] dest=piplining data is_sql=None)

-- (- sql 3 expression=select y.b from y  input=[] output=['y.b'] key=[] 
split_key=['y.b'] tables=['y'] dest=piplining data is_sql=None)

What is the expected output? What do you see instead?

Ex.6) --parse-planバージョン (F='cmd')
$ paralite a.db "select F(a) from x, y where x.a = y.b with F='cmd'" 
--parse-plan
↓
 (- udx 0 expression=None input=['a'] output=['F(a)'] key=['a'] split_key=[] tables=[None] dest= data to one client udxes=['cmd'])

- (- join 1 expression=['x.a = y.b '] input=['x.a', 'y.b'] output=[] 
key=['x.a', 'y.b'] split_key=[] tables=['x', 'y'] dest=distribute data to 
clients is_sql=0 is_sub_plan=False)

-- (- sql 2 expression=select x.a from x  input=[] output=['x.a'] key=[] 
split_key=['x.a'] tables=['x'] dest=piplining data is_sql=None)

-- (- sql 3 expression=select y.b from y  input=[] output=['y.b'] key=[] 
split_key=['y.b'] tables=['y'] dest=piplining data is_sql=None)

Please use labels and text to provide additional information.

● 修正箇所
 ◆ bin/paralite
< before >
        elif len(argv) == 4 and argv[3].startswith("--parse-"):
            # query for syntax tree or query plan
            # Usage: paralite db "select * from T" --parse-syntax 
            #        paralite db "select * from T" --parse-plan
            paraLiteParser.main(argv)
            sys.exit(0)

< after >
        # takizawa: 下記3行を追加。「.analyze」が「--parse-plan」と同じ処理のため。
        elif len(argv) == 3 and argv[2].lower().startswith(".analyze") or argv[2].lower().startswith("analyze"):
            print "Please use '--parse-plan' for showing the logical plan of a SQL query."
            sys.exit(0)

        elif len(argv) == 4 and argv[3].startswith("--parse-"):
            # query for syntax tree or query plan
            # Usage: paralite db "select * from T" --parse-syntax 
            #        paralite db "select * from T" --parse-plan
            paraLiteParser.main(argv)
            sys.exit(0)

 ◆ bin/m_paraLite.py / def execute_special_task(self, t):
< before >
        elif t.type == t.TABLE:
            ret = InfoCenter().get_table_info(t.database)
        elif t.type == t.ANALYZE:
            temp_task = Task()
            temp_task.database = metadata_db
            sql = t.cmd[t.cmd.find("\"")+1:len(t.cmd)-1]
            temp_task.query = sql
            if self.parse_task(temp_task):
                ret = temp_task.plan.get()

< after >
        elif t.type == t.TABLE:
            ret = InfoCenter().get_table_info(t.database)
            # takizawa:Case 02: 下記7行をコメントアウト。'.analyze'が'--parse-plan'と同じ処理のため。
            '''
        elif t.type == t.ANALYZE:
            temp_task = Task()
            temp_task.database = metadata_db
            sql = t.cmd[t.cmd.find("\"")+1:len(t.cmd)-1]
            temp_task.query = sql
            if self.parse_task(temp_task):
                ret = temp_task.plan.get()
            '''

 ◆ bin/m_paraLite.py / class SpecialTask:
< before >
    SHOW = ".show"
    ANALYZE = ".analyze"

< after >
    SHOW = ".show"
    # takizawa:Case 02: 下記1行をコメントアウト。'.analyze'が'--parse-plan'と同じ処理のため。
    # ANALYZE = ".analyze"

 ◆ bin/m_paraLite.py / def parse_query_args(self, cmd):
< before >
                elif cq.startswith(".show"):
                    spec_task.type = spec_task.SHOW
                elif cq.startswith(".analyze"):
                    spec_task.type = spec_task.ANALYZE

< after >
                elif cq.startswith(".show"):
                    spec_task.type = spec_task.SHOW
                # takizawa:Case 02: 下記2行をコメントアウト。'.analyze'が'--parse-plan'と同じ処理のため。
                    '''
                elif cq.startswith(".analyze"):
                    spec_task.type = spec_task.ANALYZE
                    '''

 ◆ bin/paraLite.py / def do_help_cmd(self, args):
< before >
    def do_help_cmd(self, args):
        u = """Usage: paralite /path/to/db STATEMENT [--hub]
--hub:
       \tfile://path/to/file
       \tdb://path/to/file 
       \thost://hostname:port

Examples:

   paralite /path/to/db \"QUERY\"\tissue a query --hub file:/home/user/hub_info
   paralite /path/to/db < query.sql
   Paralite /path/to/db \"SPECIAL COMMAND\" 
       \t.import FILE/DIR TABLE [record_tag][-hash key][-replicate] [-column_separator col_sep -row_separator row_sep]\tImport data from FILE into TABLE
       \t.output FILE\tSend output to FILENAME
       \t.output stdout\tSend output to the screen
       \t.indices [TABLE]\tShow names of all indices. If TABLE specified, only show indices for tables
       \t.row_separator STRING\tChange separator used by output mode and .import
       \t.col_separator STRING\tChange separator used by output mode and .import
       \t.show\tShow the current values for various settings
       \t.analyze \"QUERY\"
"""

< after >
    def do_help_cmd(self, args):
        # takizawa:Case 02: 下記の文字列を修正。'.analyze'が'--parse-plan'と同じ処理のため、.analyzeを削除。
        '''
        u = """Usage: paralite /path/to/db STATEMENT [--hub]
--hub:
       \tfile://path/to/file
       \tdb://path/to/file 
       \thost://hostname:port

Examples:

   paralite /path/to/db \"QUERY\"\tissue a query --hub file:/home/user/hub_info
   paralite /path/to/db < query.sql
   Paralite /path/to/db \"SPECIAL COMMAND\" 
       \t.import FILE/DIR TABLE [record_tag][-hash key][-replicate] [-column_separator col_sep -row_separator row_sep]\tImport data from FILE into TABLE
       \t.output FILE\tSend output to FILENAME
       \t.output stdout\tSend output to the screen
       \t.indices [TABLE]\tShow names of all indices. If TABLE specified, only show indices for tables
       \t.row_separator STRING\tChange separator used by output mode and .import
       \t.col_separator STRING\tChange separator used by output mode and .import
       \t.show\tShow the current values for various settings
       \t.analyze \"QUERY\"
"""
        '''
        u = """Usage: paralite /path/to/db STATEMENT [--hub]
--hub:
       \tfile://path/to/file
       \tdb://path/to/file 
       \thost://hostname:port

Examples:

   paralite /path/to/db \"QUERY\"\tissue a query --hub file:/home/user/hub_info
   paralite /path/to/db < query.sql
   Paralite /path/to/db \"SPECIAL COMMAND\" 
       \t.import FILE/DIR TABLE [record_tag][-hash key][-replicate] [-column_separator col_sep -row_separator row_sep]\tImport data from FILE into TABLE
       \t.output FILE\tSend output to FILENAME
       \t.output stdout\tSend output to the screen
       \t.indices [TABLE]\tShow names of all indices. If TABLE specified, only show indices for tables
       \t.row_separator STRING\tChange separator used by output mode and .import
       \t.col_separator STRING\tChange separator used by output mode and .import
       \t.show\tShow the current values for various settings
"""
        print u

 ◆ lib/newparser.py / command_line
< before >
command_line = ~keyword + Word("/" + "(" + alphas, alphanums + "{" + "}" + 
"+"+"<"+ "_" +"." + " "+ "/" + "-" + ";" + "'" + "(" + ")" + "&" + "=" + "$" + 
":" + "|")

< after >
# takizawa:Case 02: 
下記1行を修正。UDXでシングルクォートを使えるようにした�
��
# command_line = ~keyword + Word("/" + "(" + alphas, alphanums + "{" + "}" + 
"+"+"<"+ "_" +"." + " "+ "/" + "-" + ";" + "'" + "(" + ")" + "&" + "=" + "$" + 
":" + "|")
command_line = ~keyword + Word("/" + "(" + alphas, alphanums + "{" + "}" + 
"+"+"<"+ "_" +"." + " "+ "/" + "-" + ";" + "(" + ")" + "&" + "=" + "$" + ":" + 
"|")

 ◆ lib/newparser.py / udx
< before >
udx = exe_name("exe_name") + EQUAL + DQUOTE + command_line + DQUOTE + 
Optional(INPUT + (STDIN | (SQUOTE+ file_name + SQUOTE)))("input") + 
Optional(INPUT_ROW_DELIMITER + ((SQUOTE + delimiter + SQUOTE) | EMPTY_LINE | 
NEW_LINE )) + Optional(INPUT_COL_DELIMITER + (NULL | SPACE| (SQUOTE + delimiter 
+ SQUOTE))) + Optional(INPUT_RECORD_DELIMITER + (NEW_LINE|EMPTY_LINE | (SQUOTE 
+ delimiter + SQUOTE)))+ Optional(OUTPUT + (STDOUT | (SQUOTE+file_name + 
SQUOTE))) + Optional(OUTPUT_ROW_DELIMITER + (NEW_LINE | EMPTY_LINE | (SQUOTE 
+delimiter+ SQUOTE))) + Optional(OUTPUT_COL_DELIMITER + (NULL | SPACE | (SQUOTE 
+ delimiter + SQUOTE))) + Optional(OUTPUT_RECORD_DELIMITER + (EMPTY_LINE | 
(SQUOTE + delimiter + SQUOTE))) 

< after >
# takizawa:Case 02: 
下記1行を修正。command_lineでシングルクォートを使えるよう�
��、デリミタが順不同になるように修正。
# udx = exe_name("exe_name") + EQUAL + DQUOTE + command_line + DQUOTE + 
Optional(INPUT + (STDIN | (SQUOTE+ file_name + SQUOTE)))("input") + 
Optional(INPUT_ROW_DELIMITER + ((SQUOTE + delimiter + SQUOTE) | EMPTY_LINE | 
NEW_LINE )) + Optional(INPUT_COL_DELIMITER + (NULL | SPACE| (SQUOTE + delimiter 
+ SQUOTE))) + Optional(INPUT_RECORD_DELIMITER + (NEW_LINE|EMPTY_LINE | (SQUOTE 
+ delimiter + SQUOTE)))+ Optional(OUTPUT + (STDOUT | (SQUOTE+file_name + 
SQUOTE))) + Optional(OUTPUT_ROW_DELIMITER + (NEW_LINE | EMPTY_LINE | (SQUOTE 
+delimiter+ SQUOTE))) + Optional(OUTPUT_COL_DELIMITER + (NULL | SPACE | (SQUOTE 
+ delimiter + SQUOTE))) + Optional(OUTPUT_RECORD_DELIMITER + (EMPTY_LINE | 
(SQUOTE + delimiter + SQUOTE))) 
udx = exe_name("exe_name") + EQUAL + ((DQUOTE + command_line + DQUOTE) | 
(SQUOTE + command_line + SQUOTE)) + ZeroOrMore((INPUT + (STDIN | SQUOTE + 
file_name + SQUOTE)) | (INPUT_ROW_DELIMITER + (SQUOTE + delimiter + SQUOTE | 
EMPTY_LINE | NEW_LINE )) | (INPUT_COL_DELIMITER + (NULL | SPACE | SQUOTE + 
delimiter + SQUOTE)) | (INPUT_RECORD_DELIMITER + (NEW_LINE | EMPTY_LINE | 
SQUOTE + delimiter + SQUOTE)) | (OUTPUT + (STDOUT | SQUOTE + file_name + 
SQUOTE)) | (OUTPUT_ROW_DELIMITER + (NEW_LINE | EMPTY_LINE | SQUOTE + delimiter 
+ SQUOTE)) | (OUTPUT_COL_DELIMITER + (NULL | SPACE | SQUOTE + delimiter + 
SQUOTE)) | (OUTPUT_RECORD_DELIMITER + (EMPTY_LINE | (SQUOTE + delimiter + 
SQUOTE)))

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

GoogleCodeExporter commented 9 years ago
・修正箇所のコメントを修正(takizawa:Case 02 --> takizawa:Issue26)

● 修正箇所
 ◆ bin/paralite
< before >
        elif len(argv) == 4 and argv[3].startswith("--parse-"):
            # query for syntax tree or query plan
            # Usage: paralite db "select * from T" --parse-syntax 
            #        paralite db "select * from T" --parse-plan
            paraLiteParser.main(argv)
            sys.exit(0)

< after >
        # takizawa:Issue26: 下記3行を追加。「.analyze」が「--parse-plan」と同じ処理のため。
        elif len(argv) == 3 and argv[2].lower().startswith(".analyze") or argv[2].lower().startswith("analyze"):
            print "Please use '--parse-plan' for showing the logical plan of a SQL query."
            sys.exit(0)

        elif len(argv) == 4 and argv[3].startswith("--parse-"):
            # query for syntax tree or query plan
            # Usage: paralite db "select * from T" --parse-syntax 
            #        paralite db "select * from T" --parse-plan
            paraLiteParser.main(argv)
            sys.exit(0)

 ◆ bin/m_paraLite.py / def execute_special_task(self, t):
< before >
        elif t.type == t.TABLE:
            ret = InfoCenter().get_table_info(t.database)
        elif t.type == t.ANALYZE:
            temp_task = Task()
            temp_task.database = metadata_db
            sql = t.cmd[t.cmd.find("\"")+1:len(t.cmd)-1]
            temp_task.query = sql
            if self.parse_task(temp_task):
                ret = temp_task.plan.get()

< after >
        elif t.type == t.TABLE:
            ret = InfoCenter().get_table_info(t.database)
            # takizawa:Issue26: 下記7行をコメントアウト。'.analyze'が'--parse-plan'と同じ処理のため。
            '''
        elif t.type == t.ANALYZE:
            temp_task = Task()
            temp_task.database = metadata_db
            sql = t.cmd[t.cmd.find("\"")+1:len(t.cmd)-1]
            temp_task.query = sql
            if self.parse_task(temp_task):
                ret = temp_task.plan.get()
            '''

 ◆ bin/m_paraLite.py / class SpecialTask:
< before >
    SHOW = ".show"
    ANALYZE = ".analyze"

< after >
    SHOW = ".show"
    # takizawa:Issue26: 下記1行をコメントアウト。'.analyze'が'--parse-plan'と同じ処理のため。
    # ANALYZE = ".analyze"

 ◆ bin/m_paraLite.py / def parse_query_args(self, cmd):
< before >
                elif cq.startswith(".show"):
                    spec_task.type = spec_task.SHOW
                elif cq.startswith(".analyze"):
                    spec_task.type = spec_task.ANALYZE

< after >
                elif cq.startswith(".show"):
                    spec_task.type = spec_task.SHOW
                # takizawa:Issue26: 下記2行をコメントアウト。'.analyze'が'--parse-plan'と同じ処理のため。
                    '''
                elif cq.startswith(".analyze"):
                    spec_task.type = spec_task.ANALYZE
                    '''

 ◆ bin/paraLite.py / def do_help_cmd(self, args):
< before >
    def do_help_cmd(self, args):
        u = """Usage: paralite /path/to/db STATEMENT [--hub]
--hub:
       \tfile://path/to/file
       \tdb://path/to/file 
       \thost://hostname:port

Examples:

   paralite /path/to/db \"QUERY\"\tissue a query --hub file:/home/user/hub_info
   paralite /path/to/db < query.sql
   Paralite /path/to/db \"SPECIAL COMMAND\" 
       \t.import FILE/DIR TABLE [record_tag][-hash key][-replicate] [-column_separator col_sep -row_separator row_sep]\tImport data from FILE into TABLE
       \t.output FILE\tSend output to FILENAME
       \t.output stdout\tSend output to the screen
       \t.indices [TABLE]\tShow names of all indices. If TABLE specified, only show indices for tables
       \t.row_separator STRING\tChange separator used by output mode and .import
       \t.col_separator STRING\tChange separator used by output mode and .import
       \t.show\tShow the current values for various settings
       \t.analyze \"QUERY\"
"""

< after >
    def do_help_cmd(self, args):
        # takizawa:Issue26: 下記の文字列を修正。'.analyze'が'--parse-plan'と同じ処理のため、.analyzeを削除。
        '''
        u = """Usage: paralite /path/to/db STATEMENT [--hub]
--hub:
       \tfile://path/to/file
       \tdb://path/to/file 
       \thost://hostname:port

Examples:

   paralite /path/to/db \"QUERY\"\tissue a query --hub file:/home/user/hub_info
   paralite /path/to/db < query.sql
   Paralite /path/to/db \"SPECIAL COMMAND\" 
       \t.import FILE/DIR TABLE [record_tag][-hash key][-replicate] [-column_separator col_sep -row_separator row_sep]\tImport data from FILE into TABLE
       \t.output FILE\tSend output to FILENAME
       \t.output stdout\tSend output to the screen
       \t.indices [TABLE]\tShow names of all indices. If TABLE specified, only show indices for tables
       \t.row_separator STRING\tChange separator used by output mode and .import
       \t.col_separator STRING\tChange separator used by output mode and .import
       \t.show\tShow the current values for various settings
       \t.analyze \"QUERY\"
"""
        '''
        u = """Usage: paralite /path/to/db STATEMENT [--hub]
--hub:
       \tfile://path/to/file
       \tdb://path/to/file 
       \thost://hostname:port

Examples:

   paralite /path/to/db \"QUERY\"\tissue a query --hub file:/home/user/hub_info
   paralite /path/to/db < query.sql
   Paralite /path/to/db \"SPECIAL COMMAND\" 
       \t.import FILE/DIR TABLE [record_tag][-hash key][-replicate] [-column_separator col_sep -row_separator row_sep]\tImport data from FILE into TABLE
       \t.output FILE\tSend output to FILENAME
       \t.output stdout\tSend output to the screen
       \t.indices [TABLE]\tShow names of all indices. If TABLE specified, only show indices for tables
       \t.row_separator STRING\tChange separator used by output mode and .import
       \t.col_separator STRING\tChange separator used by output mode and .import
       \t.show\tShow the current values for various settings
"""
        print u

 ◆ lib/newparser.py / command_line
< before >
command_line = ~keyword + Word("/" + "(" + alphas, alphanums + "{" + "}" + 
"+"+"<"+ "_" +"." + " "+ "/" + "-" + ";" + "'" + "(" + ")" + "&" + "=" + "$" + 
":" + "|")

< after >
# takizawa:Issue26: 
下記1行を修正。UDXでシングルクォートを使えるようにした�
��
# command_line = ~keyword + Word("/" + "(" + alphas, alphanums + "{" + "}" + 
"+"+"<"+ "_" +"." + " "+ "/" + "-" + ";" + "'" + "(" + ")" + "&" + "=" + "$" + 
":" + "|")
command_line = ~keyword + Word("/" + "(" + alphas, alphanums + "{" + "}" + 
"+"+"<"+ "_" +"." + " "+ "/" + "-" + ";" + "(" + ")" + "&" + "=" + "$" + ":" + 
"|")

 ◆ lib/newparser.py / udx
< before >
udx = exe_name("exe_name") + EQUAL + DQUOTE + command_line + DQUOTE + 
Optional(INPUT + (STDIN | (SQUOTE+ file_name + SQUOTE)))("input") + 
Optional(INPUT_ROW_DELIMITER + ((SQUOTE + delimiter + SQUOTE) | EMPTY_LINE | 
NEW_LINE )) + Optional(INPUT_COL_DELIMITER + (NULL | SPACE| (SQUOTE + delimiter 
+ SQUOTE))) + Optional(INPUT_RECORD_DELIMITER + (NEW_LINE|EMPTY_LINE | (SQUOTE 
+ delimiter + SQUOTE)))+ Optional(OUTPUT + (STDOUT | (SQUOTE+file_name + 
SQUOTE))) + Optional(OUTPUT_ROW_DELIMITER + (NEW_LINE | EMPTY_LINE | (SQUOTE 
+delimiter+ SQUOTE))) + Optional(OUTPUT_COL_DELIMITER + (NULL | SPACE | (SQUOTE 
+ delimiter + SQUOTE))) + Optional(OUTPUT_RECORD_DELIMITER + (EMPTY_LINE | 
(SQUOTE + delimiter + SQUOTE))) 

< after >
# takizawa:Issue26: 
下記1行を修正。command_lineでシングルクォートを使えるよう�
��、デリミタが順不同になるように修正。
# udx = exe_name("exe_name") + EQUAL + DQUOTE + command_line + DQUOTE + 
Optional(INPUT + (STDIN | (SQUOTE+ file_name + SQUOTE)))("input") + 
Optional(INPUT_ROW_DELIMITER + ((SQUOTE + delimiter + SQUOTE) | EMPTY_LINE | 
NEW_LINE )) + Optional(INPUT_COL_DELIMITER + (NULL | SPACE| (SQUOTE + delimiter 
+ SQUOTE))) + Optional(INPUT_RECORD_DELIMITER + (NEW_LINE|EMPTY_LINE | (SQUOTE 
+ delimiter + SQUOTE)))+ Optional(OUTPUT + (STDOUT | (SQUOTE+file_name + 
SQUOTE))) + Optional(OUTPUT_ROW_DELIMITER + (NEW_LINE | EMPTY_LINE | (SQUOTE 
+delimiter+ SQUOTE))) + Optional(OUTPUT_COL_DELIMITER + (NULL | SPACE | (SQUOTE 
+ delimiter + SQUOTE))) + Optional(OUTPUT_RECORD_DELIMITER + (EMPTY_LINE | 
(SQUOTE + delimiter + SQUOTE))) 
udx = exe_name("exe_name") + EQUAL + ((DQUOTE + command_line + DQUOTE) | 
(SQUOTE + command_line + SQUOTE)) + ZeroOrMore((INPUT + (STDIN | SQUOTE + 
file_name + SQUOTE)) | (INPUT_ROW_DELIMITER + (SQUOTE + delimiter + SQUOTE | 
EMPTY_LINE | NEW_LINE )) | (INPUT_COL_DELIMITER + (NULL | SPACE | SQUOTE + 
delimiter + SQUOTE)) | (INPUT_RECORD_DELIMITER + (NEW_LINE | EMPTY_LINE | 
SQUOTE + delimiter + SQUOTE)) | (OUTPUT + (STDOUT | SQUOTE + file_name + 
SQUOTE)) | (OUTPUT_ROW_DELIMITER + (NEW_LINE | EMPTY_LINE | SQUOTE + delimiter 
+ SQUOTE)) | (OUTPUT_COL_DELIMITER + (NULL | SPACE | SQUOTE + delimiter + 
SQUOTE)) | (OUTPUT_RECORD_DELIMITER + (EMPTY_LINE | (SQUOTE + delimiter + 
SQUOTE)))

Original comment by wdb.taki...@gmail.com on 24 Dec 2014 at 4:33