Skip to content

Commit 4d10545

Browse files
committed
Fix issue with OUTER JOIN syntax.
Fix problem where subqueries were not parsed, and their contents placed into 'sub_expr'. Fix problem with the token 0 in places other than the WHERE clause. Some general code cleanup (remove commented code). git-svn-id: https://php-sql-parser.googlecode.com/svn/trunk@40 44dcfd11-89b7-3d55-2063-5c365055f77f
1 parent a6e5eb6 commit 4d10545

File tree

6 files changed

+106
-64
lines changed

6 files changed

+106
-64
lines changed

.buildpath

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<buildpath>
3+
<buildpathentry kind="src" path=""/>
4+
<buildpathentry kind="con" path="org.eclipse.php.core.LANGUAGE"/>
5+
</buildpath>

.project

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<projectDescription>
3+
<name>PHP-SQL-Parser</name>
4+
<comment></comment>
5+
<projects>
6+
</projects>
7+
<buildSpec>
8+
<buildCommand>
9+
<name>org.eclipse.wst.validation.validationbuilder</name>
10+
<arguments>
11+
</arguments>
12+
</buildCommand>
13+
<buildCommand>
14+
<name>org.eclipse.dltk.core.scriptbuilder</name>
15+
<arguments>
16+
</arguments>
17+
</buildCommand>
18+
</buildSpec>
19+
<natures>
20+
<nature>org.eclipse.php.core.PHPNature</nature>
21+
</natures>
22+
</projectDescription>

.settings/org.eclipse.php.core.prefs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#Sun May 01 15:33:45 EDT 2011
2+
eclipse.preferences.version=1
3+
include_path=0;/PHP-SQL-Parser

php-sql-parser.php

Lines changed: 66 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ private function process_sql(&$tokens,$start_at = 0, $stop_at = false) {
314314
$token_category = 'SELECT';
315315
}
316316

