view tests/agcl/parsifal/sql.syn @ 20:bb115deb6fb2

Improve agfiles rule. (1) It didn't depend on $(AGCL) and it absolutely should have. (2) allow AGFORCE=1 to make it rebuild whether or not it looks out of date. (3) Document this.
author David A. Holland
date Mon, 13 Jun 2022 00:02:15 -0400
parents 13d2b8934445
children
line wrap: on
line source

/*
 * AnaGram, A System for Syntax Directed Programming
 * Copyright 1993-2002 Parsifal Software. All Rights Reserved.
 * See the file COPYING for license and usage terms.
 */

// Define character sets

blank           = ' ' + '\t' + '\r'
digit           = '0-9'
eof             = 0
letter          = 'a-z' + 'A-Z' + '#' + '@' + '$'
simple char     = ~eof - ('\'' + '\\' + '\n')
string char     = ~eof - ('"' + '\\' + '\n')


CHAR             = {"CHAR" | "CHARACTER"}
DECIMAL          = {"DEC" | "DECIMAL" | "NUM" | "NUMERIC"}
DECLARE SECTION  = {"DECLARE", "SECTION"}
DELETE FROM      = {"DELETE", "FROM"}
NOT NULL         = {"NOT", "NULL"}
PACKAGE          = {"PACKAGE" | "PROGRAM"}
PRIMARY KEY      = {"PRIMARY", "KEY"}
USING DESCRIPTOR = {"USING", "DESCRIPTOR"}

[
  distinguish keywords { letter}      //Avoid problems with partial matches
  disregard white space
  lexeme {ordinary identifier, delimited identifier, integer, 
          decimal constant, character string constant}
  distinguish lexemes
  //sticky {ordinary identifier}
 ~case sensitive
  far tables
]

// Define white space to include both C and C++ style comments
white space
 -> blank
 -> "//", ~(eof + '\n')?..., '\n'
 -> ["--", ~(eof + '\n')?...], '\n'
 -> "/*", ~eof?..., "*/"

identifier
 -> ordinary identifier
 -> delimited identifier

qualified identifier
 -> identifier, '.', identifier

any identifier
 -> identifier
 -> qualified identifier

ordinary identifier
 -> letter
 -> ordinary identifier, letter + digit + '_'

delimited identifier
 -> '"', delimited identifier text, '"'

delimited identifier text
 -> delimited identifier char
 -> delimited identifier text, delimited identifier char

delimited identifier char
 -> ~eof - '"'
 -> "\"\""

host identifier
 -> 'a-z' + 'A-Z' + '_'
 -> host identifier, 'a-z' + 'A-Z' + '0-9' + '_'

descriptor name
 -> ':', host identifier

host variable
 -> descriptor name
 -> descriptor name, descriptor name

expression
 -> term
 -> expression, addop, term

addop
 -> '+'
 -> '-'

term
 -> factor
 -> term, multop, factor

multop
 -> '*'
 -> '/'

factor
 -> special register
 -> simple factor
 -> simple factor, duration
 -> sign, factor

simple factor
 -> function
 -> '(', expression, ')'
 -> constant
 -> column name
 -> host variable

sign
 -> '-' | '+'

column name
 -> any identifier

constant
 -> integer
 -> decimal constant
 -> floating point constant
 -> character string constant

integer
 -> digit
 -> integer, digit

decimal constant
 -> integer, '.'
 -> decimal constant, digit

floating point constant
 -> integer, "E", signed integer
 -> decimal constant, "E", signed integer

signed integer
 -> '+'?, integer
 -> '-', integer

character string constant
 -> '\'', character string char?..., '\''

character string char
 -> ~eof - '\''
 -> "''"

duration
 -> "YEAR"
 -> "YEARS"
 -> "MONTH"
 -> "MONTHS"
 -> "DAY"
 -> "DAYS"
 -> "HOUR"
 -> "HOURS"
 -> "MINUTE"
 -> "MINUTES"
 -> "SECOND"
 -> "SECONDS"
 -> "MICROSECOND"
 -> "MICROSECONDS"


// PREDICATES

predicate
 -> expression, comparison operator, comparand
 -> expression, between operator, expression, "AND", expression
 -> expression, "IS", "NULL"
 -> expression, "IS", NOT NULL
 -> expression, similarity operator, like operand
 -> expression, existence operator, set designation
 -> "EXISTS", '(', fullselect, ')'

existence operator
 -> "IN"
 -> "NOT", "IN"

between operator
 -> "BETWEEN"
 -> "NOT", "BETWEEN"

similarity operator
 -> "LIKE"
 -> "NOT", "LIKE"

comparison operator
 -> '=' | "<>" | '>' | "<=" | ">="

comparand
 -> expression
 -> '(', fullselect, ')'
 -> quantifier, '(', fullselect, ')'

quantifier
 -> "SOME"
 -> "ANY"
 -> "ALL"

like operand
 -> "USER"
 -> host variable
 -> character string constant

