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 reflects the ADQL spec version v2.0
The select statement is found at <query_specification>
For region and associated constructs, see...
<geometry_value_expression>,
<numeric_geometry_function>,
<string_geometry_function>
User defined function is found at <user_defined_function>
See SQL92 for a similar page describing SQL92 in full.
  <ADQL_language_character> ::=
      <simple_Latin_letter>
    | <digit>
    | <SQL_special_character>
  <ADQL_reserved_word> ::=
      ABS 
    | ACOS 
    | AREA    
    | ASIN 
    | ATAN 
    | ATAN2 
    | BOX
    | CEILING 
    | CENTROID
    | CIRCLE
    | CONTAINS
    | COORD1
    | COORD2
    | COORDSYS
    | COS 
    | DEGREES 
    | DISTANCE
    | EXP 
    | FLOOR 
    | INTERSECTS
    | LOG 
    | LOG10 
    | MOD 
    | PI 
    | POINT
    | POLYGON
    | POWER 
    | RADIANS 
    | REGION 
    | RAND 
    | ROUND 
    | SIN 
    | SQRT 
    | TOP
    | TAN 
    | TRUNCATE
  <SQL_embedded_language_character> ::=
      <left_bracket>
    | <right_bracket>
  <SQL_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
  <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>
  <ampersand> ::= &
  <approximate_numeric_literal> ::= <mantissa>E<exponent>
  <area> ::= AREA <left_paren> <geometry_value_expression> <right_paren>
  <as_clause> ::= [ AS ] <column_name>
  <asterisk> ::= *
  <between_predicate> ::=
     <value_expression> [ NOT ] BETWEEN
     <value_expression> AND <value_expression>
  <boolean_factor> ::= [ NOT ] <boolean_primary>
  <boolean_primary> ::=
     | <left_paren> <search_condition> <right_paren> 
       <predicate> 
  <boolean_term> ::=
      <boolean_factor>
    | <boolean_term> AND <boolean_factor>
  <box> ::= 
      BOX <left_paren> <coord_sys>
                     <comma> <coordinates> 
                     <comma> <numeric_value_expression> 
                     <comma> <numeric_value_expression> 
                <right_paren>
  <catalog_name> ::= <identifier>
  <centroid> ::= CENTROID <left_paren> <geometry_value_expression> <right_paren>
  <character_factor> ::= <character_primary>
  !! For information only, SQL92 supports <collate_clause>
  <character_primary> ::= 
      <value_expression_primary>
    | <string_value_function>
  <character_representation> ::= <nonquote_character> | <quote_symbol>
  !! A way of allowing a single quote to be escaped by a single quote.
  <character_string_literal> ::=
     <quote> [ <character_representation>... ] <quote>
     [ { <separator>... <quote> [ <character_representation>... ] <quote> }... ]
  <character_value_expression> ::= <concatenation> | <character_factor>
  <circle> ::= 
      CIRCLE <left_paren> <coord_sys> 
                  <comma> <coordinates> 
                  <comma> <radius> 
             <right_paren>
  <colon> ::= :
  <column_name> ::= <identifier>
  <column_name_list> ::= <column_name> [ { <comma> <column_name> }... ]
  <column_reference> ::= [ <qualifier> <period> ] <column_name>
  <comma> ::= ,
  <comment> ::= <comment_introducer> [ <comment_character>... ] <newline>
  <comment_character> ::= <nonquote_character> | <quote>
  <comment_introducer> ::= <minus_sign><minus_sign> [<minus_sign>...]
  <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>
  <concatenation> ::= <character_value_expression> <concatenation_operator> <character_factor>
  <concatenation_operator> ::= ||
  <contains> ::= CONTAINS <left_paren> <geometry_value_expression> <comma> <geometry_value_expression> <right_paren>  
  <coord1> ::= COORD1 <left_paren> <coord_value> <right_paren>
  <coord2> ::= COORD2 <left_paren> <coord_value> <right_paren>
  <coord_sys> ::= <string_value_expression>
  <coord_value> ::= <point> | <column_reference>
  <coordinate1> ::= <numeric_value_expression>
  <coordinate2> ::= <numeric_value_expression>
  <coordinates> ::=  <coordinate1>  <comma>  <coordinate2> 
  <correlation_name> ::= <identifier>
  <correlation_specification> ::= [ AS ] <correlation_name>
  <default_function_prefix> ::=
   !! The prefix is set by default to "udf_".
   !! It should be possible to change the default prefix to accommodate local preferences.
  <delimited_identifier> ::= <double_quote> <delimited_identifier_body> <double_quote>
  !! These diagrams are somewhat difficult to follow through and understand immediately. 
  !! The idea is to allow any identifier to be quoted by enclosing within double quotes.
  !! This can allow the use of reserved words as identifiers, eg: "DATE" as a column name.  
  !! The identifier can also contain double quotes as long as they are escaped by double quotes. 
  !! For example: "Table""X" will be identifier Table"X
  <delimited_identifier_body> ::= <delimited_identifier_part>...
  <delimited_identifier_part> ::= <nondoublequote_character> | <double_quote_symbol>
  <delimiter_token> ::=
        <character_string_literal>
    |   <delimited_identifier>
    |   <SQL_special_character>
    |   <not_equals_operator>
    |   <greater_than_or_equals_operator>
    |   <less_than_or_equals_operator>
    |   <concatenation_operator>
    |   <double_period>
    |   <left_bracket>
    |   <right_bracket>
  <derived_column> ::= <value_expression> [ <as_clause> ]
  <derived_table> ::= <table_subquery>
  <digit> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
  <distance> ::=     
     DISTANCE <left_paren> <coord_value> <comma> <coord_value> <right_paren>
  <double_period> ::= ..
  <double_quote> ::= "
  <double_quote_symbol> ::= <double_quote><double_quote>
  <equals_operator> ::= =
  <exact_numeric_literal> ::=
      <unsigned_integer> [ <period> [ <unsigned_integer> ] ]
    | <period> <unsigned_integer>
  <exists_predicate> ::= EXISTS <table_subquery>
  <exponent> ::= <signed_integer> 
  <extract_coordsys> ::= COORDSYS <left_paren> <geometry_value_expression> <right_paren>
  <factor> ::= [ <sign> ] <numeric_primary> 
  <from_clause> ::= FROM <table_reference>
     [ { <comma> <table_reference> }... ]
  <general_literal> ::= <character_string_literal>
  !! ADQL Note:
  !! For information, SQL92 has <general_literal>, and also supports
  !! <national_character_string_literal>, <bit_string_literal>, 
  !! <hex_string_literal>, <datetime_literal> and <interval_literal>
  !! Good to retain this as a place-holder, bearing in mind
  !! that we might need <bit_string_literal> and <hex_string_literal>
  !! at some point in the future?
  <general_set_function> ::=
     <set_function_type> <left_paren> [ <set_quantifier> ] <value_expression> <right_paren>
  <geometry_value_expression> ::= <value_expression_primary> | <geometry_value_function>
  <geometry_value_function> ::=
       <box> 
     | <centroid> 
     | <circle> 
     | <point> 
     | <polygon> 
     | <region> 
  <greater_than_operator> ::= >
  <greater_than_or_equals_operator> ::= >=
  <group_by_clause> ::= GROUP BY <grouping_column_reference_list>
  <grouping_column_reference> ::= <column_reference> 
  !! For information, SQL92 supports a <collate_clause>
  <grouping_column_reference_list> ::=
      <grouping_column_reference> [ { <comma> <grouping_column_reference> }... ]
  <having_clause> ::= HAVING <search_condition>	
  <identifier> ::= <regular_identifier> | <delimited_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> ::=
      <value_expression> { <comma> <value_expression> } ...
  <intersects> ::= INTERSECTS <left_paren> <geometry_value_expression> <comma> <geometry_value_expression> <right_paren>
  <join_column_list> ::= <column_name_list>
  <join_condition> ::= ON <search_condition>
  <join_specification> ::= <join_condition> | <named_columns_join>	
  <join_type> ::=
     INNER
   | <outer_join_type> [ OUTER ]
  !! For information, SQL92 also supports UNION
  <joined_table> ::=
      <qualified_join>
    | <left_paren> <joined_table> <right_paren>
  <keyword> ::= <SQL_reserved_word> | <ADQL_reserved_word>
  <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> 
	  | LOG10 <left_paren> <numeric_value_expression> <right_paren> 	  
	  | MOD <left_paren> <numeric_value_expression> <comma> <numeric_value_expression> <right_paren> 	  
	  | PI <left_paren><right_paren> 
	  | POWER <left_paren> <numeric_value_expression> <comma> <numeric_value_expression> <right_paren> 
	  | RADIANS <left_paren> <numeric_value_expression> <right_paren> 
	  | RAND <left_paren> [ <numeric_value_expression> ] <right_paren> 
	  | ROUND <left_paren> <numeric_value_expression> [<comma> <signed_integer>] <right_paren> 
	  | SQRT <left_paren> <numeric_value_expression> <right_paren> 
	  | TRUNCATE <left_paren> <numeric_value_expression> [<comma> <signed_integer>] <right_paren> 
  <minor_radius> ::= <numeric_value_expression>
  <minus_sign> ::= -
  <named_columns_join> ::= USING <left_paren> <join_column_list> <right_paren> 
  <newline> ::= 
  !! Implementation defined end of line indicator
  <non_predicate_geometry_function> ::= 
     <area>
   | <coord1>
   | <coord2> 
   | <distance>
  <nondelimiter_token> ::= 
      <regular_identifier>
    | <keyword>
    | <unsigned_numeric_literal>
   !! For information, SQL92 has some others. 
   !! (Jeff: Not sure I understand how this is used.)
  <nondoublequote_character> ::= 
   !! See SQL92 syntax rules. But basically what it says.
  <nonquote_character> ::= 
  !! One ASCII character but not a single quote 
  <not_equals_operator> ::= <not_equals_operator1> | <not_equals_operator2>
  <not_equals_operator1> ::= <>
  <not_equals_operator2> ::= !=
  <null_predicate> ::= <column_reference> IS [ NOT ] NULL
  <numeric_geometry_function> ::=
      <predicate_geometry_function> | <non_predicate_geometry_function>
  <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>	
   | <numeric_geometry_function>
   | <user_defined_function>
  !! For information, SQ92 also supports <position_expression>,
  !! <extract_expression> and <length_expression>
  <order_by_clause> ::= ORDER BY <sort_specification_list>
  <ordering_specification> ::= ASC | DESC
  <outer_join_type> ::= LEFT | RIGHT | FULL
  <pattern> ::= <character_value_expression>
  <percent> ::= %
  <period> ::= .
  <plus_sign> ::= +
  <point> ::= POINT <left_paren> <coord_sys> <comma> <coordinates> <right_paren>
  <polygon> ::=
      POLYGON <left_paren> <coord_sys> 
                   <comma> <coordinates> 
                   <comma> <coordinates> 
                 { <comma> <coordinates> } ?
              <right_paren>
  <predicate> ::=
     <comparison_predicate>
   | <between_predicate>
   | <in_predicate>
   | <like_predicate>
   | <null_predicate>
   | <exists_predicate>
  !! For information, SQL92 also supports the following predicates: 
  !! <quantified_comparison_predicate>, <unique_predicate>, 
  !! <match_predicate> and <overlaps_predicate>
  <predicate_geometry_function> ::= <contains> | <intersects>
  <qualified_join> ::=
      <table_reference> [ NATURAL ] [ <join_type> ] JOIN
      <table_reference> [ <join_specification> ]
  <qualifier> ::= <table_name> | <correlation_name> 
  <query_expression> ::=
       <query_specification>
     | <joined_table>
   !! ADQL Note: SQL92 uses <non_join_query_expression> rather than <query_specification>
  <query_specification> ::=
      SELECT [ <set_quantifier> ] [ <set_limit> ] <select_list> <table_expression>
  <question_mark> ::= ?
  <quote> ::= '
  <quote_symbol> ::= <quote> <quote>
  <radius> ::= <numeric_value_expression>
  <region> ::= REGION <left_paren> <string_value_expression> <right_paren>
  <regular_identifier> ::=
      <simple_Latin_letter>... 
      [ { <digit> | <simple_Latin_letter> | <underscore> }... ]
  <right_bracket> ::= ]
  <right_paren> ::= )
  <schema_name> ::= [ <catalog_name> <period> ] <unqualified_schema name>
  <search_condition> ::=
      <boolean_term>
    | <search_condition> OR <boolean_term>
  <select_list> ::=
      <asterisk>
    | <select_sublist> [ { <comma> <select_sublist> }... ]
  <select_sublist> ::= <derived_column> | <qualifier> <period> <asterisk>
  <semicolon> ::= ;
  <separator> ::= { <comment> | <space> | <newline> }...
  <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
  <solidus> ::= /
  <sort_key> ::= <column_name> | <unsigned_integer> 
   !! For information, the use of <unsigned_integer> in <sort_key>is a deprecated feature of SQL92
  <sort_specification> ::=
      <sort_key> [ <ordering_specification> ]
  !! For information, SQL92 also supports <collate_clause>
  <sort_specification_list> ::=
      <sort_specification> [ { <comma> <sort_specification> }... ]
  <space> ::=
  !! Imagine there is a space character here
  <string_geometry_function> ::= <extract_coordsys>
  <string_value_expression> ::=
      <character_value_expression>
  !! For information, SQL92 also supports <bit_value_expression>
  <string_value_function> ::= <string_geometry_function> | <user_defined_function>
  <subquery> ::= <left_paren> <query_expression> <right_paren>
  <table_expression> ::=
      <from_clause>
      [ <where_clause> ]
      [ <group_by_clause> ]
      [ <having_clause> ]
      [ <order_by_clause> ]
  <table_name> ::= [ <schema_name> <period> ] <identifier>
  <table_reference> ::=
     <table_name> [ <correlation_specification> ]
   | <derived_table> <correlation_specification>
   | <joined_table>
  <table_subquery> ::= <subquery>
  <term> ::=
      <factor>
    | <term> <asterisk> <factor>
    | <term> <solidus> <factor>
  <token> ::= 
      <nondelimiter_token>
    | <delimiter_token>
  <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>
  <underscore> ::= _
  <unqualified_schema name> ::= <identifier>
  <unsigned_integer> ::= <digit>...
  <unsigned_literal> ::= <unsigned_numeric_literal> | <general_literal>
  <unsigned_numeric_literal> ::=
     <exact_numeric_literal>
   | <approximate_numeric_literal>
  <unsigned_value_specification> ::= <unsigned_literal>
  <user_defined_function> ::=
      <user_defined_function_name> 
          <left_paren> 
              [ <user_defined_function_param> [ { <comma> <user_defined_function_param> }... ] ]
          <right_paren> 
  !! ADQL Note:
  !! If metadata on a user defined function is available, this should be used.
  !! For example, function names and cardinality of arguments should be checked.
  <user_defined_function_name> ::=
       [ <default_function_prefix> ] <regular_identifier>
   !! Function names should be checked against metadata where available. 
  <user_defined_function_param> ::= <value_expression>
  <value_expression> ::=
      <numeric_value_expression>
    | <string_value_expression>
    | <geometry_value_expression>
  <value_expression_primary> ::=
      <unsigned_value_specification>
    | <column_reference>
    | <set_function_specification>
    | <left_paren> <value_expression> <right_paren>
  !! For information, SQL92 supports <scalar_subquery>,
  !! <case_expression> and <cast_specification>
  <vertical_bar> ::= |
  <where_clause> ::= WHERE <search_condition>