317-
/* If it isn't obvious, when $skip_next is set, then we ignore the next real
317+
/* If it isn't obvious, when $skip_next is set, then we ignore the next real
318318
token, that is we ignore whitespace.
319319
*/
320320
if($skip_next) {
@@ -323,7 +323,7 @@ private function process_sql(&$tokens,$start_at = 0, $stop_at = false) {
323323
continue;
324324
}
325325

326-
#to skip the token we replace it with whitespace
326+
#to skip the token we replace it with whitespace
327327
$new_token = "";
328328
$skip_next = false;
329329
}
@@ -440,7 +440,6 @@ private function process_sql(&$tokens,$start_at = 0, $stop_at = false) {
440440
break;
441441

442442
case 'USING':
443-
#case 'ON':
444443
/* USING in FROM clause is different from USING w/ prepared statement*/
445444
if($token_category == 'EXECUTE') {
446445
$token_category=$upper;
@@ -545,7 +544,6 @@ private function process_sql(&$tokens,$start_at = 0, $stop_at = false) {
545544
break;
546545
}
547546

548-
#echo "HERE: $token $token_number\n";
549547
if($prev_category == $token_category) {
550548
$out[$token_category][] = $token;
551549
}
@@ -592,7 +590,7 @@ private function process_set_list($tokens) {
592590
foreach($tokens as $token) {
593591
$token=trim($token);
594592
if(!$column) {
595-
if(!$token) continue;
593+
if($token === false || empty($token)) continue;
596594
$column .= $token;
597595
continue;
598596
}
@@ -659,7 +657,7 @@ private function process_select(&$tokens) {
659657
$expr[] = $this->process_select_expr(trim($expression));
660658
$expression = "";
661659
} else {
662-
if(!$token) $token=" ";
660+
if($token === "" || $token===false) $token=" ";
663661
$expression .= $token ;
664662
}
665663
}
@@ -748,7 +746,8 @@ private function process_select_expr($expression) {
748746
}
749747
$processed = false;
750748
$type='expression';
751-
if(trim($base_expr) == '(') {
749+
750+
if(substr(trim($base_expr),0,1) == '(') {
752751
$base_expr = substr($expression,1,-1);
753752
if(preg_match('/^sel/i', $base_expr)) {
754753
$type='subquery';
@@ -775,16 +774,19 @@ private function process_from(&$tokens) {
775774
$expr = array();
776775
$token_count=0;
777776
$table = "";
778-
$alias = "";
777+
$alias = "";
779778

780779
$skip_next=false;
781780
$i=0;
782-
$join_type = '';
781+
$join_type = '';
783782
$ref_type="";
784783
$ref_expr="";
785784
$base_expr="";
786785
$sub_tree = false;
787786
$subquery = "";
787+
788+
$first_join=true;
789+
788790
foreach($tokens as $token) {
789791
$base_expr = false;
790792
$upper = strtoupper(trim($token));
@@ -798,20 +800,49 @@ private function process_from(&$tokens) {
798800
continue;
799801
}
800802
}
803+
801804
if(preg_match("/^\\s*\\(\\s*select/i",$token)) {
802805
$type = 'subquery';
803806
$table = "DEPENDENT-SUBQUERY";
804807
$sub_tree = $this->parse(trim($token,'() '));
805808
$subquery = $token;
806809
}
807810

808-
if($upper != 'JOIN' && $token != ',') {
809-
$expression .= $token == '' ? " " : $token;
810-
if($ref_type) {
811-
$ref_expr .= $token == '' ? " " : $token;
812-
}
813-
814-
}
811+
switch($upper) {
812+
case 'OUTER':
813+
continue;
814+
break;
815+
816+
case 'LEFT':
817+
case 'RIGHT':
818+
case 'NATURAL':
819+
case 'CROSS':
820+
//if($join_type == "") {
821+
if($first_join) {
822+
$first_join = false;
823+
$join_type = 'JOIN';
824+
} else {
825+
$join_type = " " . $upper . " ";
826+
}
827+
//} else {
828+
// $join_type = " " . $upper . " ";
829+
//}
830+
831+
break;
832+
833+
case ',':
834+
case 'JOIN':
835+
$first_join=false;
836+
if($join_type == "") $join_type = "JOIN ";
837+
break;
838+
839+
default:
840+
$expression .= $token == '' ? " " : $token;
841+
if($ref_type) {
842+
$ref_expr .= $token == '' ? " " : $token;
843+
}
844+
break;
845+
}
815846

816847
switch($upper) {
817848
case 'AS':
@@ -827,7 +858,6 @@ private function process_from(&$tokens) {
827858
break;
828859

829860
case 'INDEX':
830-
831861
if($token_category == 'CREATE') {
832862
$token_category = $upper;
833863
continue 2;
@@ -855,53 +885,34 @@ private function process_from(&$tokens) {
855885
case 'LEFT':
856886
case 'RIGHT':
857887
case 'STRAIGHT_JOIN':
858-
$join_type .= ($token == '' ? ' ' : $token . " ");
859-
$ref_expr = "";
860888
continue;
861889
break;
862-
863-
case 'FOR':
890+
891+
case 'FOR':
864892
$token_count++;
865893
$skip_next = true;
866894
continue;
867895
break;
868-
869-
case ',':
896+
897+
case ',':
870898
case 'JOIN':
871-
#any options for the first join (the one after the FROM) are "stuck" to the first
872-
#table. we need to use 'FROM' as the join_type for the first table, and save the
873-
#"stuck" options for the next table
874-
$save_join_type = "";
875-
if(count($expr)>0) {
876-
$join_type .= $token == ',' ? ' JOIN' : $upper;
877-
} else {
878-
$save_join_type = $join_type;
879-
$join_type = 'JOIN';
880-
}
899+
881900
if(!trim($alias)) $alias = $table;
882-
883-
$join_type=strtoupper($join_type);
884-
/*if(!$base_expr) {
885-
$expr[] = array('table'=>$table, 'alias'=>$alias,'join_type'=>$join_type,'ref_type'=> $ref_type,'ref_clause'=> $ref_expr);
886-
} else {*/
887-
if($subquery) $base_expr=$subquery;
888-
$expr[] = array('table'=>$table, 'alias'=>$alias,'join_type'=>$join_type,'ref_type'=> $ref_type,'ref_clause'=> $ref_expr, 'base_expr' => $base_expr, 'sub_tree' => $sub_tree);
889-
$subquery = "";
890-
# }
891-
892-
if($save_join_type) {
893-
$join_type = $save_join_type;
894-
} else {
895-
$join_type = "";
901+
if($subquery) {
902+
$sub_tree = $this->parse(trim($subquery,'()'));
903+
$base_expr=$subquery;
896904
}
905+
$expr[] = array('table'=>$table, 'alias'=>$alias,'join_type'=>$join_type,'ref_type'=> $ref_type,'ref_clause'=> $ref_expr, 'base_expr' => $base_expr, 'sub_tree' => $sub_tree);
906+
897907
$token_count = 0;
898-
$table = $alias = $expression = $base_expr = $ref_type = $ref_expr = "";
899-
$sub_tree = false;
908+
$table = $alias = $expression = $base_expr = $ref_type = $ref_expr = "";
909+
$sub_tree=false;
910+
$subquery = "";
900911

901912
break;
902913

903914
default:
904-
if(!$token) continue;
915+
if($token === false || empty($token) || $token === "") continue;
905916

906917
if($token_count == 0 ) {
907918
if(!$table) {
@@ -915,13 +926,11 @@ private function process_from(&$tokens) {
915926
}
916927
++$i;
917928
}
918-
if($join_type == '') $join_type = 'JOIN';
919-
if(!trim($alias)) $alias = $table;
920-
/*if(!$base_expr) {
921-
$expr[] = array('table'=>$table, 'alias'=>$alias,'join_type'=>$join_type,'ref_type'=> $ref_type,'ref_clause'=> $ref_expr);
922-
} else { */
923-
$expr[] = array('table'=>$table, 'alias'=>$alias,'join_type'=>$join_type,'ref_type'=> $ref_type,'ref_clause'=> $ref_expr, 'base_expr' => $base_expr, 'sub_tree' => $sub_tree);
924-
# }
929+
if($join_type == '') $join_type = 'JOIN';
930+
931+
if(!trim($alias)) $alias = $table;
932+
$expr[] = array('table'=>$table, 'alias'=>$alias,'join_type'=>$join_type,'ref_type'=> $ref_type,'ref_clause'=> $ref_expr, 'base_expr' => $base_expr, 'sub_tree' => $sub_tree);
933+
925934

926935
return $expr;
927936
}

t/from.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222

2323
$parser = new PHPSQLParser($sql);
2424
$p=$parser->parsed;
25-
#print_r($p);
2625

2726
ok(count($p['SELECT']) == 7);
2827
ok($p['SELECT'][0]['alias'] == '`c1`');

t/left.php

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,26 @@
1010
LEFT JOIN tableb b ON b.ida = a.id
1111
LEFT JOIN tablec c ON c.idb = b.id;';
1212

13-
echo $sql . "\n";
14-
1513
$parser->parse($sql);
1614
$p = $parser->parsed;
17-
print_r($p);
15+
16+
$result = serialize($p);
17+
#file_put_contents('../r/left1.serialized',$result);
18+
$good = file_get_contents('../r/left1.serialized');
19+
ok($result == $good);
1820

1921
$sql = 'SELECT a.field1, b.field1, c.field1
2022
FROM tablea a
2123
LEFT OUTER JOIN tableb b ON b.ida = a.id
22-
LEFT OUTER JOIN tablec c ON c.idb = b.id;';
24+
RIGHT JOIN tablec c ON c.idb = b.id
25+
JOIN tabled d USING (d_id);';
2326

24-
echo $sql . "\n";
2527

2628
$parser->parse($sql);
2729
$p = $parser->parsed;
28-
print_r($p);
30+
#file_put_contents('../r/left2.serialized',$result);
31+
$good = file_get_contents('../r/left2.serialized');
32+
ok($result == $good);
2933

3034

3135

0 commit comments

Comments
 (0)