Skip to content

Fix #105: Fix parsing of FIELDS and LINES options in Select..Into #107

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Dec 22, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 103 additions & 5 deletions src/Components/IntoKeyword.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,30 @@
class IntoKeyword extends Component
{

/**
* FIELDS/COLUMNS Options for `SELECT...INTO` statements.
*
* @var array
*/
public static $FIELDS_OPTIONS = array(

'TERMINATED BY' => array(1, 'expr'),
'OPTIONALLY' => 2,
'ENCLOSED BY' => array(3, 'expr'),
'ESCAPED BY' => array(4, 'expr'),
);

/**
* LINES Options for `SELECT...INTO` statements.
*
* @var array
*/
public static $LINES_OPTIONS = array(

'STARTING BY' => array(1, 'expr'),
'TERMINATED BY' => array(2, 'expr'),
);

/**
* Type of target (OUTFILE or SYMBOL).
*
Expand Down Expand Up @@ -52,6 +76,29 @@ class IntoKeyword extends Component
*/
public $values;

/**
* Options for FIELDS/COLUMNS keyword
*
* @var OptionsArray
* @see static::$FIELDS_OPTIONS
*/
public $fields_options;

/**
* Whether to use `FIELDS` or `COLUMNS` while building
*
* @var boolean
*/
public $fields_keyword;

/**
* Options for OPTIONS keyword
*
* @var OptionsArray
* @see static::$LINES_OPTIONS
*/
public $lines_options;

/**
* @param Parser $parser The parser that serves as context.
* @param TokensList $list The list of tokens that are being parsed.
Expand Down Expand Up @@ -104,8 +151,10 @@ public static function parse(Parser $parser, TokensList $list, array $options =
continue;
}

// No other keyword is expected.
break;
// No other keyword is expected except for $state = 4, which expects `LINES`
if ($state !== 4) {
break;
}
}

if ($state === 0) {
Expand Down Expand Up @@ -134,15 +183,51 @@ public static function parse(Parser $parser, TokensList $list, array $options =
break;
} elseif ($state === 2) {
$ret->dest = $token->value;
++$list->idx;
break;

$state = 3;
} elseif ($state == 3) {
$ret->parseFileOptions($parser, $list, $token->value);
$state = 4;
} elseif ($state == 4) {
if ($token->type === Token::TYPE_KEYWORD && $token->value !== 'LINES') {
break;
}

$ret->parseFileOptions($parser, $list, $token->value);
$state = 5;
}
}

--$list->idx;
return $ret;
}

public function parseFileOptions(Parser $parser, TokensList $list, $keyword='FIELDS') {
++$list->idx;

if ($keyword === 'FIELDS' || $keyword === 'COLUMNS') {
// parse field options
$this->fields_options = OptionsArray::parse(
$parser,
$list,
static::$FIELDS_OPTIONS
);

if ($keyword === 'FIELDS') {
$this->fields_keyword = true;
} else {
$this->fields_keyword = false;
}
} else {
// parse line options
$this->lines_options = OptionsArray::parse(
$parser,
$list,
static::$LINES_OPTIONS
);
}
}

/**
* @param IntoKeyword $component The component to be built.
* @param array $options Parameters for building.
Expand All @@ -158,7 +243,20 @@ public static function build($component, array $options = array())
} elseif (isset($component->values)) {
return ExpressionArray::build($component->values);
} else {
return 'OUTFILE "' . $component->dest . '"';
$ret = 'OUTFILE "' . $component->dest . '"';

$fields_options_str = OptionsArray::build($component->fields_options);
if (trim($fields_options_str) !== '') {
$ret .= ($component->fields_keyword) ? ' FIELDS' : ' COLUMNS';
$ret .= ' ' . $fields_options_str;
}

$lines_options_str = OptionsArray::build($component->lines_options, array('expr' => true));
if (trim($lines_options_str) !== '') {
$ret .= ' LINES ' . $lines_options_str;
}

return $ret;
}
}
}
8 changes: 4 additions & 4 deletions src/Contexts/ContextMySql50000.php
Original file line number Diff line number Diff line change
Expand Up @@ -145,12 +145,12 @@ class ContextMySql50000 extends Context
'AND CHAIN' => 7, 'FULL JOIN' => 7, 'IF EXISTS' => 7, 'LEFT JOIN' => 7,
'LESS THAN' => 7, 'NO ACTION' => 7, 'ON DELETE' => 7, 'ON UPDATE' => 7,
'UNION ALL' => 7,
'CROSS JOIN' => 7, 'FOR UPDATE' => 7, 'INNER JOIN' => 7, 'LINEAR KEY' => 7,
'NO RELEASE' => 7, 'OR REPLACE' => 7, 'RIGHT JOIN' => 7,
'LINEAR HASH' => 7,
'CROSS JOIN' => 7, 'ESCAPED BY' => 7, 'FOR UPDATE' => 7, 'INNER JOIN' => 7,
'LINEAR KEY' => 7, 'NO RELEASE' => 7, 'OR REPLACE' => 7, 'RIGHT JOIN' => 7,
'ENCLOSED BY' => 7, 'LINEAR HASH' => 7, 'STARTING BY' => 7,
'AND NO CHAIN' => 7, 'FOR EACH ROW' => 7, 'NATURAL JOIN' => 7,
'PARTITION BY' => 7, 'SET PASSWORD' => 7, 'SQL SECURITY' => 7,
'CHARACTER SET' => 7, 'IF NOT EXISTS' => 7,
'CHARACTER SET' => 7, 'IF NOT EXISTS' => 7, 'TERMINATED BY' => 7,
'DATA DIRECTORY' => 7, 'UNION DISTINCT' => 7,
'DEFAULT CHARSET' => 7, 'DEFAULT COLLATE' => 7, 'FULL OUTER JOIN' => 7,
'INDEX DIRECTORY' => 7, 'LEFT OUTER JOIN' => 7, 'SUBPARTITION BY' => 7,
Expand Down
8 changes: 4 additions & 4 deletions src/Contexts/ContextMySql50100.php
Original file line number Diff line number Diff line change
Expand Up @@ -159,12 +159,12 @@ class ContextMySql50100 extends Context
'AND CHAIN' => 7, 'FULL JOIN' => 7, 'IF EXISTS' => 7, 'LEFT JOIN' => 7,
'LESS THAN' => 7, 'NO ACTION' => 7, 'ON DELETE' => 7, 'ON UPDATE' => 7,
'UNION ALL' => 7,
'CROSS JOIN' => 7, 'FOR UPDATE' => 7, 'INNER JOIN' => 7, 'LINEAR KEY' => 7,
'NO RELEASE' => 7, 'OR REPLACE' => 7, 'RIGHT JOIN' => 7,
'LINEAR HASH' => 7,
'CROSS JOIN' => 7, 'ESCAPED BY' => 7, 'FOR UPDATE' => 7, 'INNER JOIN' => 7,
'LINEAR KEY' => 7, 'NO RELEASE' => 7, 'OR REPLACE' => 7, 'RIGHT JOIN' => 7,
'ENCLOSED BY' => 7, 'LINEAR HASH' => 7, 'STARTING BY' => 7,
'AND NO CHAIN' => 7, 'FOR EACH ROW' => 7, 'NATURAL JOIN' => 7,
'PARTITION BY' => 7, 'SET PASSWORD' => 7, 'SQL SECURITY' => 7,
'CHARACTER SET' => 7, 'IF NOT EXISTS' => 7,
'CHARACTER SET' => 7, 'IF NOT EXISTS' => 7, 'TERMINATED BY' => 7,
'DATA DIRECTORY' => 7, 'UNION DISTINCT' => 7,
'DEFAULT CHARSET' => 7, 'DEFAULT COLLATE' => 7, 'FULL OUTER JOIN' => 7,
'INDEX DIRECTORY' => 7, 'LEFT OUTER JOIN' => 7, 'SUBPARTITION BY' => 7,
Expand Down
8 changes: 4 additions & 4 deletions src/Contexts/ContextMySql50500.php
Original file line number Diff line number Diff line change
Expand Up @@ -163,12 +163,12 @@ class ContextMySql50500 extends Context
'AND CHAIN' => 7, 'FULL JOIN' => 7, 'IF EXISTS' => 7, 'LEFT JOIN' => 7,
'LESS THAN' => 7, 'NO ACTION' => 7, 'ON DELETE' => 7, 'ON UPDATE' => 7,
'UNION ALL' => 7,
'CROSS JOIN' => 7, 'FOR UPDATE' => 7, 'INNER JOIN' => 7, 'LINEAR KEY' => 7,
'NO RELEASE' => 7, 'OR REPLACE' => 7, 'RIGHT JOIN' => 7,
'LINEAR HASH' => 7,
'CROSS JOIN' => 7, 'ESCAPED BY' => 7, 'FOR UPDATE' => 7, 'INNER JOIN' => 7,
'LINEAR KEY' => 7, 'NO RELEASE' => 7, 'OR REPLACE' => 7, 'RIGHT JOIN' => 7,
'ENCLOSED BY' => 7, 'LINEAR HASH' => 7, 'STARTING BY' => 7,
'AND NO CHAIN' => 7, 'FOR EACH ROW' => 7, 'NATURAL JOIN' => 7,
'PARTITION BY' => 7, 'SET PASSWORD' => 7, 'SQL SECURITY' => 7,
'CHARACTER SET' => 7, 'IF NOT EXISTS' => 7,
'CHARACTER SET' => 7, 'IF NOT EXISTS' => 7, 'TERMINATED BY' => 7,
'DATA DIRECTORY' => 7, 'UNION DISTINCT' => 7,
'DEFAULT CHARSET' => 7, 'DEFAULT COLLATE' => 7, 'FULL OUTER JOIN' => 7,
'INDEX DIRECTORY' => 7, 'LEFT OUTER JOIN' => 7, 'SUBPARTITION BY' => 7,
Expand Down
8 changes: 4 additions & 4 deletions src/Contexts/ContextMySql50600.php
Original file line number Diff line number Diff line change
Expand Up @@ -169,12 +169,12 @@ class ContextMySql50600 extends Context
'AND CHAIN' => 7, 'FULL JOIN' => 7, 'IF EXISTS' => 7, 'LEFT JOIN' => 7,
'LESS THAN' => 7, 'NO ACTION' => 7, 'ON DELETE' => 7, 'ON UPDATE' => 7,
'UNION ALL' => 7,
'CROSS JOIN' => 7, 'FOR UPDATE' => 7, 'INNER JOIN' => 7, 'LINEAR KEY' => 7,
'NO RELEASE' => 7, 'OR REPLACE' => 7, 'RIGHT JOIN' => 7,
'LINEAR HASH' => 7,
'CROSS JOIN' => 7, 'ESCAPED BY' => 7, 'FOR UPDATE' => 7, 'INNER JOIN' => 7,
'LINEAR KEY' => 7, 'NO RELEASE' => 7, 'OR REPLACE' => 7, 'RIGHT JOIN' => 7,
'ENCLOSED BY' => 7, 'LINEAR HASH' => 7, 'STARTING BY' => 7,
'AND NO CHAIN' => 7, 'FOR EACH ROW' => 7, 'NATURAL JOIN' => 7,
'PARTITION BY' => 7, 'SET PASSWORD' => 7, 'SQL SECURITY' => 7,
'CHARACTER SET' => 7, 'IF NOT EXISTS' => 7,
'CHARACTER SET' => 7, 'IF NOT EXISTS' => 7, 'TERMINATED BY' => 7,
'DATA DIRECTORY' => 7, 'UNION DISTINCT' => 7,
'DEFAULT CHARSET' => 7, 'DEFAULT COLLATE' => 7, 'FULL OUTER JOIN' => 7,
'INDEX DIRECTORY' => 7, 'LEFT OUTER JOIN' => 7, 'SUBPARTITION BY' => 7,
Expand Down
8 changes: 4 additions & 4 deletions src/Contexts/ContextMySql50700.php
Original file line number Diff line number Diff line change
Expand Up @@ -175,12 +175,12 @@ class ContextMySql50700 extends Context
'AND CHAIN' => 7, 'FULL JOIN' => 7, 'IF EXISTS' => 7, 'LEFT JOIN' => 7,
'LESS THAN' => 7, 'NO ACTION' => 7, 'ON DELETE' => 7, 'ON UPDATE' => 7,
'UNION ALL' => 7,
'CROSS JOIN' => 7, 'FOR UPDATE' => 7, 'INNER JOIN' => 7, 'LINEAR KEY' => 7,
'NO RELEASE' => 7, 'OR REPLACE' => 7, 'RIGHT JOIN' => 7,
'LINEAR HASH' => 7,
'CROSS JOIN' => 7, 'ESCAPED BY' => 7, 'FOR UPDATE' => 7, 'INNER JOIN' => 7,
'LINEAR KEY' => 7, 'NO RELEASE' => 7, 'OR REPLACE' => 7, 'RIGHT JOIN' => 7,
'ENCLOSED BY' => 7, 'LINEAR HASH' => 7, 'STARTING BY' => 7,
'AND NO CHAIN' => 7, 'FOR EACH ROW' => 7, 'NATURAL JOIN' => 7,
'PARTITION BY' => 7, 'SET PASSWORD' => 7, 'SQL SECURITY' => 7,
'CHARACTER SET' => 7, 'IF NOT EXISTS' => 7,
'CHARACTER SET' => 7, 'IF NOT EXISTS' => 7, 'TERMINATED BY' => 7,
'DATA DIRECTORY' => 7, 'UNION DISTINCT' => 7,
'DEFAULT CHARSET' => 7, 'DEFAULT COLLATE' => 7, 'FULL OUTER JOIN' => 7,
'INDEX DIRECTORY' => 7, 'LEFT OUTER JOIN' => 7, 'SUBPARTITION BY' => 7,
Expand Down
17 changes: 17 additions & 0 deletions tests/Builder/SelectStatementTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,21 @@ public function testBuilderEndOptions()
$stmt->build()
);
}


public function testBuilderIntoOptions()
{
/* Assertion 1 */
$query = 'SELECT a, b, a+b INTO OUTFILE "/tmp/result.txt"'
. ' COLUMNS TERMINATED BY \',\' OPTIONALLY ENCLOSED BY \'"\''
. ' LINES TERMINATED BY \'\n\''
. ' FROM test_table ';
$parser = new Parser($query);
$stmt = $parser->statements[0];

$this->assertEquals(
$query,
$stmt->build()
);
}
}
3 changes: 3 additions & 0 deletions tests/Parser/SelectStatementTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ public function testSelectProvider()
array('parser/parseSelectCaseErr3'),
array('parser/parseSelectCaseErr4'),
array('parser/parseSelectCaseErr5'),
array('parser/parseSelectIntoOptions1'),
array('parser/parseSelectIntoOptions2'),
array('parser/parseSelectIntoOptions3'),
array('parser/parseSelectJoinCross'),
array('parser/parseSelectJoinNatural'),
array('parser/parseSelectJoinNaturalLeft'),
Expand Down
4 changes: 4 additions & 0 deletions tests/data/parser/parseSelectIntoOptions1.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
SELECT a,b,a+b INTO OUTFILE '/tmp/result.txt'
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"'
LINES TERMINATED BY '\n'
FROM test_table;
10 changes: 10 additions & 0 deletions tests/data/parser/parseSelectIntoOptions1.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
a:4:{s:5:"query";s:152:"SELECT a,b,a+b INTO OUTFILE '/tmp/result.txt'
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"'
LINES TERMINATED BY '\n'
FROM test_table;";s:5:"lexer";O:15:"SqlParser\Lexer":8:{s:6:"strict";b:0;s:3:"str";s:152:"SELECT a,b,a+b INTO OUTFILE '/tmp/result.txt'
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"'
LINES TERMINATED BY '\n'
FROM test_table;";s:3:"len";i:152;s:4:"last";i:152;s:4:"list";O:20:"SqlParser\TokensList":3:{s:6:"tokens";a:39:{i:0;O:15:"SqlParser\Token":5:{s:5:"token";s:6:"SELECT";s:5:"value";s:6:"SELECT";s:4:"type";i:1;s:5:"flags";i:3;s:8:"position";i:0;}i:1;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:6;}i:2;O:15:"SqlParser\Token":5:{s:5:"token";s:1:"a";s:5:"value";s:1:"a";s:4:"type";i:0;s:5:"flags";i:0;s:8:"position";i:7;}i:3;O:15:"SqlParser\Token":5:{s:5:"token";s:1:",";s:5:"value";s:1:",";s:4:"type";i:2;s:5:"flags";i:16;s:8:"position";i:8;}i:4;O:15:"SqlParser\Token":5:{s:5:"token";s:1:"b";s:5:"value";s:1:"b";s:4:"type";i:0;s:5:"flags";i:0;s:8:"position";i:9;}i:5;O:15:"SqlParser\Token":5:{s:5:"token";s:1:",";s:5:"value";s:1:",";s:4:"type";i:2;s:5:"flags";i:16;s:8:"position";i:10;}i:6;O:15:"SqlParser\Token":5:{s:5:"token";s:1:"a";s:5:"value";s:1:"a";s:4:"type";i:0;s:5:"flags";i:0;s:8:"position";i:11;}i:7;O:15:"SqlParser\Token":5:{s:5:"token";s:1:"+";s:5:"value";s:1:"+";s:4:"type";i:2;s:5:"flags";i:1;s:8:"position";i:12;}i:8;O:15:"SqlParser\Token":5:{s:5:"token";s:1:"b";s:5:"value";s:1:"b";s:4:"type";i:0;s:5:"flags";i:0;s:8:"position";i:13;}i:9;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:14;}i:10;O:15:"SqlParser\Token":5:{s:5:"token";s:4:"INTO";s:5:"value";s:4:"INTO";s:4:"type";i:1;s:5:"flags";i:3;s:8:"position";i:15;}i:11;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:19;}i:12;O:15:"SqlParser\Token":5:{s:5:"token";s:7:"OUTFILE";s:5:"value";s:7:"OUTFILE";s:4:"type";i:1;s:5:"flags";i:3;s:8:"position";i:20;}i:13;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:27;}i:14;O:15:"SqlParser\Token":5:{s:5:"token";s:17:"'/tmp/result.txt'";s:5:"value";s:15:"/tmp/result.txt";s:4:"type";i:7;s:5:"flags";i:1;s:8:"position";i:28;}i:15;O:15:"SqlParser\Token":5:{s:5:"token";s:5:"
";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:45;}i:16;O:15:"SqlParser\Token":5:{s:5:"token";s:6:"FIELDS";s:5:"value";s:6:"FIELDS";s:4:"type";i:1;s:5:"flags";i:1;s:8:"position";i:50;}i:17;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:56;}i:18;O:15:"SqlParser\Token":5:{s:5:"token";s:13:"TERMINATED BY";s:5:"value";s:13:"TERMINATED BY";s:4:"type";i:1;s:5:"flags";i:7;s:8:"position";i:57;}i:19;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:70;}i:20;O:15:"SqlParser\Token":5:{s:5:"token";s:3:"','";s:5:"value";s:1:",";s:4:"type";i:7;s:5:"flags";i:1;s:8:"position";i:71;}i:21;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:74;}i:22;O:15:"SqlParser\Token":5:{s:5:"token";s:10:"OPTIONALLY";s:5:"value";s:10:"OPTIONALLY";s:4:"type";i:1;s:5:"flags";i:3;s:8:"position";i:75;}i:23;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:85;}i:24;O:15:"SqlParser\Token":5:{s:5:"token";s:11:"ENCLOSED BY";s:5:"value";s:11:"ENCLOSED BY";s:4:"type";i:1;s:5:"flags";i:7;s:8:"position";i:86;}i:25;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:97;}i:26;O:15:"SqlParser\Token":5:{s:5:"token";s:4:"'\"'";s:5:"value";s:2:"\"";s:4:"type";i:7;s:5:"flags";i:1;s:8:"position";i:98;}i:27;O:15:"SqlParser\Token":5:{s:5:"token";s:5:"
";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:102;}i:28;O:15:"SqlParser\Token":5:{s:5:"token";s:5:"LINES";s:5:"value";s:5:"LINES";s:4:"type";i:1;s:5:"flags";i:3;s:8:"position";i:107;}i:29;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:112;}i:30;O:15:"SqlParser\Token":5:{s:5:"token";s:13:"TERMINATED BY";s:5:"value";s:13:"TERMINATED BY";s:4:"type";i:1;s:5:"flags";i:7;s:8:"position";i:113;}i:31;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:126;}i:32;O:15:"SqlParser\Token":5:{s:5:"token";s:4:"'\n'";s:5:"value";s:2:"\n";s:4:"type";i:7;s:5:"flags";i:1;s:8:"position";i:127;}i:33;O:15:"SqlParser\Token":5:{s:5:"token";s:5:"
";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:131;}i:34;O:15:"SqlParser\Token":5:{s:5:"token";s:4:"FROM";s:5:"value";s:4:"FROM";s:4:"type";i:1;s:5:"flags";i:3;s:8:"position";i:136;}i:35;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:140;}i:36;O:15:"SqlParser\Token":5:{s:5:"token";s:10:"test_table";s:5:"value";s:10:"test_table";s:4:"type";i:0;s:5:"flags";i:0;s:8:"position";i:141;}i:37;O:15:"SqlParser\Token":5:{s:5:"token";s:1:";";s:5:"value";s:1:";";s:4:"type";i:9;s:5:"flags";i:0;s:8:"position";i:151;}i:38;O:15:"SqlParser\Token":5:{s:5:"token";N;s:5:"value";N;s:4:"type";i:9;s:5:"flags";i:0;s:8:"position";N;}}s:5:"count";i:39;s:3:"idx";i:39;}s:9:"delimiter";s:1:";";s:12:"delimiterLen";i:1;s:6:"errors";a:0:{}}s:6:"parser";O:16:"SqlParser\Parser":5:{s:4:"list";r:8;s:6:"strict";b:0;s:6:"errors";a:0:{}s:10:"statements";a:1:{i:0;O:36:"SqlParser\Statements\SelectStatement":16:{s:4:"expr";a:3:{i:0;O:31:"SqlParser\Components\Expression":7:{s:8:"database";N;s:5:"table";N;s:6:"column";s:1:"a";s:4:"expr";s:1:"a";s:5:"alias";N;s:8:"function";N;s:8:"subquery";N;}i:1;O:31:"SqlParser\Components\Expression":7:{s:8:"database";N;s:5:"table";N;s:6:"column";s:1:"b";s:4:"expr";s:1:"b";s:5:"alias";N;s:8:"function";N;s:8:"subquery";N;}i:2;O:31:"SqlParser\Components\Expression":7:{s:8:"database";N;s:5:"table";N;s:6:"column";s:1:"a";s:4:"expr";s:3:"a+b";s:5:"alias";N;s:8:"function";N;s:8:"subquery";N;}}s:4:"from";a:1:{i:0;O:31:"SqlParser\Components\Expression":7:{s:8:"database";N;s:5:"table";s:10:"test_table";s:6:"column";N;s:4:"expr";s:10:"test_table";s:5:"alias";N;s:8:"function";N;s:8:"subquery";N;}}s:9:"partition";N;s:5:"where";N;s:5:"group";N;s:6:"having";N;s:5:"order";N;s:5:"limit";N;s:9:"procedure";N;s:4:"into";O:32:"SqlParser\Components\IntoKeyword":7:{s:4:"type";s:7:"OUTFILE";s:4:"dest";s:15:"/tmp/result.txt";s:7:"columns";N;s:6:"values";N;s:14:"fields_options";O:33:"SqlParser\Components\OptionsArray":1:{s:7:"options";a:3:{i:1;a:4:{s:4:"name";s:13:"TERMINATED BY";s:6:"equals";b:0;s:4:"expr";O:31:"SqlParser\Components\Expression":7:{s:8:"database";N;s:5:"table";N;s:6:"column";s:1:",";s:4:"expr";s:3:"','";s:5:"alias";N;s:8:"function";N;s:8:"subquery";N;}s:5:"value";s:3:"','";}i:2;s:10:"OPTIONALLY";i:3;a:4:{s:4:"name";s:11:"ENCLOSED BY";s:6:"equals";b:0;s:4:"expr";O:31:"SqlParser\Components\Expression":7:{s:8:"database";N;s:5:"table";N;s:6:"column";s:2:"\"";s:4:"expr";s:4:"'\"'";s:5:"alias";N;s:8:"function";N;s:8:"subquery";N;}s:5:"value";s:4:"'\"'";}}}s:14:"fields_keyword";b:1;s:13:"lines_options";O:33:"SqlParser\Components\OptionsArray":1:{s:7:"options";a:1:{i:2;a:4:{s:4:"name";s:13:"TERMINATED BY";s:6:"equals";b:0;s:4:"expr";O:31:"SqlParser\Components\Expression":7:{s:8:"database";N;s:5:"table";N;s:6:"column";s:2:"\n";s:4:"expr";s:4:"'\n'";s:5:"alias";N;s:8:"function";N;s:8:"subquery";N;}s:5:"value";s:4:"'\n'";}}}}s:4:"join";N;s:5:"union";a:0:{}s:11:"end_options";N;s:7:"options";O:33:"SqlParser\Components\OptionsArray":1:{s:7:"options";a:0:{}}s:5:"first";i:0;s:4:"last";i:36;}}s:8:"brackets";i:0;}s:6:"errors";a:2:{s:5:"lexer";a:0:{}s:6:"parser";a:0:{}}}
4 changes: 4 additions & 0 deletions tests/data/parser/parseSelectIntoOptions2.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
SELECT a,b,a+b INTO OUTFILE '/tmp/result.txt'
COLUMNS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"'
LINES TERMINATED BY '\n'
FROM test_table;
Loading