This file contains a BNF definition of ADQL, the Astronomical
Data Query Language. The elements are arranged in alphabetical
order. ADQL is based upon a subset of SQL92 with extensions for
astronomical usage.

The definition represents the equivalent ADQL/s version of ADQL/x v1.0a2
as supported by Astrogrid. This is an evolving document.

The select statement is found at <query_specification>
See SQL92 for a similar page describing SQL92 in full.

  <ADQL-reserved-word> ::=
        TOP
      | ABS 
      | CEILING 
      | DEGREES 
      | EXP 
      | FLOOR 
      | LOG 
      | PI 
      | POWER 
      | RADIANS 
      | SQRT 
      | SQUARE 
      | LOG10 
      | RAND 
      | ROUND 
      | TRUNCATE 
      | SIN 
      | COS 
      | TAN 
      | COT 
      | ASIN 
      | ACOS 
      | ATAN 
      | ATAN2

  <ADQL-special-character> ::=
      <left_brace>
    | <right_brace>
    | <dollar>

  <SQL_embedded_language_character> ::=
      <left_bracket>
    | <right_bracket>

  <SQL_special_character> ::=
     <space>
   | <double_quote>
   | <percent>
   | <ampersand>
   | <quote>
   | <left_paren>
   | <right_paren>
   | <asterisk>
   | <plus_sign>
   | <comma>
   | <minus_sign>
   | <period>
   | <solidus>
   | <colon>
   | <semicolon>
   | <less_than_operator>
   | <equals_operator>
   | <greater_than_operator>
   | <question_mark>
   | <underscore>
   | <vertical_bar>

 <actual_identifier> ::= <regular_identifier> | <delimited_identifier>

 <ampersand> ::= &

  <approximate_numeric_literal> ::= <mantissa>E<exponent>

  <as_clause> ::= [ AS ] <column_name>

 <asterisk> ::= *

 <between_predicate> ::=
     <value_expression> [ NOT ] BETWEEN
     <value_expression> AND <value_expression>

 <boolean_factor> ::= [ NOT ] <boolean_test>

  <boolean_primary> ::=
     | <left_paren> <search_condition> <right_paren> 
       <predicate> 

  <boolean_term> ::=
      <boolean_factor>
    | <boolean_term> AND <boolean_factor>

  <boolean_test> ::= <boolean_primary>

  <character_factor> ::= <character_primary>

  <character_primary> ::= <value_expression_primary>

  <character_representation> ::=
  !! At present this is one ASCII character (but not a single quote).

  <character_string_literal> ::=
     <quote> [ <character_representation>... ] <quote>
     [ { <quote> [ <character_representation>... ] <quote> }... ]

  <character_value_expression> ::= <character_factor>

 <colon> ::= :

 <column_name> ::= <identifier>

 <column_name_list> ::= <column_name> [ { <comma> <column_name> }... ]

  <column_reference> ::= 
     [ <schema_name> <period> ] <table_name> <period> <column_name>
  !! Enforces qualified column names.

 <comma> ::= ,

  <comp_op> ::=
      <equals_operator>
    | <not_equals_operator>
    | <less_than_operator>
    | <greater_than_operator>
    | <less_than_or_equals_operator>
    | <greater_than_or_equals_operator>

  <comparison_predicate> ::=
      <value_expression> <comp_op> <value_expression>

 <correlation_name> ::= <identifier>

  <delimited_identifier> ::=
  !! Begins and ends with a double quote as delimiters
     but contains no double quotes or white space

  <derived_column> ::= <value_expression> [ <as_clause> ]

 <derived_column_list> ::= <column_name_list>

 <digit> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

 <dollar> ::= $

 <double_quote> ::= "

 <equals_operator> ::= =

  <exact_numeric_literal> ::=
      <unsigned_integer> [ <period> [ <unsigned_integer> ] ]
    | <period> <unsigned_integer>

 <exponent> ::= <signed_integer> 

 <factor> ::= [ <sign> ] <numeric_primary> 

  <from_clause> ::= FROM <table_reference>
     [ { <comma> <table_reference> }... ]

  <general_literal> ::= <character_string_literal>

  <general_set_function> ::=
     <set_function_type>
         <left_paren> <value_expression> <right_paren>

 <greater_than_operator> ::= >

 <greater_than_or_equals_operator> ::= >=

  <group_by_clause> ::= GROUP BY <grouping_column_reference_list>

  <grouping_column_reference> ::= <column_reference> 

  <grouping_column_reference_list> ::=
      <grouping_column_reference> [ { <comma> <grouping_column_reference> }... ]

 <having_clause> ::= HAVING <search_condition>	

  <identifier> ::= <actual_identifier>

  <in_predicate> ::=
      <value_expression> [ NOT ] IN <in_predicate_value>

  <in_predicate_value> ::=
     <table_subquery> | <left_paren> <in_value_list> <right_paren>

  <in_value_list> ::=
      <in_value_list_constant> { <comma> <in_value_list_constant> }...

  <in_value_list_constant> ::=
	       [ <plus_sign> | <minus_sign> ] <exact_numeric_literal>
	    |  <character_string_literal> 

  <join_condition> ::= ON <comparison_predicate>

  <join_specification> ::= <join_condition>	

  <join_type> ::=
     INNER
   | <outer_join_type> [ OUTER ]

  <joined_table> ::=
      <qualified_join>

 <left_brace> ::= {

 <left_bracket> ::= [

 <left_paren> ::= (

 <less_than_operator> ::= <

 <less_than_or_equals_operator> ::= <=

  <like_predicate> ::=
      <match_value> [ NOT ] LIKE <pattern>

 <mantissa> ::= <exact_numeric_literal>

 <match_value> ::= <character_value_expression>

  <math_function> ::=
      ABS <left_paren> <numeric_value_expression> <right_paren> 
	  | CEILING <left_paren> <numeric_value_expression> <right_paren> 
	  | DEGREES <left_paren> <numeric_value_expression> <right_paren> 
	  | EXP <left_paren> <numeric_value_expression> <right_paren> 
	  | FLOOR <left_paren> <numeric_value_expression> <right_paren> 
	  | LOG <left_paren> <numeric_value_expression> <right_paren> 
	  | PI <left_paren><right_paren> 
	  | POWER <left_paren> <numeric_value_expression> <comma> <unsigned_integer> <right_paren> 
	  | RADIANS <left_paren> <numeric_value_expression> <right_paren> 
	  | SQUARE <left_paren> <numeric_value_expression> <right_paren> 
	  | SQRT <left_paren> <numeric_value_expression> <right_paren> 
	  | LOG10 <left_paren> <numeric_value_expression> <right_paren> 
	  | RAND <left_paren> [ <numeric_value_expression> ] <right_paren> 
	  | ROUND <left_paren> <numeric_value_expression> <right_paren> 
	  | TRUNCATE <left_paren> <numeric_value_expression> <right_paren> 

 <minus_sign> ::= -

 <not_equals_operator> ::= <not_equals_operator1> | <not_equals_operator2>

 <not_equals_operator1> ::= <>

 <not_equals_operator2> ::= !=

  <numeric_primary> ::=
      <value_expression_primary>
    | <numeric_value_function>

  <numeric_value_expression> ::=
      <term>
    | <numeric_value_expression> <plus_sign> <term>
    | <numeric_value_expression> <minus_sign> <term>

  <numeric_value_function> ::= <trig_function> | <math_function>	

  <order_by_clause> ::= ORDER BY <sort_specification_list>

 <ordering_specification> ::= ASC | DESC

 <outer_join_type> ::= LEFT | RIGHT 

  <pattern> ::= <character_string_literal>

 <percent> ::= %

 <period> ::= .

 <plus_sign> ::= +

  <predicate> ::=
     <comparison_predicate>
   | <between_predicate>
   | <in_predicate>
   | <like_predicate>

  <qualified_join> ::=
      <simple_table_reference> [ <join_type> ] JOIN
      <simple_table_reference> [ <join_specification> ]

  <qualifier> ::= <table_name> 

  <query_specification> ::=
      SELECT [ <set_quantifier> ] [ <set_limit> ] <select_list> <table_expression>

 <question_mark> ::= ?

 <quote> ::= '

  <regular_identifier> ::=
      <simple_Latin_letter>... 
      [ { <digit> | <simple_Latin_letter> | <dollar> | <underscore> }... ]

  <reserved_word> ::=
     ABSOLUTE | ACTION | ADD | ALL
   | ALLOCATE | ALTER | AND
   | ANY | ARE
   | AS | ASC
   | ASSERTION | AT
   | AUTHORIZATION | AVG
   | BEGIN | BETWEEN | BIT | BIT_LENGTH
   | BOTH | BY
   | CASCADE | CASCADED | CASE | CAST
   | CATALOG
   | CHAR | CHARACTER | CHAR_LENGTH
   | CHARACTER_LENGTH | CHECK | CLOSE | COALESCE
   | COLLATE | COLLATION
   | COLUMN | COMMIT
   | CONNECT
   | CONNECTION | CONSTRAINT
   | CONSTRAINTS | CONTINUE
   | CONVERT | CORRESPONDING | COUNT | CREATE | CROSS
   | CURRENT
   | CURRENT_DATE | CURRENT_TIME
   | CURRENT_TIMESTAMP | CURRENT_USER | CURSOR
   | DATE | DAY | DEALLOCATE 
   | DECIMAL | DECLARE | DEFAULT | DEFERRABLE
   | DEFERRED | DELETE | DESC | DESCRIBE | DESCRIPTOR
   | DIAGNOSTICS
   | DISCONNECT | DISTINCT | DOMAIN | DOUBLE | DROP
   | ELSE | END | END-EXEC | ESCAPE
   | EXCEPT | EXCEPTION
   | EXEC | EXECUTE | EXISTS
   | EXTERNAL | EXTRACT
   | FALSE | FETCH | FIRST | FLOAT | FOR
   | FOREIGN | FOUND | FROM | FULL
   | GET | GLOBAL | GO | GOTO
   | GRANT | GROUP
   | HAVING | HOUR
   | IDENTITY | IMMEDIATE | IN | INDICATOR
   | INITIALLY | INNER | INPUT
   | INSENSITIVE | INSERT | INT | INTEGER | INTERSECT
   | INTERVAL | INTO | IS
   | ISOLATION
   | JOIN
   | KEY
   | LANGUAGE | LAST | LEADING | LEFT
   | LEVEL | LIKE | LOCAL | LOWER
   | MATCH | MAX | MIN | MINUTE | MODULE
   | MONTH
   | NAMES | NATIONAL | NATURAL | NCHAR | NEXT | NO
   | NOT | NULL
   | NULLIF | NUMERIC
   | OCTET_LENGTH | OF
   | ON | ONLY | OPEN | OPTION | OR
   | ORDER | OUTER
   | OUTPUT | OVERLAPS
   | PAD | PARTIAL | POSITION | PRECISION | PREPARE
   | PRESERVE | PRIMARY
   | PRIOR | PRIVILEGES | PROCEDURE | PUBLIC
   | READ | REAL | REFERENCES | RELATIVE | RESTRICT
   | REVOKE | RIGHT
   | ROLLBACK | ROWS
   | SCHEMA | SCROLL | SECOND | SECTION
   | SELECT
   | SESSION | SESSION_USER | SET
   | SIZE | SMALLINT | SOME | SPACE | SQL | SQLCODE
   | SQLERROR | SQLSTATE
   | SUBSTRING | SUM | SYSTEM_USER
   | TABLE | TEMPORARY
   | THEN | TIME | TIMESTAMP
   | TIMEZONE_HOUR | TIMEZONE_MINUTE
   | TO | TRAILING | TRANSACTION
   | TRANSLATE | TRANSLATION | TRIM | TRUE
   | UNION | UNIQUE | UNKNOWN | UPDATE | UPPER | USAGE
   | USER | USING
   | VALUE | VALUES | VARCHAR | VARYING | VIEW
   | WHEN | WHENEVER | WHERE | WITH | WORK | WRITE
   | YEAR
   | ZONE

 <right_brace> ::= }

 <right_bracket> ::= ]

 <right_paren> ::= )

    <schema_name> ::= <identifier>

  <search_condition> ::=
      <boolean_term>
    | <search_condition> OR <boolean_term>

  <select_list> ::=
      <asterisk>
    | <select_sublist> [ { <comma> <select_sublist> }... ]

  <select_sublist> ::=
      <derived_column>

 <semicolon> ::= ;

  <set_function_specification> ::=
      COUNT <left_paren> <asterisk> <right_paren>
    | <general_set_function>

 <set_function_type> ::= AVG | MAX | MIN | SUM | COUNT

  <set_limit> ::= TOP <unsigned_integer>

 <set_quantifier> ::= DISTINCT | ALL

 <sign> ::= <plus_sign> | <minus_sign>

 <signed_integer> ::= [ <sign> ] <unsigned_integer>

  <simple_Latin_letter> ::=
      <simple_Latin_upper_case_letter>
    | <simple_Latin_lower_case_letter>

  <simple_Latin_lower_case_letter> ::=
      a | b | c | d | e | f | g | h | i | j | k | l | m | n | o
    | p | q | r | s | t | u | v | w | x | y | z

  <simple_Latin_upper_case_letter> ::=
      A | B | C | D | E | F | G | H | I | J | K | L | M | N | O
    | P | Q | R | S | T | U | V | W | X | Y | Z

  <simple_table_reference> ::=
      [ <schema_name> <period> ] <table_name> [ [ AS ] <correlation_name> ] 

 <solidus> ::= /

  <sort_key> ::= <value_expression>

  <sort_specification> ::=
      <sort_key> [ <ordering_specification> ]e>

  <sort_specification_list> ::=
      <sort_specification> [ { <comma> <sort_specification> }... ]

  <space> ::=
  !! Imagine there is a space character here

  <string_value_expression> ::=
      <character_value_expression>

  <table_expression> ::=
      <from_clause>
      [ <where_clause> ]
      [ <group_by_clause> ]
      [ <having_clause> ]
      [ <order_by_clause> ]

  <table_name> ::=
      <identifier>

  <table_reference> ::=
      <simple_table_reference>
    | <joined_table> 

  <table_subquery> ::= 
      <left_paren> <query_specification> <right_paren>

  <term> ::=
      <factor>
    | <term> <asterisk> <factor>
    | <term> <solidus> <factor>

  <trig_function> ::=
      ACOS <left_paren> <numeric_value_expression> <right_paren>
    | ASIN <left_paren> <numeric_value_expression> <right_paren>
    | ATAN <left_paren> <numeric_value_expression> <right_paren>
    | ATAN2 <left_paren> <numeric_value_expression> <comma> <numeric_value_expression> <right_paren>
    | COS <left_paren> <numeric_value_expression> <right_paren>
    | COT <left_paren> <numeric_value_expression> <right_paren>
    | SIN <left_paren> <numeric_value_expression> <right_paren>
    | TAN <left_paren> <numeric_value_expression> <right_paren>L

 <underscore> ::= _

 <unsigned_integer> ::= <digit>...

 <unsigned_literal> ::= <unsigned_numeric_literal> | <general_literal>

  <unsigned_numeric_literal> ::=
     <exact_numeric_literal>
     |
     <approximate_numeric_literal>

  <unsigned_value_specification> ::=
      <unsigned_literal>

  <value_expression> ::=
	    <numeric_value_expression>
    | <string_value_expression>

  <value_expression_primary> ::=
      <unsigned_value_specification>
    | <column_reference>
    | <set_function_specification>
    | <left_paren> <value_expression> <right_paren>

 <vertical_bar> ::= |

 <where_clause> ::= WHERE <search_condition>