set designation
 -> '(', fullselect, ')'
 -> '(', expression, {',', expression}..., ')'
 -> expression

special register
 -> "USER"
 -> "CURRENT", "DATE"
 -> "CURRENT", "TIME"
 -> "CURRENT", "TIMESTAMP"

simple search condition
 -> predicate
 -> '(', search condition, ')'
 -> "NOT", simple search condition

search condition
 -> simple search condition
 -> search condition, logical op, simple search condition

logical op
 -> "AND"
 -> "OR"

// FUNCTIONS

function
 -> aggregate function
 -> count function
 -> char function
 -> function name, '(', args, ')'

aggregate function name
 -> "AVG" | "MAX" | "MIN" | "SUM"

aggregate function
 -> aggregate function name, '(', "ALL"?,  expression, ')'
 -> aggregate function name, distinct column name

count function
 -> "COUNT", distinct column name
 -> "COUNT", '(', '*', ')'

distinct column name
 -> '(', "DISTINCT", column name, ')'

char function
 -> "CHAR", '(', expression, date type, ')'

date type
 ->              //not specified, use default
 -> ',', "ISO"
 -> ',', "USA"
 -> ',', "EUR"
 -> ',', "JIS"
 -> ',', "LOCAL"

function name
 -> "DATE" | "DAY" | "DAYS" | "HOUR" | "LENGTH" |
    "MICROSECOND" | "MINUTE" | "MONTH" |
    "SECOND" | "TIME" | "YEAR" |
    "SUBSTR" | "TIMESTAMP" | "TRANSLATE"

args
 -> expression
 -> args, ',', expression

//  QUERIES

subselect
 -> select clause, from clause,
    where clause?, group by clause?, having clause?

select clause
 -> "SELECT", ["ALL" | "DISTINCT"], { '*' | select list}

select list
 -> select item
 -> select list, ',', select item

select item
 -> expression
 -> identifier, '.', '*'
 -> identifier, '.', identifier, '.', '*'

from clause
 -> "FROM", from list

from list
 -> from item
 -> from list, ',', from item

from item
 -> any identifier
 -> any identifier, any identifier

where clause
 -> "WHERE", search condition

group by clause
 -> "GROUP", "BY", identifier list

identifier list
 -> any identifier
 -> identifier list, ',', any identifier

paren identifier list
 -> '(', identifier list, ')'

having clause
 -> "HAVING", search condition

simple select
 -> subselect
 -> '(', fullselect, ')'

fullselect
 -> simple select
 -> fullselect, set operator, simple select

set operator
 -> "UNION" | "UNION", "ALL" | "EXCEPT" | "EXCEPT", "ALL" |
    "INTERSECT" | "INTERSECT", "ALL"

select statement
 -> fullselect
 -> fullselect, order by clause
 -> fullselect,                  fetch clause
 -> fullselect, order by clause, fetch clause
 -> fullselect, update clause

order by clause
 -> "ORDER", "BY", sort list

sort list
 -> sort item
 -> sort list, ',', sort item

sort item
 -> any identifier, sort direction
 -> integer, sort direction

sort direction
 ->                           // not specified, use default
 -> "ASC"
 -> "DESC"

update clause
 -> "FOR", "UPDATE", "OF", identifier list

fetch clause
 -> "FOR", "FETCH", "ONLY"

// STATEMENTS

grammar
 -> statements?, eof

statements
 -> drop hack
 -> statement
 -> statements, statement

statement
 -> "ALTER", "TABLE", any identifier, alter table item list, drop hack?...
 -> "BEGIN", DECLARE SECTION
 -> "CLOSE", identifier
 -> "COMMENT", "ON", comment object, "IS", character string constant
 -> "COMMIT", "WORK"?
 -> create statement
 -> "DECLARE", identifier, "CURSOR", ["WITH", "HOLD"], "FOR",
    {select statement | identifier}
 -> delete statement
 -> "DESCRIBE", identifier, "INTO", descriptor name
 -> "END", DECLARE SECTION
 -> execute statement
 -> fetch statement
 -> "GRANT", privileges, "ON", privileged object, "TO", grantee
 -> "INCLUDE", {"SQLCA" | "SQLDA"}
 -> insert statement
 -> "LOCK", "TABLE", any identifier, "IN", {"SHARE" | "EXCLUSIVE"}, "MODE"
 -> open statement
 -> "PREPARE", identifier, ["INTO", descriptor name], "FROM", host variable
 -> "REVOKE", privileges, "ON", privileged object, "FROM", grantee
 -> "ROLLBACK", "WORK"?
 -> select into statement
 -> update statement
 -> "WHENEVER", {"NOT", "FOUND" | "SQLERROR" | "SQLWARNING"},
    {"CONTINUE" | "GO", "TO", host identifier}

privileged object
 -> privileged object type, any identifier
 -> "DATABASE"

privileged object type
 ->                                // defaults to table
 -> "INDEX"
 -> PACKAGE
 -> "TABLE"

alter table item list
 -> alter table item
 -> alter table item list, alter table item

