Commit | Line | Data |
d6e108eb |
1 | =head1 NAME |
2 | |
3 | SQL::Abstract::Manual::Specification |
4 | |
5 | =head1 SYNOPSIS |
6 | |
7 | This discusses the specification for the AST provided by L<SQL::Abstract>. It is |
8 | meant to describe how the AST is structured, various components provided by |
9 | L<SQL::Abstract> for use with this AST, how to manipulate the AST, and various |
10 | uses for the AST once it is generated. |
11 | |
12 | =head1 MOTIVATIONS |
13 | |
14 | L<SQL::Abstract> has been in use for many years. Originally created to handle |
15 | the where-clause formation found in L<DBIx::Abstract>, it was generalized to |
16 | manage the creation of any SQL statement through the use of Perl structures. |
17 | Through the beating it received as the SQL generation syntax for L<DBIx::Class>, |
18 | various deficiencies were found and a generalized SQL AST was designed. This |
19 | document describes that AST. |
20 | |
21 | =head1 GOALS |
22 | |
23 | The goals for this AST are as follows: |
24 | |
25 | =head2 SQL-specific semantics |
26 | |
27 | Instead of attempting to be an AST to handle any form of query, this will |
28 | instead be specialized to manage SQL queries (and queries that map to SQL |
29 | queries). This means that there will be support for SQL-specific features, such |
30 | as placeholders. |
31 | |
32 | =head2 Perl-specific semantics |
33 | |
34 | This AST is meant to be used from within Perl5 only. So, it will take advantage |
35 | of as many Perl-specific features that make sense to use. No attempt whatosever |
36 | will be made to make this AST work within any other language, including Perl6. |
37 | |
38 | =head2 Whole-lifecycle management |
39 | |
40 | Whether a query is built out of whole cloth in one shot or cobbled together from |
41 | several snippets over the lifetime of a process, this AST will support any way |
42 | to construct the query. Queries can also be built from other queries, so an |
43 | UPDATE statement could be used as the basis for a SELECT statement, DELETE |
44 | statement, or even a DDL statement of some kind. |
45 | |
46 | =head2 Dialect-agnostic usage |
47 | |
48 | Even though SQL itself has several ANSI specifications (SQL-92 and SQL-99 among |
49 | them), this only serves as a basis for what a given RDBMS will expect. However, |
50 | every engine has its own specific extensions and specific ways of handling |
393a4eb8 |
51 | common features. The AST will provide ways of expressing common functionality in |
52 | a common language. The emitters (objects that follow the Visitor pattern) will |
53 | be responsible for converting that common language into RDBMS-specific SQL. |
54 | |
ad0f8fa6 |
55 | =head1 RESTRICTIONS |
56 | |
57 | The following are the restrictions upon the AST: |
58 | |
59 | =head2 DML-only |
60 | |
61 | The AST will only support DML (Data Modelling Language). It will not (currently) |
62 | support DDL (Data Definition Language). Practically, this means that the only |
63 | statements supported will be: |
64 | |
65 | =over 4 |
66 | |
67 | =item * SELECT |
68 | |
69 | =item * INSERT INTO |
70 | |
71 | =item * UPDATE |
72 | |
73 | =item * DELETE |
74 | |
75 | =back |
76 | |
77 | Additional DML statements may be supported by specific Visitors (such as a |
78 | MySQL visitor supporting REPLACE INTO). q.v. the relevant sections of this |
79 | specification for details. |
80 | |
804bd4ab |
81 | =head2 Dialect-agnostic construction |
82 | |
83 | The AST will not attempt to be immediately readable to a human as SQL. In fact, |
84 | due to the dialect differences, particularly in terms of which use operators and |
cca4daf5 |
85 | which use functions for a given action, the AST will provide simple units. It is |
86 | the responsibility of the Visitor to provide the appropriate SQL. Furthermore, |
87 | the AST will be very generic and only provide hints for a subset of SQL. If a |
88 | Visitor is sufficiently intelligent, pretty SQL may be emitted, but that is not |
89 | the goal of this AST. |
804bd4ab |
90 | |
393a4eb8 |
91 | =head1 COMPONENTS |
92 | |
93 | There are two major components to SQL::Abstract v2. |
94 | |
95 | =over 4 |
96 | |
97 | =item * AST |
98 | |
99 | This is the Abstract Syntax Tree. It is a data structure that represents |
100 | everything necessary to construct the SQL statement in whatever dialect the |
101 | user requires. |
102 | |
103 | =item * Visitor |
104 | |
105 | This object conforms to the Visitor pattern and is used to generate the SQL |
106 | represented by the AST. Each dialect will have a different Visitor object. In |
107 | addition, there will be visitors for at least one of the ANSI specifications. |
108 | |
109 | =back |
d6e108eb |
110 | |
df35a525 |
111 | The division of duties between the two components will focus on what the AST |
112 | can and cannot assume. For example, identifiers do not have 20 components in |
113 | any dialect, so the AST can validate that. However, determining what |
114 | constitutes a legal identifier can only be determined by the Visitor object |
115 | enforcing that dialect's rules. |
116 | |
d6e108eb |
117 | =head1 AST STRUCTURE |
118 | |
393a4eb8 |
119 | The AST will be a HoHo..oH (hash of hash of ... of hashes). The keys to the |
120 | outermost hash will be the various clauses of a SQL statement, plus some |
37f2cc3f |
121 | metadata keys. |
d6e108eb |
122 | |
123 | =head2 Metadata keys |
124 | |
125 | These are the additional metadata keys that the AST provides for. |
126 | |
37f2cc3f |
127 | =head3 type |
df35a525 |
128 | |
129 | This denotes what kind of query this AST should be interpreted as. Different |
37f2cc3f |
130 | Visitors may accept additional values for type. For example, a MySQL Visitor |
131 | may choose to accept 'replace' for REPLACE INTO. If a type value is |
7c66a0ab |
132 | unrecognized by the Visitor, the Visitor is expected to throw an error. |
df35a525 |
133 | |
37f2cc3f |
134 | All Visitors are expected to handle the following values for type: |
df35a525 |
135 | |
d6e108eb |
136 | =over 4 |
137 | |
df35a525 |
138 | =item * select |
139 | |
140 | This is a SELECT statement. |
d6e108eb |
141 | |
df35a525 |
142 | =item * insert |
d6e108eb |
143 | |
df35a525 |
144 | This is an INSERT statement. |
393a4eb8 |
145 | |
df35a525 |
146 | =item * update |
147 | |
148 | This is an UPDATE statement. |
149 | |
150 | =item * delete |
151 | |
152 | This is a DELETE statement. |
d6e108eb |
153 | |
154 | =back |
155 | |
37f2cc3f |
156 | =head3 ast_version |
df35a525 |
157 | |
158 | This denotes the version of the AST. Different versions will indicate different |
37f2cc3f |
159 | capabilities provided. Visitors will choose to respect the ast_version as needed |
df35a525 |
160 | and desired. |
161 | |
d6e108eb |
162 | =head2 Structural units |
163 | |
df35a525 |
164 | All structural units will be hashes. These hashes will have, at minimum, the |
165 | following keys: |
166 | |
167 | =over 4 |
168 | |
804bd4ab |
169 | =item * type |
df35a525 |
170 | |
171 | This indicates the structural unit that this hash is representing. While this |
172 | specification provides for standard structural units, different Visitors may |
173 | choose to accept additional units as desired. If a Visitor encounters a unit it |
174 | doesn't know how to handle, it is expected to throw an exception. |
175 | |
176 | =back |
177 | |
d6e108eb |
178 | Structural units in the AST are supported by loaded components. L<SQL::Abstract> |
179 | provides for the following structural units by default: |
180 | |
181 | =head3 Identifier |
182 | |
df35a525 |
183 | This is a (potentially) fully canonicalized identifier for a elemnt in the |
184 | query. This element could be a schema, table, or column. The Visitor will |
185 | determine validity within the context of that SQL dialect. The AST is only |
186 | responsible for validating that the elements are non-empty Strings. |
187 | |
188 | The hash will be structured as follows: |
189 | |
190 | { |
804bd4ab |
191 | type => 'Identifier', |
a08e7c02 |
192 | elements => [ Scalar ], |
df35a525 |
193 | } |
d6e108eb |
194 | |
a08e7c02 |
195 | All values in elements must be defined. |
7c66a0ab |
196 | |
ad0f8fa6 |
197 | Visitors are expected to, by default, quote all identifiers according to the SQL |
198 | dialect's quoting scheme. |
d6e108eb |
199 | |
4f6e8987 |
200 | Any of the elements may be '*', as in SELECT * or SELECT COUNT(*). Visitors must |
201 | be careful to I<not> quote asterisks. |
202 | |
10000e9e |
203 | =head3 Value |
d6e108eb |
204 | |
da93022e |
205 | A Value is a Perl scalar. Depending on the subtype, a Visitor may be able to |
206 | make certain decisions. The following are the minimally-valid subtypes: |
10000e9e |
207 | |
208 | =over 4 |
209 | |
210 | =item * String |
211 | |
7c66a0ab |
212 | A String is a quoted series of characters. The Visitor is expected to ensure |
213 | that embedded quotes are properly handled per the SQL dialect's quoting scheme. |
10000e9e |
214 | |
215 | =item * Number |
216 | |
7c66a0ab |
217 | A Number is an unquoted number in some numeric format. |
10000e9e |
218 | |
ad0f8fa6 |
219 | =item * Null |
10000e9e |
220 | |
5ec9ab19 |
221 | A Null is SQL's NULL and corresponds to Perl's C<undef>. |
10000e9e |
222 | |
5ec9ab19 |
223 | =item * Boolean |
10000e9e |
224 | |
5ec9ab19 |
225 | A Boolean is a two-value entity - true or false. Some DBMSes provide an explicit |
226 | boolean while others do not. |
10000e9e |
227 | |
5ec9ab19 |
228 | =item * Date |
229 | |
230 | A Date represents (generally) a year, month, and day. |
231 | |
232 | =item * Time |
233 | |
234 | A Time represents (generally) an hour, minute, and second. |
235 | |
236 | =item * DateTime |
237 | |
238 | A DateTime represents the complete description necessary to determine a specific point in |
239 | time. This could correspond to a L<DateTime/> object in Perl. |
7c66a0ab |
240 | |
10000e9e |
241 | =back |
242 | |
a3872878 |
243 | The hash will be structured as follows: |
244 | |
245 | { |
804bd4ab |
246 | type => 'Value' |
5ec9ab19 |
247 | subtype => [ 'String' | 'Number' | 'Null' | 'Boolean' | 'Date' | 'Time' | 'DateTime' ] |
7c66a0ab |
248 | value => Scalar |
5ec9ab19 |
249 | is_bind => Boolean |
a3872878 |
250 | } |
251 | |
252 | The provided subtypes are the ones that all Visitors are expected to support. |
253 | Visitors may choose to support additional subtypes. Visitors are expected to |
254 | throw an exception upon encountering an unknown subtype. |
d6e108eb |
255 | |
5ec9ab19 |
256 | C<is_bind> defaults to true. It determines whether or not the Visitor should |
257 | attempt to treat this value as a BindParameter or not. |
258 | |
804bd4ab |
259 | =head3 Operator |
81cd86f1 |
260 | |
804bd4ab |
261 | An Operator would be, in SQL dialect terms, a unary operator, a binary operator, |
262 | a trinary operator, or a function. Since different dialects may have a given |
263 | functionality as an operator or a function (such as CONCAT in MySQl vs. || in |
264 | Oracle for string concatenation), they will be represented in the AST as generic |
265 | operators. |
d6e108eb |
266 | |
7c66a0ab |
267 | The hash will be structured as follows: |
268 | |
269 | { |
804bd4ab |
270 | type => 'Operator', |
271 | op => String, |
f32d60b9 |
272 | args => [ |
273 | Expression, |
274 | ], |
7c66a0ab |
275 | } |
276 | |
804bd4ab |
277 | Operators have a cardinality, or expected number of arguments. Some operators, |
ad0f8fa6 |
278 | such as MAX(), have a cardinality of 1. Others, such as IF(), have a cardinality |
279 | of N, meaning they can have any number of arguments greater than 0. Others, such |
804bd4ab |
280 | as NOW(), have a cardinality of 0. Several operators with the same meaning may |
ad0f8fa6 |
281 | have a different cardinality in different SQL dialects as different engines may |
804bd4ab |
282 | allow different behaviors. As cardinality may differ between dialects, enforcing |
283 | cardinality is necessarily left to the Visitor. |
ad0f8fa6 |
284 | |
804bd4ab |
285 | Operators also have restrictions on the types of arguments they will accept. The |
286 | first argument may or may not restricted in the same fashion as the other |
287 | arguments. As with cardinality, this restriction will need to be managed by the |
288 | Visitor. |
289 | |
290 | The operator name needs to take into account the possibility that the RDBMS may |
291 | allow UDFs (User-Defined Functions) that have the same name as an operator, such |
292 | as 'AND'. This will have to be managed by the Visitor. |
ad0f8fa6 |
293 | |
d6e108eb |
294 | =head3 Subquery |
295 | |
37f2cc3f |
296 | A Subquery is another AST whose type metadata parameter is set to "SELECT". |
d6e108eb |
297 | |
298 | Most places that a Subquery can be used would require a single value to be |
299 | returned (single column, single row), but that is not something that the AST can |
ad0f8fa6 |
300 | easily enforce. The single-column restriction may possibly be enforced, but the |
d6e108eb |
301 | single-row restriction is much more difficult and, in most cases, probably |
302 | impossible. |
303 | |
7c66a0ab |
304 | Subqueries, when expressed in SQL, must be bounded by parentheses. |
81cd86f1 |
305 | |
662b716d |
306 | =head3 Alias |
307 | |
5ec9ab19 |
308 | An Alias is any place where the construct "X as Y" appears; it is the "AS Y" part. |
662b716d |
309 | |
310 | The hash will be structured as follows: |
311 | |
312 | { |
313 | type => 'Alias', |
314 | value => Expression, |
3004ebb7 |
315 | as => Identifier, |
662b716d |
316 | } |
317 | |
d6e108eb |
318 | =head3 Expression |
319 | |
7c66a0ab |
320 | An Expression can be any one of the following: |
d6e108eb |
321 | |
322 | =over 4 |
323 | |
804bd4ab |
324 | =item * Identifier |
325 | |
10000e9e |
326 | =item * Value |
d6e108eb |
327 | |
804bd4ab |
328 | =item * Operator |
d6e108eb |
329 | |
330 | =item * Subquery |
331 | |
662b716d |
332 | =item * Alias |
333 | |
d6e108eb |
334 | =back |
335 | |
7c66a0ab |
336 | An Expression is a meta-syntactic unit. An "Expression" unit will never appear |
337 | within the AST. It acts as a junction. |
338 | |
4f6e8987 |
339 | =head3 Nesting |
340 | |
3d8ddf0b |
341 | There is no specific operator or nodetype for nesting. Instead, nesting is |
342 | explicitly specified by node descent in the AST. |
4f6e8987 |
343 | |
d6e108eb |
344 | =head2 SQL clauses |
345 | |
10000e9e |
346 | These are all the legal and acceptable clauses within the AST that would |
347 | correpsond to clauses in a SQL statement. Not all clauses are legal within a |
348 | given RDBMS engine's SQL dialect and some clauses may be required in one and |
349 | optional in another. Detecting and enforcing those engine-specific restrictions |
350 | is the responsibility of the Visitor object. |
351 | |
bc06d3c1 |
352 | The following clauses are expected to be handled by Visitors for each statement: |
10000e9e |
353 | |
354 | =over 4 |
355 | |
a08e7c02 |
356 | =item * select |
10000e9e |
357 | |
bc06d3c1 |
358 | =over 4 |
10000e9e |
359 | |
bc06d3c1 |
360 | =item * select |
10000e9e |
361 | |
bc06d3c1 |
362 | =item * tables |
10000e9e |
363 | |
bc06d3c1 |
364 | =item * where |
10000e9e |
365 | |
bc06d3c1 |
366 | =item * orderby |
10000e9e |
367 | |
bc06d3c1 |
368 | =item * groupby |
369 | |
370 | =back |
371 | |
372 | =item * insert |
373 | |
374 | =over 4 |
10000e9e |
375 | |
bc06d3c1 |
376 | =item * tables |
10000e9e |
377 | |
a08e7c02 |
378 | =item * set |
bc06d3c1 |
379 | |
380 | =back |
381 | |
382 | There are RDBMS-specific variations of the INSERT statement, such the one in |
383 | MySQL's |
384 | |
385 | =item * update |
386 | |
387 | =over 4 |
388 | |
389 | =item * tables |
390 | |
391 | =item * set |
392 | |
393 | =item * where |
394 | |
395 | =back |
396 | |
397 | =item * delete |
398 | |
399 | =over 4 |
400 | |
401 | =item * tables |
402 | |
403 | =item * where |
404 | |
405 | =back |
10000e9e |
406 | |
407 | =back |
408 | |
d6e108eb |
409 | The expected clauses are (name and structure): |
410 | |
411 | =head3 select |
412 | |
81cd86f1 |
413 | This corresponds to the SELECT clause of a SELECT statement. |
414 | |
662b716d |
415 | A select clause unit is an array of one or more Expressions. |
d6e108eb |
416 | |
417 | =head3 tables |
418 | |
419 | This is a list of tables that this clause is affecting. It corresponds to the |
81cd86f1 |
420 | FROM clause in a SELECT statement and the INSERT INTO/UPDATE/DELETE clauses in |
37f2cc3f |
421 | those respective statements. Depending on the type metadata entry, the |
81cd86f1 |
422 | appropriate clause name will be used. |
d6e108eb |
423 | |
424 | The tables clause has several RDBMS-specific variations. The AST will support |
425 | all of them and it is up to the Visitor object constructing the actual SQL to |
426 | validate and/or use what is provided as appropriate. |
427 | |
5ec9ab19 |
428 | A tables clause is an Expression that also allows for Joins. |
7c66a0ab |
429 | |
5ec9ab19 |
430 | The hash for an Join within a tables clause will be composed as follows: |
cca4daf5 |
431 | |
7c66a0ab |
432 | { |
5ec9ab19 |
433 | type => 'Join', |
cca4daf5 |
434 | op => '< LEFT|RIGHT|FULL [ OUTER ] > | INNER | CROSS', |
435 | on => Expression, |
a08e7c02 |
436 | args => [ Expression ], |
7c66a0ab |
437 | } |
d6e108eb |
438 | |
cca4daf5 |
439 | A USING clause is syntactic sugar for an ON clause and, as such, is not provided |
da74c1c8 |
440 | for by the AST. A join of a comma is identical to a CROSS JOIN and, as such, is |
441 | not provided for by the AST. The on clause is optional. |
d6e108eb |
442 | |
443 | =head3 where |
444 | |
81cd86f1 |
445 | This corresponds to the WHERE clause in a SELECT, UPDATE, or DELETE statement. |
446 | |
37f2cc3f |
447 | A where clause is composed of an Expression. |
81cd86f1 |
448 | |
d6e108eb |
449 | =head3 set |
450 | |
81cd86f1 |
451 | This corresponds to the SET clause in an INSERT or UPDATE statement. |
452 | |
a08e7c02 |
453 | The hash for an set clause will be composed as follows: |
81cd86f1 |
454 | |
753e226d |
455 | { |
a08e7c02 |
456 | type => 'Set', |
457 | args => [ |
458 | [ Identifier ], |
459 | [ Expresion ], |
460 | ], |
753e226d |
461 | } |
81cd86f1 |
462 | |
a08e7c02 |
463 | The args is an array that is organized as follows: The first element is an array of |
464 | Identifiers for the columns being set. The following arrays are Expressions describing |
465 | the values. The various arrays should be the same length. The array of Identifiers can |
466 | be omitted. |
81cd86f1 |
467 | |
d6e108eb |
468 | =head3 orderby |
469 | |
81cd86f1 |
470 | This corresponds to the ORDER BY clause in a SELECT statement. |
471 | |
da74c1c8 |
472 | A orderby clause unit is an array of one or more OrderbyComponent units. |
81cd86f1 |
473 | |
da74c1c8 |
474 | The hash for a OrderbyComponent unit is composed as follows: |
81cd86f1 |
475 | |
da74c1c8 |
476 | { |
477 | type => 'OrderbyComponent', |
bc06d3c1 |
478 | value => Expression, |
da74c1c8 |
479 | dir => '< ASC | DESC >', |
480 | } |
481 | |
bc06d3c1 |
482 | The value should either be an Identifier or a Number. The dir element, if |
483 | omitted, will be defaulted to ASC by the AST. The number corresponds to a column |
484 | in the select clause. |
81cd86f1 |
485 | |
d6e108eb |
486 | =head3 groupby |
487 | |
81cd86f1 |
488 | This corresponds to the GROUP BY clause in a SELECT statement. |
489 | |
da74c1c8 |
490 | A groupby clause unit is an array of one or more GroupbyComponent units. |
81cd86f1 |
491 | |
da74c1c8 |
492 | The hash for a GroupbyComponent unit is composed as follows: |
493 | |
494 | { |
495 | type => 'GroupbyComponent', |
bc06d3c1 |
496 | value => Expression, |
da74c1c8 |
497 | } |
81cd86f1 |
498 | |
bc06d3c1 |
499 | The value should either be an Identifier or a Number. The number corresponds to |
500 | a column in the select clause. |
501 | |
502 | =head2 Possible RDBMS-specific clauses |
503 | |
504 | The following clauses are provided as examples for RDBMS-specific elements. They |
505 | are B<not> expected to be supported by all Visitors. Visitors may choose whether |
506 | or not to throw on an unexpected clause, though it is strongly recommended. |
81cd86f1 |
507 | |
d6e108eb |
508 | =head3 rows |
509 | |
81cd86f1 |
510 | This corresponds to the clause that is used in some RDBMS engines to limit the |
bc06d3c1 |
511 | number of rows returned by a SELECT statement. In MySQL, this would be the LIMIT |
512 | clause. |
81cd86f1 |
513 | |
e4a310cb |
514 | The hash for a rows clause is composed as follows: |
81cd86f1 |
515 | |
e4a310cb |
516 | { |
e4a310cb |
517 | start => Number, |
518 | count => Number, |
519 | } |
520 | |
521 | The start attribute, if ommitted, will default to 0. The count attribute is |
522 | optional. |
81cd86f1 |
523 | |
d6e108eb |
524 | =head3 for |
525 | |
81cd86f1 |
526 | This corresponds to the clause that is used in some RDBMS engines to indicate |
527 | what locks are to be taken by this SELECT statement. |
528 | |
e4a310cb |
529 | The hash for a for clause is composed as follows: |
81cd86f1 |
530 | |
e4a310cb |
531 | { |
532 | value => '< UPDATE | DELETE >', |
533 | } |
81cd86f1 |
534 | |
cca4daf5 |
535 | =head1 TODO |
536 | |
537 | =over 4 |
538 | |
539 | =item * sproc unit |
540 | |
662b716d |
541 | =item * UNION, UNION ALL, and MINUS |
542 | |
5ec9ab19 |
543 | =item * start the API guidelines |
0f93e5f7 |
544 | |
cca4daf5 |
545 | =back |
546 | |
a08e7c02 |
547 | Convert INSERT and UPDATE into ->populate form. |
548 | |
d6e108eb |
549 | =head1 AUTHORS |
550 | |
81cd86f1 |
551 | robkinyon: Rob Kinyon C<< <rkinyon@cpan.org> >> |
d6e108eb |
552 | |
553 | =head1 LICENSE |
554 | |
555 | You may distribute this code under the same terms as Perl itself. |
556 | |
557 | =cut |