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 | |
393a4eb8 |
81 | =head1 COMPONENTS |
82 | |
83 | There are two major components to SQL::Abstract v2. |
84 | |
85 | =over 4 |
86 | |
87 | =item * AST |
88 | |
89 | This is the Abstract Syntax Tree. It is a data structure that represents |
90 | everything necessary to construct the SQL statement in whatever dialect the |
91 | user requires. |
92 | |
93 | =item * Visitor |
94 | |
95 | This object conforms to the Visitor pattern and is used to generate the SQL |
96 | represented by the AST. Each dialect will have a different Visitor object. In |
97 | addition, there will be visitors for at least one of the ANSI specifications. |
98 | |
99 | =back |
d6e108eb |
100 | |
df35a525 |
101 | The division of duties between the two components will focus on what the AST |
102 | can and cannot assume. For example, identifiers do not have 20 components in |
103 | any dialect, so the AST can validate that. However, determining what |
104 | constitutes a legal identifier can only be determined by the Visitor object |
105 | enforcing that dialect's rules. |
106 | |
d6e108eb |
107 | =head1 AST STRUCTURE |
108 | |
393a4eb8 |
109 | The AST will be a HoHo..oH (hash of hash of ... of hashes). The keys to the |
110 | outermost hash will be the various clauses of a SQL statement, plus some |
111 | metadata keys. All metadata keys will be identifiable as such by being prefixed |
112 | with an underscore. All keys will be in lowercase. |
d6e108eb |
113 | |
114 | =head2 Metadata keys |
115 | |
116 | These are the additional metadata keys that the AST provides for. |
117 | |
df35a525 |
118 | =head3 _query |
119 | |
120 | This denotes what kind of query this AST should be interpreted as. Different |
121 | Visitors may accept additional values for _query. For example, a MySQL Visitor |
7c66a0ab |
122 | may choose to accept 'replace' for REPLACE INTO. If a _query value is |
123 | unrecognized by the Visitor, the Visitor is expected to throw an error. |
df35a525 |
124 | |
125 | All Visitors are expected to handle the following values for _query: |
126 | |
d6e108eb |
127 | =over 4 |
128 | |
df35a525 |
129 | =item * select |
130 | |
131 | This is a SELECT statement. |
d6e108eb |
132 | |
df35a525 |
133 | =item * insert |
d6e108eb |
134 | |
df35a525 |
135 | This is an INSERT statement. |
393a4eb8 |
136 | |
df35a525 |
137 | =item * update |
138 | |
139 | This is an UPDATE statement. |
140 | |
141 | =item * delete |
142 | |
143 | This is a DELETE statement. |
d6e108eb |
144 | |
145 | =back |
146 | |
df35a525 |
147 | =head3 _version |
148 | |
149 | This denotes the version of the AST. Different versions will indicate different |
150 | capabilities provided. Visitors will choose to respect the _version as needed |
151 | and desired. |
152 | |
d6e108eb |
153 | =head2 Structural units |
154 | |
df35a525 |
155 | All structural units will be hashes. These hashes will have, at minimum, the |
156 | following keys: |
157 | |
158 | =over 4 |
159 | |
7c66a0ab |
160 | =item * name |
df35a525 |
161 | |
162 | This indicates the structural unit that this hash is representing. While this |
163 | specification provides for standard structural units, different Visitors may |
164 | choose to accept additional units as desired. If a Visitor encounters a unit it |
165 | doesn't know how to handle, it is expected to throw an exception. |
166 | |
167 | =back |
168 | |
d6e108eb |
169 | Structural units in the AST are supported by loaded components. L<SQL::Abstract> |
170 | provides for the following structural units by default: |
171 | |
172 | =head3 Identifier |
173 | |
df35a525 |
174 | This is a (potentially) fully canonicalized identifier for a elemnt in the |
175 | query. This element could be a schema, table, or column. The Visitor will |
176 | determine validity within the context of that SQL dialect. The AST is only |
177 | responsible for validating that the elements are non-empty Strings. |
178 | |
179 | The hash will be structured as follows: |
180 | |
181 | { |
7c66a0ab |
182 | name => 'Identifier', |
183 | element1 => Scalar, |
184 | element2 => Scalar, |
185 | element3 => Scalar, |
df35a525 |
186 | } |
d6e108eb |
187 | |
7c66a0ab |
188 | If element3 exists, then element2 must exist. element1 must always exist. If a |
189 | given element exists, then it must be defined and of non-zero length. |
190 | |
ad0f8fa6 |
191 | Visitors are expected to, by default, quote all identifiers according to the SQL |
192 | dialect's quoting scheme. |
d6e108eb |
193 | |
10000e9e |
194 | =head3 Value |
d6e108eb |
195 | |
7c66a0ab |
196 | A Value is a Perl scalar. Depending on the type, a Visitor may be able to make |
197 | certain decisions. |
10000e9e |
198 | |
199 | =over 4 |
200 | |
201 | =item * String |
202 | |
7c66a0ab |
203 | A String is a quoted series of characters. The Visitor is expected to ensure |
204 | that embedded quotes are properly handled per the SQL dialect's quoting scheme. |
10000e9e |
205 | |
206 | =item * Number |
207 | |
7c66a0ab |
208 | A Number is an unquoted number in some numeric format. |
10000e9e |
209 | |
ad0f8fa6 |
210 | =item * Null |
10000e9e |
211 | |
ad0f8fa6 |
212 | Null is SQL's NULL and corresponds to Perl's C<undef>. |
10000e9e |
213 | |
214 | =item * BindParameter |
215 | |
216 | This corresponds to a value that will be passed in. This value is normally |
217 | quoted in such a fashion so as to protect against SQL injection attacks. (q.v. |
218 | L<DBI/quote()> for an example.) |
219 | |
7c66a0ab |
220 | BindParameters are normally represented by a '?'. |
221 | |
10000e9e |
222 | =back |
223 | |
a3872878 |
224 | The hash will be structured as follows: |
225 | |
226 | { |
7c66a0ab |
227 | name => 'Value' |
228 | subtype => [ 'String' | 'Number' | 'Null' | 'BindParameter' ] |
229 | value => Scalar |
a3872878 |
230 | } |
231 | |
232 | The provided subtypes are the ones that all Visitors are expected to support. |
233 | Visitors may choose to support additional subtypes. Visitors are expected to |
234 | throw an exception upon encountering an unknown subtype. |
d6e108eb |
235 | |
236 | =head3 Function |
237 | |
7c66a0ab |
238 | A Function is anything of the form C<< name( arglist ) >> where C<<name>> is a |
239 | string and C<arglist> is an ExpressionList. |
d6e108eb |
240 | |
81cd86f1 |
241 | Yes, a Subquery is legal as an argument for many functions. Some example |
242 | functions are: |
243 | |
244 | =over 4 |
245 | |
81cd86f1 |
246 | =item * C<< MAX >> |
247 | |
248 | =item * C<< MIN >> |
249 | |
250 | =item * C<< SUM >> |
251 | |
ad0f8fa6 |
252 | =item * C<< IF >> |
253 | |
81cd86f1 |
254 | =back |
d6e108eb |
255 | |
7c66a0ab |
256 | The hash will be structured as follows: |
257 | |
258 | { |
259 | name => "Function", |
260 | function => String, |
261 | arglist => ExpressionList, |
262 | } |
263 | |
ad0f8fa6 |
264 | Functions have a cardinality, or expected number of arguments. Some functions, |
265 | such as MAX(), have a cardinality of 1. Others, such as IF(), have a cardinality |
266 | of N, meaning they can have any number of arguments greater than 0. Others, such |
267 | as NOW(), have a cardinality of 0. Several functions with the same meaning may |
268 | have a different cardinality in different SQL dialects as different engines may |
269 | allow different behaviors. |
270 | |
271 | As cardinality may differ between dialects, enforcing cardinality is necessarily |
272 | left to the Visitor. |
273 | |
d6e108eb |
274 | =head3 Subquery |
275 | |
276 | A Subquery is another AST whose _query metadata parameter is set to "SELECT". |
277 | |
278 | Most places that a Subquery can be used would require a single value to be |
279 | returned (single column, single row), but that is not something that the AST can |
ad0f8fa6 |
280 | easily enforce. The single-column restriction may possibly be enforced, but the |
d6e108eb |
281 | single-row restriction is much more difficult and, in most cases, probably |
282 | impossible. |
283 | |
7c66a0ab |
284 | Subqueries, when expressed in SQL, must be bounded by parentheses. |
81cd86f1 |
285 | |
d6e108eb |
286 | =head3 Unary Operator |
287 | |
ad0f8fa6 |
288 | A UnaryOperator takes a single argument on the RHS. The argument for a |
289 | UnaryOperator is an Expression. |
290 | |
291 | Visitors are expected to support, at minimum, the following operators: |
d6e108eb |
292 | |
293 | =over 4 |
294 | |
ad0f8fa6 |
295 | =item * NOT X |
296 | |
297 | =item * ANY X |
298 | |
299 | =item * ALL X |
300 | |
301 | =item * SOME X |
d6e108eb |
302 | |
303 | =back |
304 | |
ad0f8fa6 |
305 | The hash for a UnaryOperator is as follows: |
306 | |
307 | { |
7c66a0ab |
308 | name => 'UnaryOperator' |
309 | operator => [ .... ], |
ad0f8fa6 |
310 | argument1 => Expression, |
311 | } |
312 | |
313 | Visitors may choose to support additional operators. Visitors are expected to |
314 | throw an exception upon encountering an unknown operator. |
315 | |
d6e108eb |
316 | =head3 BinaryOperator |
317 | |
ad0f8fa6 |
318 | A BinaryOperator takes two arguments (one on the LHS and one on the RHS). The |
319 | arguments for a BinaryOperator are all Expressions. |
a3872878 |
320 | |
ad0f8fa6 |
321 | Visitors are expected to support, at minimum, the following operators: |
d6e108eb |
322 | |
323 | =over 4 |
324 | |
a3872878 |
325 | =item * X = Y |
326 | |
327 | =item * X != Y |
d6e108eb |
328 | |
a3872878 |
329 | =item * X > Y |
d6e108eb |
330 | |
a3872878 |
331 | =item * X < Y |
d6e108eb |
332 | |
a3872878 |
333 | =item * X >= Y |
d6e108eb |
334 | |
a3872878 |
335 | =item * X <= Y |
d6e108eb |
336 | |
a3872878 |
337 | =item * X IS Y |
d6e108eb |
338 | |
a3872878 |
339 | =item * X IN Y |
d6e108eb |
340 | |
ad0f8fa6 |
341 | =item * X NOT IN Y |
342 | |
343 | =item * X AND Y |
344 | |
345 | =item * X OR Y |
346 | |
d6e108eb |
347 | =back |
348 | |
ad0f8fa6 |
349 | (Note that an operator can comprise of what would be multiple tokens in a normal |
350 | parsing effort.) |
351 | |
352 | Visitors may choose to support additional operators. Visitors are expected to |
353 | throw an exception upon encountering an unknown operator. |
354 | |
355 | The hash for a BinaryOperator is as follows: |
356 | |
357 | { |
7c66a0ab |
358 | name => 'BinaryOperator' |
359 | operator => [ .... ], |
ad0f8fa6 |
360 | argument1 => Expression, |
361 | argument2 => Expression, |
362 | } |
d6e108eb |
363 | |
a3872878 |
364 | =head3 TrinaryOperator |
365 | |
366 | A TrinaryOperator takes three arguments. It generally is composed of two |
367 | elements with one argument to the LHS, one to the RHS, and a third in the middle |
ad0f8fa6 |
368 | of the elements. The arguments for a TrinaryOperator are all Expressions. |
a3872878 |
369 | |
ad0f8fa6 |
370 | Visitors are expected to support, at minimum, the following operators: |
a3872878 |
371 | |
372 | =over 4 |
373 | |
374 | =item * X BETWEEN Y AND Z |
375 | |
376 | =back |
377 | |
ad0f8fa6 |
378 | Visitors may choose to support additional operators. Visitors are expected to |
379 | throw an exception upon encountering an unknown operator. |
380 | |
381 | The hash for a TrinaryOperator is as follows: |
382 | |
383 | { |
7c66a0ab |
384 | name => 'TrinaryOperator' |
385 | operator => [ .... ], |
ad0f8fa6 |
386 | argument1 => Expression, |
387 | argument2 => Expression, |
388 | argument3 => Expression, |
389 | } |
390 | |
d6e108eb |
391 | =head3 Expression |
392 | |
7c66a0ab |
393 | An Expression can be any one of the following: |
d6e108eb |
394 | |
395 | =over 4 |
396 | |
10000e9e |
397 | =item * Value |
d6e108eb |
398 | |
399 | =item * Function |
400 | |
401 | =item * Subquery |
402 | |
ad0f8fa6 |
403 | =item * UnaryOperator |
d6e108eb |
404 | |
ad0f8fa6 |
405 | =item * BinaryOperator |
406 | |
407 | =item * TrinaryOperator |
d6e108eb |
408 | |
409 | =back |
410 | |
7c66a0ab |
411 | An Expression is a meta-syntactic unit. An "Expression" unit will never appear |
412 | within the AST. It acts as a junction. |
413 | |
414 | =head3 ExpressionList |
415 | |
416 | An ExpressionList is a list of Expressions, generally separated by commas |
417 | (though other separators may be appropriate at times or for different SQL |
418 | dialects). |
81cd86f1 |
419 | |
7c66a0ab |
420 | The hash for an ExpressionList is as follows: |
ad0f8fa6 |
421 | |
422 | { |
7c66a0ab |
423 | name => 'ExpressionList', |
424 | separator => ',', |
425 | elements => Array of Expressions, |
ad0f8fa6 |
426 | } |
427 | |
7c66a0ab |
428 | An ExpressionList is always rendered in SQL with parentheses around it. |
429 | |
d6e108eb |
430 | =head2 SQL clauses |
431 | |
10000e9e |
432 | These are all the legal and acceptable clauses within the AST that would |
433 | correpsond to clauses in a SQL statement. Not all clauses are legal within a |
434 | given RDBMS engine's SQL dialect and some clauses may be required in one and |
435 | optional in another. Detecting and enforcing those engine-specific restrictions |
436 | is the responsibility of the Visitor object. |
437 | |
438 | The clauses are defined with a yacc-like syntax. The various parts are: |
439 | |
440 | =over 4 |
441 | |
442 | =item * := |
443 | |
444 | This means "defined" and is used to create a new term to be used below. |
445 | |
446 | =item * [] |
447 | |
448 | This means optional and indicates that the items within it are optional. |
449 | |
450 | =item * []* |
451 | |
452 | This means optional and repeating as many times as desired. |
453 | |
454 | =item * | |
455 | |
456 | This means alternation. It is a binary operator and indicates that either the |
457 | left or right hand sides may be used, but not both. |
458 | |
459 | =item * C<< <> >> |
460 | |
461 | This is a grouping construct. It means that all elements within this construct |
462 | are treated together for the purposes of optional, repeating, alternation, etc. |
463 | |
464 | =back |
465 | |
d6e108eb |
466 | The expected clauses are (name and structure): |
467 | |
468 | =head3 select |
469 | |
81cd86f1 |
470 | This corresponds to the SELECT clause of a SELECT statement. |
471 | |
7c66a0ab |
472 | A select clause unit is an array of one or more SelectComponent units. |
81cd86f1 |
473 | |
7c66a0ab |
474 | The hash for a SelectComponent unit is composed as follows: |
81cd86f1 |
475 | |
7c66a0ab |
476 | { |
477 | name => 'SelectComponent', |
478 | value => Expression, |
479 | [ as => Identifier, ] |
480 | } |
481 | |
482 | The 'as' component is optional. Visitors may choose to make it required in |
483 | certain situations. |
d6e108eb |
484 | |
485 | =head3 tables |
486 | |
487 | This is a list of tables that this clause is affecting. It corresponds to the |
81cd86f1 |
488 | FROM clause in a SELECT statement and the INSERT INTO/UPDATE/DELETE clauses in |
489 | those respective statements. Depending on the _query metadata entry, the |
490 | appropriate clause name will be used. |
d6e108eb |
491 | |
7c66a0ab |
492 | A tables clause unit is an array of one or more TableComponent units. |
493 | |
d6e108eb |
494 | The tables clause has several RDBMS-specific variations. The AST will support |
495 | all of them and it is up to the Visitor object constructing the actual SQL to |
496 | validate and/or use what is provided as appropriate. |
497 | |
7c66a0ab |
498 | The hash for a TableJoin will be composed as follows: |
499 | |
500 | # TableJoin |
501 | { |
502 | name => 'TableJoin', |
503 | join => < LEFT|RIGHT [ OUTER ] > | INNER | CROSS | ',', |
504 | [ using => IdentifierList, ] |
505 | [ on => ExpressionList, ] |
506 | } |
507 | |
508 | A TableJoin may not have both a 'using' element and an 'on' element. It may |
509 | have one of them if the 'join' element is not equal to ',' but doesn't have to. |
510 | If the 'join' element is equal to ',', then it may not have either a 'using' or |
511 | an 'on' element. |
512 | |
513 | The hash for a TableIdentifier will be composed as follows: |
d6e108eb |
514 | |
7c66a0ab |
515 | # TableIdentifier |
516 | { |
517 | name => 'TableIdentifier', |
518 | value => Identifier | SubQuery |
519 | [ join => TableJoin, ] |
520 | [ as => Identifier, ] |
521 | } |
522 | |
523 | The first TableComponent in a tables clause may not have a join element. All |
524 | other TableComponent elements that do not have a join element will have a |
525 | default join element of: |
526 | |
527 | { |
528 | name => 'TableJoin', |
529 | join => ',', |
530 | } |
d6e108eb |
531 | |
7c66a0ab |
532 | The 'as' component is optional. Visitors may choose to make it required in |
533 | certain situations (such as MySQL requiring an alias for subqueries). |
d6e108eb |
534 | |
535 | Additionally, where aliases are provided for in the TableIdentifier, those |
536 | aliases must be used as the tablename in subsequent Identifiers that identify a |
7c66a0ab |
537 | column of that table. This may be enforceable by the AST or the Visitor. But, it |
538 | is more likely that it will not be. |
d6e108eb |
539 | |
540 | =head3 where |
541 | |
81cd86f1 |
542 | This corresponds to the WHERE clause in a SELECT, UPDATE, or DELETE statement. |
543 | |
544 | A where clause is composed as follows: |
545 | |
546 | WhereOperator := AND | OR |
547 | WhereExpression := Expression | Expression WhereOperator Expression |
548 | |
549 | WhereExpression |
550 | |
d6e108eb |
551 | =head3 set |
552 | |
81cd86f1 |
553 | This corresponds to the SET clause in an INSERT or UPDATE statement. |
554 | |
555 | A set clause is composed as follows: |
556 | |
557 | SetComponent := Identifier = Expression |
558 | |
559 | SetComponent [ , SetComponent ]* |
560 | |
561 | =head3 columns |
562 | |
563 | This corresponds to the optional list of columns in an INSERT statement. |
564 | |
7c66a0ab |
565 | A columns clause is an IdentifierList and the unit is composed as follows: |
81cd86f1 |
566 | |
7c66a0ab |
567 | columns => [ |
568 | Identifier, |
569 | [ Identifier, ]* |
570 | ], |
81cd86f1 |
571 | |
d6e108eb |
572 | =head3 values |
573 | |
81cd86f1 |
574 | This corresponds to the VALUES clause in an INSERT statement. |
575 | |
7c66a0ab |
576 | A values clause is an ExpressionList and the unit is composed as follows. |
81cd86f1 |
577 | |
7c66a0ab |
578 | values => [ |
579 | Expression, |
580 | [ Expression, ]* |
581 | ], |
81cd86f1 |
582 | |
583 | If there is a columns clause, the number of entries in the values clause must be |
584 | equal to the number of entries in the columns clause. |
585 | |
d6e108eb |
586 | =head3 orderby |
587 | |
81cd86f1 |
588 | This corresponds to the ORDER BY clause in a SELECT statement. |
589 | |
590 | An orderby clause is composed as follows: |
591 | |
10000e9e |
592 | OrderByComponent := XXX-TODO-XXX |
81cd86f1 |
593 | OrderByDirection := ASC | DESC |
594 | |
595 | OrderByComponent [ OrderByDirection ] |
596 | [ , OrderByComponent [ OrderByDirection ] ]* |
597 | |
d6e108eb |
598 | =head3 groupby |
599 | |
81cd86f1 |
600 | This corresponds to the GROUP BY clause in a SELECT statement. |
601 | |
602 | An groupby clause is composed as follows: |
603 | |
10000e9e |
604 | GroupByComponent := XXX-TODO-XXX |
81cd86f1 |
605 | |
606 | GroupByComponent [ , GroupByComponent ]* |
607 | |
d6e108eb |
608 | =head3 rows |
609 | |
81cd86f1 |
610 | This corresponds to the clause that is used in some RDBMS engines to limit the |
611 | number of rows returned by a query. In MySQL, this would be the LIMIT clause. |
612 | |
613 | A rows clause is composed as follows: |
614 | |
615 | Number [, Number ] |
616 | |
d6e108eb |
617 | =head3 for |
618 | |
81cd86f1 |
619 | This corresponds to the clause that is used in some RDBMS engines to indicate |
620 | what locks are to be taken by this SELECT statement. |
621 | |
622 | A for clause is composed as follows: |
623 | |
624 | UPDATE | DELETE |
625 | |
626 | =head3 connectby |
627 | |
628 | This corresponds to the clause that is used in some RDBMS engines to provide for |
629 | an adjacency-list query. |
630 | |
631 | A connectby clause is composed as follows: |
632 | |
633 | Identifier, WhereExpression |
634 | |
7c66a0ab |
635 | =head1 EXAMPLES |
636 | |
637 | The following are example SQL statements and a possible AST for each one. |
638 | |
639 | =over 4 |
640 | |
641 | =item * SELECT 1 |
642 | |
643 | { |
644 | _query => 'select', |
645 | _ast_version => 0.0001, |
646 | select => [ |
647 | { |
648 | name => 'SelectComponent', |
649 | value => { |
650 | name => 'Value', |
651 | subtype => 'number', |
652 | value => 1, |
653 | }, |
654 | }, |
655 | ], |
656 | } |
657 | |
658 | =item * SELECT NOW() AS time FROM dual AS duality |
659 | |
660 | { |
661 | _query => 'select', |
662 | _ast_version => 0.0001, |
663 | select => [ |
664 | { |
665 | name => 'SelectComponent', |
666 | value => { |
667 | name => 'Function', |
668 | function => 'NOW', |
669 | }, |
670 | as => { |
671 | name => 'Identifier', |
672 | element1 => 'time', |
673 | }, |
674 | }, |
675 | ], |
676 | tables => [ |
677 | { |
678 | name => 'TablesComponent', |
679 | value => { |
680 | name => 'Identifier', |
681 | element1 => 'dual', |
682 | }, |
683 | as => { |
684 | name => 'Identifier', |
685 | element1 => 'duality', |
686 | }, |
687 | }, |
688 | ], |
689 | } |
690 | |
691 | =back |
692 | |
d6e108eb |
693 | =head1 AUTHORS |
694 | |
81cd86f1 |
695 | robkinyon: Rob Kinyon C<< <rkinyon@cpan.org> >> |
d6e108eb |
696 | |
697 | =head1 LICENSE |
698 | |
699 | You may distribute this code under the same terms as Perl itself. |
700 | |
701 | =cut |