2011-08-06 8 views
4

昨日、同僚が私に次のpostgresクエリを示しました。SELECT *対SELECT *

SELECT* FROM mytable; 

を私は最近、私はなぜこのクエリは「コンパイル」より深く理解しようとSELECT * FROM mytable;と同じ結果を返しています、別の言語用のパーサをコード化されたので:我々は両方それが働いていたことに驚きました。おそらくこれが原因で字句解析時に有効なクエリとして認識されている

、Postgresはトークンとして入力からSELECT読み込み、それが*として見つかった次のトークン、を検索し、というように - である多かれ少なかれ何ここにいるの?

また、postgres lexer/parserはこのクエリを理解するのに十分な堅牢性を持っていますか、他のデータベースで同様のSELECT*クエリを理解していますか?

+1

作品、ここで

は、SELECT文のBNFです。 – Jacob

+0

APEXとの関係は不明です。 –

+0

スペースにかかわらずDBが「SELECT *」を受け入れるという事実、またはスペースに関係なく「SELEcT *」が受け入れられることに驚いていますか?後者は一般的なプログラミング言語の標準です。空白は一般的にオプションです。私はデータベースベンダーの間でどのように「SELECT *」が共通しているのか分かりませんが、それは十分明確です。 –

答えて

5

通常、レクサーは、現在のトークンに属していない文字が見つかるまで、現在のトークンに文字を追加します。その後、終了していない場所から終了します。

それでは、ここで起こっているのは、レクサーはSELECTをゴブルズし、次の文字がSELECTに属することはできません、それは言葉を集めているため、*であることを認識していることです。それで、それは停止し、SELECTをキーワードとして分析し、それが認識する*などからやり直します。他のプログラミング言語でを2*22 * 2の両方から取得するのと同じ理由があります。

他のデータベースで動作するかどうかは、すべて字句解析ツールの詳細と文法のルールによって異なります。

2

私が知る限り、SQLはスキップして空白を解析できるので、SELECT*FROM or SELECT * FROMは基本的に同じです。

`'も何であるかを理解するために使用します。だからSELECT * FROM myTable WHERE id = my stringは "と"の "文字列"が理解されていないため無効なクエリになります。

+0

本当ですか?たとえば、cularisは、この構文がOracleの少なくとも1つのフレーバーでは機能しないことを示しました。 –

3

明らかにトークナイザは空白と演算で使用される特殊文字をトークン化します。 h2database.com:ないのOracle APEXにあまりにもMySQLの上

SELECT [ TOP term ] [ DISTINCT | ALL ] selectExpression [,...] 
FROM tableExpression [,...] [ WHERE expression ] 
[ GROUP BY expression [,...] ] [ HAVING expression ] 
[ { UNION [ ALL ] | MINUS | EXCEPT | INTERSECT } select ] [ ORDER BY order [,...] ] 
[ LIMIT expression [ OFFSET expression ] [ SAMPLE_SIZE rowCountInt ] ] 
[ FOR UPDATE ]