From: Rob Kinyon Date: Thu, 26 Mar 2009 02:36:59 +0000 (-0400) Subject: Merge branch 'master' of git@github.com:ashb/sql-abstract X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=6540cc992748d08d5b88faeb99bfbf223721e4ee;hp=7c300b3abb9f994c68386b75df631487aed0237b;p=dbsrgits%2FSQL-Abstract-2.0-ish.git Merge branch 'master' of git@github.com:ashb/sql-abstract --- diff --git a/lib/SQL/Abstract/Manual/Examples.pod b/lib/SQL/Abstract/Manual/Examples.pod new file mode 100644 index 0000000..c684127 --- /dev/null +++ b/lib/SQL/Abstract/Manual/Examples.pod @@ -0,0 +1,247 @@ +=head1 NAME + +SQL::Abstract::Manual::Specification + +=head1 DESCRIPTION + +These are the examples for the AST + +=head1 EXAMPLES + +The following are example SQL statements and the AST that would represent each +one. The SQL used is from the MySQL dialect. + +=over 4 + +=item * SELECT 1 + + { + type => 'select', + ast_version => 0.0001, + select => [ + { + type => 'SelectComponent', + value => { + type => 'Value', + subtype => 'number', + value => 1, + }, + }, + ], + } + +=item * SELECT NOW() AS time FROM dual AS duality + + { + type => 'select', + ast_version => 0.0001, + select => [ + { + type => 'SelectComponent', + value => { + type => 'Function', + function => 'NOW', + }, + as => { + type => 'Identifier', + element1 => 'time', + }, + }, + ], + tables => { + type => 'TableIdentifier', + value => { + type => 'Identifier', + element1 => 'dual', + }, + as => 'duality', + }, + } + +=item * SELECT 1 FROM foo LEFT OUTER JOIN bar ON ( foo.col1 = bar.col2 ) + + { + type => 'select', + ast_version => 0.0001, + select => [ + { + type => 'SelectComponent', + value => { + type => 'Value', + subtype => 'number', + value => 1, + }, + }, + ], + tables => { + type => 'Operator', + op => 'LEFT OUTER', + args => [ + { + type => 'TableIdentifier', + value => { + type => 'Identifier', + element1 => 'foo', + }, + }, + { + type => 'TableIdentifier', + value => { + type => 'Identifier', + element1 => 'bar', + }, + }, + ], + on => { + type => 'Operator', + op => '=', + args => [ + { + type => 'Identifier', + element1 => 'foo', + element2 => 'col1', + }, + { + type => 'Identifier', + element1 => 'bar', + element2 => 'col2', + }, + ], + }, + }, + } + +=item SELECT * FROM foo WHERE name = 'John' + + { + type => 'select', + ast_version => 0.0001, + select => [ + { + type => 'SelectComponent', + value => { + type => 'Identifier', + element1 => '*', + }, + }, + ], + tables => { + type => 'TableIdentifier', + value => { + type => 'Identifier', + element1 => 'foo', + }, + }, + where => { + type => 'Operator', + op => '=', + args => [ + { + type => 'Identifier', + element1 => 'name', + }, + { + type => 'Value', + subtype => 'String', + element1 => 'John', + }, + ], + }, + } + +=item SELECT COUNT(*) FROM foo WHERE name = 'John' AND ( title = 'Mr' OR abbrev = 'Dr' ) + + { + type => 'select', + ast_version => 0.0001, + select => [ + { + type => 'SelectComponent', + value => { + type => 'Identifier', + element1 => '*', + }, + }, + ], + tables => { + type => 'TableIdentifier', + value => { + type => 'Identifier', + element1 => 'foo', + }, + }, + where => { + type => 'Operator', + op => 'AND', + args => [ + { + type => 'Operator', + op => '=', + args => [ + { + type => 'Identifier', + element1 => 'name', + }, + { + type => 'Value', + subtype => 'String', + element1 => 'John', + }, + ], + }, + { + type => 'Nesting', + args => [ + { + type => 'Operator', + op => 'OR', + args => [ + { + type => 'Operator', + op => '=', + args => [ + { + type => 'Identifier', + element1 => 'title', + }, + { + type => 'Value', + subtype => 'String', + element1 => 'Mr', + }, + ], + }, + { + type => 'Operator', + op => '=', + args => [ + { + type => 'Identifier', + element1 => 'abbrev', + }, + { + type => 'Value', + subtype => 'String', + element1 => 'Dr', + }, + ], + }, + ], + }, + ], + }, + ], + }, + } + +=back + +=head1 AUTHORS + +robkinyon: Rob Kinyon C<< >> + +=head1 LICENSE + +You may distribute this code under the same terms as Perl itself. + +=cut diff --git a/lib/SQL/Abstract/Manual/Specification.pod b/lib/SQL/Abstract/Manual/Specification.pod index 4484cd9..23ea0b1 100644 --- a/lib/SQL/Abstract/Manual/Specification.pod +++ b/lib/SQL/Abstract/Manual/Specification.pod @@ -118,21 +118,20 @@ enforcing that dialect's rules. The AST will be a HoHo..oH (hash of hash of ... of hashes). The keys to the outermost hash will be the various clauses of a SQL statement, plus some -metadata keys. All metadata keys will be identifiable as such by being prefixed -with an underscore. All keys will be in lowercase. +metadata keys. =head2 Metadata keys These are the additional metadata keys that the AST provides for. -=head3 _query +=head3 type This denotes what kind of query this AST should be interpreted as. Different -Visitors may accept additional values for _query. For example, a MySQL Visitor -may choose to accept 'replace' for REPLACE INTO. If a _query value is +Visitors may accept additional values for type. For example, a MySQL Visitor +may choose to accept 'replace' for REPLACE INTO. If a type value is unrecognized by the Visitor, the Visitor is expected to throw an error. -All Visitors are expected to handle the following values for _query: +All Visitors are expected to handle the following values for type: =over 4 @@ -154,10 +153,10 @@ This is a DELETE statement. =back -=head3 _version +=head3 ast_version This denotes the version of the AST. Different versions will indicate different -capabilities provided. Visitors will choose to respect the _version as needed +capabilities provided. Visitors will choose to respect the ast_version as needed and desired. =head2 Structural units @@ -201,6 +200,9 @@ given element exists, then it must be defined and of non-zero length. Visitors are expected to, by default, quote all identifiers according to the SQL dialect's quoting scheme. +Any of the elements may be '*', as in SELECT * or SELECT COUNT(*). Visitors must +be careful to I quote asterisks. + =head3 Value A Value is a Perl scalar. Depending on the type, a Visitor may be able to make @@ -278,7 +280,7 @@ as 'AND'. This will have to be managed by the Visitor. =head3 Subquery -A Subquery is another AST whose _query metadata parameter is set to "SELECT". +A Subquery is another AST whose type metadata parameter is set to "SELECT". Most places that a Subquery can be used would require a single value to be returned (single column, single row), but that is not something that the AST can @@ -323,6 +325,17 @@ The hash for an ExpressionList is as follows: An ExpressionList is always rendered in SQL with parentheses around it. +=head3 Nesting + +A Nesting is, essentially, another set of parentheses. + +The hash for a Nesting is as follows: + + { + type => 'Nesting', + args => Array of Expressions, + } + =head2 SQL clauses These are all the legal and acceptable clauses within the AST that would @@ -382,7 +395,7 @@ certain situations. This is a list of tables that this clause is affecting. It corresponds to the FROM clause in a SELECT statement and the INSERT INTO/UPDATE/DELETE clauses in -those respective statements. Depending on the _query metadata entry, the +those respective statements. Depending on the type metadata entry, the appropriate clause name will be used. The tables clause has several RDBMS-specific variations. The AST will support @@ -427,12 +440,7 @@ optional. This corresponds to the WHERE clause in a SELECT, UPDATE, or DELETE statement. -A where clause is composed as follows: - - WhereOperator := AND | OR - WhereExpression := Expression | Expression WhereOperator Expression - - WhereExpression +A where clause is composed of an Expression. =head3 set @@ -518,112 +526,6 @@ A connectby clause is composed as follows: Identifier, WhereExpression -=head1 EXAMPLES - -The following are example SQL statements and a possible AST for each one. - -=over 4 - -=item * SELECT 1 - - { - _query => 'select', - _ast_version => 0.0001, - select => [ - { - type => 'SelectComponent', - value => { - type => 'Value', - subtype => 'number', - value => 1, - }, - }, - ], - } - -=item * SELECT NOW() AS time FROM dual AS duality - - { - _query => 'select', - _ast_version => 0.0001, - select => [ - { - type => 'SelectComponent', - value => { - type => 'Function', - function => 'NOW', - }, - as => { - type => 'Identifier', - element1 => 'time', - }, - }, - ], - tables => { - type => 'TableIdentifier', - value => { - type => 'Identifier', - element1 => 'dual', - }, - as => 'duality', - }, - } - -=item * SELECT 1 FROM foo LEFT OUTER JOIN bar ON ( foo.col1 = bar.col2 ) - - { - _query => 'select', - _ast_version => 0.0001, - select => [ - { - type => 'SelectComponent', - value => { - type => 'Value', - subtype => 'number', - value => 1, - }, - }, - ], - tables => { - type => 'Operator', - op => 'LEFT OUTER', - args => [ - { - type => 'TableIdentifier', - value => { - type => 'Identifier', - element1 => 'foo', - }, - }, - { - type => 'TableIdentifier', - value => { - type => 'Identifier', - element1 => 'bar', - }, - }, - ], - on => { - type => 'Operator', - op => '=', - args => [ - { - type => 'Identifier', - element1 => 'foo', - element2 => 'col1', - }, - { - type => 'Identifier', - element1 => 'bar', - element2 => 'col2', - }, - ], - }, - }, - } - -=back - =head1 TODO =over 4