alter table item
 -> "ADD", alter column definition
 -> PRIMARY KEY, paren identifier list
 -> referential constraint
 -> "DROP", PRIMARY KEY
 -> "DROP", "FOREIGN", "KEY", identifier

drop hack
 -> "DROP", {"PACKAGE" | "PROGRAM" | "INDEX" | "TABLE" | "VIEW"}, identifier


alter column definition
 -> any identifier, data type, alter column attribute list

alter column attribute list
 ->
 -> alter column attribute list, alter column attribute

alter column attribute
 -> "FOR", "BIT", "DATA"
 -> references
 -> alter column identifier, references

alter column identifier
 -> any identifier

referential constraint
 -> referential constraint head, paren identifier list, references

referential constraint head
 -> "FOREIGN", "KEY"
 -> "FOREIGN", "KEY", any identifier

references
 -> "REFERENCES", any identifier, rules

rules
 ->
 -> delete rule
 -> delete rule, "ON", "UPDATE", "RESTRICT"
 -> "ON", "UPDATE", "RESTRICT", delete rule?

// IBM SQL spec allows delete rule to be empty. Very ambiguous.

delete rule
 -> "ON", "DELETE", {"RESTRICT" | "CASCADE" | "SET", "NULL"}

data type
 -> "INT" | "INTEGER" | "SMALLINT"
 -> "FLOAT"
 -> DECIMAL
 -> {CHAR | "VARCHAR"}, '(', integer, ')'
 -> DECIMAL, '(', integer, ')'
 -> DECIMAL, '(', integer, ',', integer, ')'
 -> CHAR
 -> "LONG", "VARCHAR"
 -> "DATE" | "TIME" | "TIMESTAMP"

comment object
 -> "TABLE", any identifier
 -> "COLUMN", qualified identifier

create statement
 -> "CREATE", "UNIQUE"?, "INDEX", any identifier, "ON", any identifier,
      '(', sort list, ')'
 -> "CREATE", "TABLE", any identifier, '(', create table list, ')'
 -> "CREATE", "VIEW", any identifier, paren identifier list?,
      "AS", fullselect, ["WITH", "CHECK", "OPTION"]

create table list
 -> create table item
 -> create table list, ',', create table item

create table item
 -> create column definition
 -> PRIMARY KEY, paren identifier list
 -> referential constraint

create column definition
 -> any identifier, data type
 -> create column definition, create column attribute

create column attribute
 -> "FOR", "BIT", "DATA"
 -> NOT NULL
 -> NOT NULL, PRIMARY KEY
 -> references
 -> any identifier, references


delete statement
 -> DELETE FROM, any identifier,  where clause?
 -> DELETE FROM, any identifier, any identifier, where clause?
 -> DELETE FROM, any identifier, where current clause

where current clause
 -> "WHERE", "CURRENT", "OF", any identifier


execute statement
 -> "EXECUTE", identifier
 -> "EXECUTE", identifier, "USING", host variable list
 -> "EXECUTE", identifier, USING DESCRIPTOR, descriptor name
 -> "EXECUTE", "IMMEDIATELY", host variable

host variable list
 -> host variable
 -> host variable list, ',', host variable


fetch statement
 -> "FETCH", any identifier, "INTO", host variable list
 -> "FETCH", any identifier, USING DESCRIPTOR, descriptor name

grantee
 -> "PUBLIC"
 -> identifier list

privileges
 -> "ALL", "PRIVILEGES"?
 -> privilege list

privilege list
 -> privilege
 -> privilege list, ',', privilege

privilege
 -> "BINDADD" | "CONNECT" | "CREATETAB" | "DBADM"
 -> "ALTER" | "BIND" | "CONTROL" | "DELETE" | "EXECUTE" |
    "INDEX" | "INSERT" | "REFERENCES" | "SELECT" | "UPDATE"

insert statement
 -> "INSERT", "INTO", any identifier,
     {fullselect | "VALUES", '(', value list, ')'}
 -> "INSERT", "INTO", any identifier, paren identifier list,
     {fullselect | "VALUES", '(', value list, ')'}

value list
 -> value
 -> value list, ',', value

value
 -> host variable
 -> constant
 -> special register
 -> "NULL"

open statement
 -> "OPEN", any identifier
 -> "OPEN", any identifier, "USING", host variable list
 -> "OPEN", any identifier, USING DESCRIPTOR, descriptor name

select into statement
 -> select clause, "INTO", host variable list, from clause,
    where clause?, group by clause?, having clause?

update statement
 -> "UPDATE", any identifier, set clause
 -> "UPDATE", any identifier, any identifier, set clause
 -> "UPDATE", any identifier, conditioned set clause
 -> "UPDATE", any identifier, any identifier, conditioned set clause
 -> "UPDATE", any identifier, set clause, where current clause

set clause
 -> "SET", assignment list

conditioned set clause
 -> set clause, where clause

assignment list
 -> assignment
 -> assignment list, ',', assignment

assignment
 -> identifier, '=', {expression | "NULL"}