Subversion

2lt

?curdirlinks? - Rev 1

?prevdifflink? - Blame



{
-----------------------------------------------------------------------------
-- |
-- Maintainer  :  dtlapa@yahoo.com, flavioxavier@gmail.com, hpacheco@gmail.com
-- Stability   :  experimental
-- Portability :  portable
--
-- See
--
--     Haskell SQL Parser Minimal Grammar
-- 
-- by
--
--     Digo Lapa, Flavio Ferreira and Hugo Pacheco
--
-----------------------------------------------------------------------------

module Language.SQL.PostgreSQL where
import Language.SQL.Lexer
import Language.SQL.Tokens
import Languag.SQL.ASTPostgreSQL
import Text.XML.HaXml.OneOfN
}

%name parsePostgreSQL
%tokentype {Token}

%token
        ABORT {Token (TokKeyword "ABORT") _ }
        ABSOLUTE {Token (TokKeyword "ABSOLUTE") _ }
        ACCESS {Token (TokKeyword "ACCESS") _ }
        ACTION {Token (TokKeyword "ACTION") _ }
        ADD {Token (TokKeyword "ADD") _ }
        ADMIN {Token (TokKeyword "ADMIN") _ }
        AFTER {Token (TokKeyword "AFTER") _ }
        AGGREGATE {Token (TokKeyword "AGGREGATE") _ }
        ALL {Token (TokKeyword "ALL") _ }
        ALSO {Token (TokKeyword "ALSO") _ }
        ALTER {Token (TokKeyword "ALTER") _ }
        ANALYSE {Token (TokKeyword "ANALYSE") _ }
        ANALYZE {Token (TokKeyword "ANALYZE") _ }
        AND {Token (TokKeyword "AND") _ }
        ANY {Token (TokKeyword "ANY") _ }
        ARRAY {Token (TokKeyword "ARRAY") _ }
        AS {Token (TokKeyword "AS") _ }
        ASC {Token (TokKeyword "ASC") _ }
        ASSERTION {Token (TokKeyword "ASSERTION") _ }
        ASSIGNMENT {Token (TokKeyword "ASSIGNMENT") _ }
        ASYMMETRIC {Token (TokKeyword "ASYMMETRIC") _ }
        AT {Token (TokKeyword "AT") _ }
        AUTHORIZATION {Token (TokKeyword "AUTHORIZATION") _ }
        BACKWARD {Token (TokKeyword "BACKWARD") _ }
        BEFORE {Token (TokKeyword "BEFORE") _ }
        BEGIN {Token (TokKeyword "BEGIN") _ }
        BETWEEN {Token (TokKeyword "BETWEEN") _ }
        BIGINT {Token (TokKeyword "BIGINT") _ }
        BINARY {Token (TokKeyword "BINARY") _ }
        BIT {Token (TokKeyword "BIT") _ }
        BOOLEAN {Token (TokKeyword "BOOLEAN") _ }
        BOTH {Token (TokKeyword "BOTH") _ }
        BY {Token (TokKeyword "BY") _ }
        CACHE {Token (TokKeyword "CACHE") _ }
        CALLED {Token (TokKeyword "CALLED") _ }
        CASCADE {Token (TokKeyword "CASCADE") _ }
        CASE {Token (TokKeyword "CASE") _ }
        CAST {Token (TokKeyword "CAST") _ }
        CHAIN {Token (TokKeyword "CHAIN") _ }
        CHAR {Token (TokKeyword "CHAR") _ }
        CHARACTER {Token (TokKeyword "CHARACTER") _ }
        CHARACTERISTICS {Token (TokKeyword "CHARACTERISTICS") _ }
        CHECK {Token (TokKeyword "CHECK") _ }
        CHECKPOINT {Token (TokKeyword "CHECKPOINT") _ }
        CLASS {Token (TokKeyword "CLASS") _ }
        CLOSE {Token (TokKeyword "CLOSE") _ }
        CLUSTER {Token (TokKeyword "CLUSTER") _ }
        COALESCE {Token (TokKeyword "COALESCE") _ }
        COLLATE {Token (TokKeyword "COLLATE") _ }
        COLUMN {Token (TokKeyword "COLUMN") _ }
        COMMENT {Token (TokKeyword "COMMENT") _ }
        COMMIT {Token (TokKeyword "COMMIT") _ }
        COMMITTED {Token (TokKeyword "COMMITTED") _ }
        CONNECTION {Token (TokKeyword "CONNECTION") _ }
        CONSTRAINT {Token (TokKeyword "CONSTRAINT") _ }
        CONSTRAINTS {Token (TokKeyword "CONSTRAINTS") _ }
        CONVERSION {Token (TokKeyword "CONVERSION") _ }
        CONVERT {Token (TokKeyword "CONVERT") _ }
        COPY {Token (TokKeyword "COPY") _ }
        CREATE {Token (TokKeyword "CREATE") _ }
        CREATEDB {Token (TokKeyword "CREATEDB") _ }
        CREATEROLE {Token (TokKeyword "CREATEROLE") _ }
        CREATEUSER {Token (TokKeyword "CREATEUSER") _ }
        CROSS {Token (TokKeyword "CROSS") _ }
        CSV {Token (TokKeyword "CSV") _ }
        CURRENT_DATE {Token (TokKeyword "CURRENT_DATE") _ }
        CURRENT_ROLE {Token (TokKeyword "CURRENT_ROLE") _ }
        CURRENT_TIME {Token (TokKeyword "CURRENT_TIME") _ }
        CURRENT_TIMESTAMP {Token (TokKeyword "CURRENT_TIMESTAMP") _ }
        CURRENT_USER {Token (TokKeyword "CURRENT_USER") _ }
        CURSOR {Token (TokKeyword "CURSOR") _ }
        CYCLE {Token (TokKeyword "CYCLE") _ }
        DATABASE {Token (TokKeyword "DATABASE") _ }
        DAY {Token (TokKeyword "DAY") _ }
        DEALLOCATE {Token (TokKeyword "DEALLOCATE") _ }
        DEC {Token (TokKeyword "DEC") _ }
        DECIMAL {Token (TokKeyword "DECIMAL") _ }
        DECLARE {Token (TokKeyword "DECLARE") _ }
        DEFAULT {Token (TokKeyword "DEFAULT") _ }
        DEFAULTS {Token (TokKeyword "DEFAULTS") _ }
        DEFERRABLE {Token (TokKeyword "DEFERRABLE") _ }
        DEFERRED {Token (TokKeyword "DEFERRED") _ }
        DEFINER {Token (TokKeyword "DEFINER") _ }
        DELETE {Token (TokKeyword "DELETE") _ }
        DELIMITER {Token (TokKeyword "DELIMITER") _ }
        DELIMITERS {Token (TokKeyword "DELIMITERS") _ }
        DESC {Token (TokKeyword "DESC") _ }
        DISABLE {Token (TokKeyword "DISABLE") _ }
        DISTINCT {Token (TokKeyword "DISTINCT") _ }
        DO {Token (TokKeyword "DO") _ }
        DOMAIN {Token (TokKeyword "DOMAIN") _ }
        DOUBLE {Token (TokKeyword "DOUBLE") _ }
        DROP {Token (TokKeyword "DROP") _ }
        EACH {Token (TokKeyword "EACH") _ }
        ELSE {Token (TokKeyword "ELSE") _ }
        ENABLE {Token (TokKeyword "ENABLE") _ }
        ENCODING {Token (TokKeyword "ENCODING") _ }
        ENCRYPTED {Token (TokKeyword "ENCRYPTED") _ }
        END {Token (TokKeyword "END") _ }
        ESCAPE {Token (TokKeyword "ESCAPE") _ }
        EXCEPT {Token (TokKeyword "EXCEPT") _ }
        EXCLUDING {Token (TokKeyword "EXCLUDING") _ }
        EXCLUSIVE {Token (TokKeyword "EXCLUSIVE") _ }
        EXECUTE {Token (TokKeyword "EXECUTE") _ }
        EXISTS {Token (TokKeyword "EXISTS") _ }
        EXPLAIN {Token (TokKeyword "EXPLAIN") _ }
        EXTERNAL {Token (TokKeyword "EXTERNAL") _ }
        EXTRACT {Token (TokKeyword "EXTRACT") _ }
        FALSE {Token (TokKeyword "FALSE") _ }
        FETCH {Token (TokKeyword "FETCH") _ }
        FIRST {Token (TokKeyword "FIRST") _ }
        FLOAT {Token (TokKeyword "FLOAT") _ }
        FOR {Token (TokKeyword "FOR") _ }
        FORCE {Token (TokKeyword "FORCE") _ }
        FOREIGN {Token (TokKeyword "FOREIGN") _ }
        FORWARD {Token (TokKeyword "FORWARD") _ }
        FREEZE {Token (TokKeyword "FREEZE") _ }
        FROM {Token (TokKeyword "FROM") _ }
        FULL {Token (TokKeyword "FULL") _ }
        FUNCTION {Token (TokKeyword "FUNCTION") _ }
        GLOBAL {Token (TokKeyword "GLOBAL") _ }
        GRANT {Token (TokKeyword "GRANT") _ }
        GRANTED {Token (TokKeyword "GRANTED") _ }
        GREATEST {Token (TokKeyword "GREATEST") _ }
        GROUP {Token (TokKeyword "GROUP") _ }
        HANDLER {Token (TokKeyword "HANDLER") _ }
        HAVING {Token (TokKeyword "HAVING") _ }
        HEADER {Token (TokKeyword "HEADER") _ }
        HOLD {Token (TokKeyword "HOLD") _ }
        HOUR {Token (TokKeyword "HOUR") _ }
        ILIKE {Token (TokKeyword "ILIKE") _ }
        IMMEDIATE {Token (TokKeyword "IMMEDIATE") _ }
        IMMUTABLE {Token (TokKeyword "IMMUTABLE") _ }
        IMPLICIT {Token (TokKeyword "IMPLICIT") _ }
        IN {Token (TokKeyword "IN") _ }
        INCLUDING {Token (TokKeyword "INCLUDING") _ }
        INCREMENT {Token (TokKeyword "INCREMENT") _ }
        INDEX {Token (TokKeyword "INDEX") _ }
        INHERIT {Token (TokKeyword "INHERIT") _ }
        INHERITS {Token (TokKeyword "INHERITS") _ }
        INITIALLY {Token (TokKeyword "INITIALLY") _ }
        INNER {Token (TokKeyword "INNER") _ }
        INOUT {Token (TokKeyword "INOUT") _ }
        INPUT {Token (TokKeyword "INPUT") _ }
        INSENSITIVE {Token (TokKeyword "INSENSITIVE") _ }
        INSERT {Token (TokKeyword "INSERT") _ }
        INSTEAD {Token (TokKeyword "INSTEAD") _ }
        INT {Token (TokKeyword "INT") _ }
        INTEGER {Token (TokKeyword "INTEGER") _ }
        INTERSECT {Token (TokKeyword "INTERSECT") _ }
        INTERVAL {Token (TokKeyword "INTERVAL") _ }
        INTO {Token (TokKeyword "INTO") _ }
        INVOKER {Token (TokKeyword "INVOKER") _ }
        IS {Token (TokKeyword "IS") _ }
        ISNULL {Token (TokKeyword "ISNULL") _ }
        ISOLATION {Token (TokKeyword "ISOLATION") _ }
        JOIN {Token (TokKeyword "JOIN") _ }
        KEY {Token (TokKeyword "KEY") _ }
        LANCOMPILER {Token (TokKeyword "LANCOMPILER") _ }
        LANGUAGE {Token (TokKeyword "LANGUAGE") _ }
        LARGE {Token (TokKeyword "LARGE") _ }
        LAST {Token (TokKeyword "LAST") _ }
        LEADING {Token (TokKeyword "LEADING") _ }
        LEAST {Token (TokKeyword "LEAST") _ }
        LEFT {Token (TokKeyword "LEFT") _ }
        LEVEL {Token (TokKeyword "LEVEL") _ }
        LIKE {Token (TokKeyword "LIKE") _ }
        LIMIT {Token (TokKeyword "LIMIT") _ }
        LISTEN {Token (TokKeyword "LISTEN") _ }
        LOAD {Token (TokKeyword "LOAD") _ }
        LOCAL {Token (TokKeyword "LOCAL") _ }
        LOCALTIME {Token (TokKeyword "LOCALTIME") _ }
        LOCALTIMESTAMP {Token (TokKeyword "LOCALTIMESTAMP") _ }
        LOCATION {Token (TokKeyword "LOCATION") _ }
        LOCK {Token (TokKeyword "LOCK") _ }
        LOGIN {Token (TokKeyword "LOGIN") _ }
        MATCH {Token (TokKeyword "MATCH") _ }
        MAXVALUE {Token (TokKeyword "MAXVALUE") _ }
        MINUTE {Token (TokKeyword "MINUTE") _ }
        MINVALUE {Token (TokKeyword "MINVALUE") _ }
        MODE {Token (TokKeyword "MODE") _ }
        MONTH {Token (TokKeyword "MONTH") _ }
        MOVE {Token (TokKeyword "MOVE") _ }
        NAMES {Token (TokKeyword "NAMES") _ }
        NATIONAL {Token (TokKeyword "NATIONAL") _ }
        NATURAL {Token (TokKeyword "NATURAL") _ }
        NCHAR {Token (TokKeyword "NCHAR") _ }
        NEW {Token (TokKeyword "NEW") _ }
        NEXT {Token (TokKeyword "NEXT") _ }
        NO {Token (TokKeyword "NO") _ }
        NOCREATEDB {Token (TokKeyword "NOCREATEDB") _ }
        NOCREATEROLE {Token (TokKeyword "NOCREATEROLE") _ }
        NOCREATEUSER {Token (TokKeyword "NOCREATEUSER") _ }
        NOINHERIT {Token (TokKeyword "NOINHERIT") _ }
        NOLOGIN {Token (TokKeyword "NOLOGIN") _ }
        NONE {Token (TokKeyword "NONE") _ }
        NOSUPERUSER {Token (TokKeyword "NOSUPERUSER") _ }
        NOT {Token (TokKeyword "NOT") _ }
        NOTHING {Token (TokKeyword "NOTHING") _ }
        NOTIFY {Token (TokKeyword "NOTIFY") _ }
        NOTNULL {Token (TokKeyword "NOTNULL") _ }
        NOWAIT {Token (TokKeyword "NOWAIT") _ }
        NULL {Token (TokKeyword "NULL") _ }
        NULLIF {Token (TokKeyword "NULLIF") _ }
        NUMERIC {Token (TokKeyword "NUMERIC") _ }
        OBJECT {Token (TokKeyword "OBJECT") _ }
        OF {Token (TokKeyword "OF") _ }
        OFF {Token (TokKeyword "OFF") _ }
        OFFSET {Token (TokKeyword "OFFSET") _ }
        OIDS {Token (TokKeyword "OIDS") _ }
        OLD {Token (TokKeyword "OLD") _ }
        ON {Token (TokKeyword "ON") _ }
        ONLY {Token (TokKeyword "ONLY") _ }
        OPERATOR {Token (TokKeyword "OPERATOR") _ }
        OPTION {Token (TokKeyword "OPTION") _ }
        OR {Token (TokKeyword "OR") _ }
        ORDER {Token (TokKeyword "ORDER") _ }
        OUT {Token (TokKeyword "OUT") _ }
        OUTER {Token (TokKeyword "OUTER") _ }
        OVERLAPS {Token (TokKeyword "OVERLAPS") _ }
        OVERLAY {Token (TokKeyword "OVERLAY") _ }
        OWNER {Token (TokKeyword "OWNER") _ }
        PARTIAL {Token (TokKeyword "PARTIAL") _ }
        PASSWORD {Token (TokKeyword "PASSWORD") _ }
        PLACING {Token (TokKeyword "PLACING") _ }
        POSITION {Token (TokKeyword "POSITION") _ }
        PRECISION {Token (TokKeyword "PRECISION") _ }
        PRESERVE {Token (TokKeyword "PRESERVE") _ }
        PREPARE {Token (TokKeyword "PREPARE") _ }
        PREPARED {Token (TokKeyword "PREPARED") _ }
        PRIMARY {Token (TokKeyword "PRIMARY") _ }
        PRIOR {Token (TokKeyword "PRIOR") _ }
        PRIVILEGES {Token (TokKeyword "PRIVILEGES") _ }
        PROCEDURAL {Token (TokKeyword "PROCEDURAL") _ }
        PROCEDURE {Token (TokKeyword "PROCEDURE") _ }
        QUOTE {Token (TokKeyword "QUOTE") _ }
        READ {Token (TokKeyword "READ") _ }
        REAL {Token (TokKeyword "REAL") _ }
        RECHECK {Token (TokKeyword "RECHECK") _ }
        REFERENCES {Token (TokKeyword "REFERENCES") _ }
        REINDEX {Token (TokKeyword "REINDEX") _ }
        RELATIVE {Token (TokKeyword "RELATIVE") _ }
        RELEASE {Token (TokKeyword "RELEASE") _ }
        RENAME {Token (TokKeyword "RENAME") _ }
        REPEATABLE {Token (TokKeyword "REPEATABLE") _ }
        REPLACE {Token (TokKeyword "REPLACE") _ }
        RESET {Token (TokKeyword "RESET") _ }
        RESTART {Token (TokKeyword "RESTART") _ }
        RESTRICT {Token (TokKeyword "RESTRICT") _ }
        RETURNS {Token (TokKeyword "RETURNS") _ }
        REVOKE {Token (TokKeyword "REVOKE") _ }
        RIGHT {Token (TokKeyword "RIGHT") _ }
        ROLE {Token (TokKeyword "ROLE") _ }
        ROLLBACK {Token (TokKeyword "ROLLBACK") _ }
        ROW {Token (TokKeyword "ROW") _ }
        ROWS {Token (TokKeyword "ROWS") _ }
        RULE {Token (TokKeyword "RULE") _ }
        SAVEPOINT {Token (TokKeyword "SAVEPOINT") _ }
        SCHEMA {Token (TokKeyword "SCHEMA") _ }
        SCROLL {Token (TokKeyword "SCROLL") _ }
        SECOND {Token (TokKeyword "SECOND") _ }
        SECURITY {Token (TokKeyword "SECURITY") _ }
        SELECT {Token (TokKeyword "SELECT") _ }
        SEQUENCE {Token (TokKeyword "SEQUENCE") _ }
        SERIALIZABLE {Token (TokKeyword "SERIALIZABLE") _ }
        SESSION {Token (TokKeyword "SESSION") _ }
        SESSION_USER {Token (TokKeyword "SESSION_USER") _ }
        SET {Token (TokKeyword "SET") _ }
        SETOF {Token (TokKeyword "SETOF") _ }
        SHARE {Token (TokKeyword "SHARE") _ }
        SHOW {Token (TokKeyword "SHOW") _ }
        SIMILAR {Token (TokKeyword "SIMILAR") _ }
        SIMPLE {Token (TokKeyword "SIMPLE") _ }
        SMALLINT {Token (TokKeyword "SMALLINT") _ }
        SOME {Token (TokKeyword "SOME") _ }
        STABLE {Token (TokKeyword "STABLE") _ }
        START {Token (TokKeyword "START") _ }
        STATEMENT {Token (TokKeyword "STATEMENT") _ }
        STATISTICS {Token (TokKeyword "STATISTICS") _ }
        STDIN {Token (TokKeyword "STDIN") _ }
        STDOUT {Token (TokKeyword "STDOUT") _ }
        STORAGE {Token (TokKeyword "STORAGE") _ }
        STRICT {Token (TokKeyword "STRICT") _ }
        SUBSTRING {Token (TokKeyword "SUBSTRING") _ }
        SUPERUSER {Token (TokKeyword "SUPERUSER") _ }
        SYMMETRIC {Token (TokKeyword "SYMMETRIC") _ }
        SYSID {Token (TokKeyword "SYSID") _ }
        SYSTEM {Token (TokKeyword "SYSTEM") _ }
        TABLE {Token (TokKeyword "TABLE") _ }
        TABLESPACE {Token (TokKeyword "TABLESPACE") _ }
        TEMP {Token (TokKeyword "TEMP") _ }
        TEMPLATE {Token (TokKeyword "TEMPLATE") _ }
        TEMPORARY {Token (TokKeyword "TEMPORARY") _ }
        THEN {Token (TokKeyword "THEN") _ }
        TIME {Token (TokKeyword "TIME") _ }
        TIMESTAMP {Token (TokKeyword "TIMESTAMP") _ }
        TO {Token (TokKeyword "TO") _ }
        TOAST {Token (TokKeyword "TOAST") _ }
        TRAILING {Token (TokKeyword "TRAILING") _ }
        TRANSACTION {Token (TokKeyword "TRANSACTION") _ }
        TREAT {Token (TokKeyword "TREAT") _ }
        TRIGGER {Token (TokKeyword "TRIGGER") _ }
        TRIM {Token (TokKeyword "TRIM") _ }
        TRUE {Token (TokKeyword "TRUE") _ }
        TRUNCATE {Token (TokKeyword "TRUNCATE") _ }
        TRUSTED {Token (TokKeyword "TRUSTED") _ }
        TYPE {Token (TokKeyword "TYPE") _ }
        UNCOMMITTED {Token (TokKeyword "UNCOMMITTED") _ }
        UNENCRYPTED {Token (TokKeyword "UNENCRYPTED") _ }
        UNION {Token (TokKeyword "UNION") _ }
        UNIQUE {Token (TokKeyword "UNIQUE") _ }
        UNKNOWN {Token (TokKeyword "UNKNOWN") _ }
        UNLISTEN {Token (TokKeyword "UNLISTEN") _ }
        UNTIL {Token (TokKeyword "UNTIL") _ }
        UPDATE {Token (TokKeyword "UPDATE") _ }
        USER {Token (TokKeyword "USER") _ }
        USING {Token (TokKeyword "USING") _ }
        VACUUM {Token (TokKeyword "VACUUM") _ }
        VALID {Token (TokKeyword "VALID") _ }
        VALIDATOR {Token (TokKeyword "VALIDATOR") _ }
        VALUES {Token (TokKeyword "VALUES") _ }
        VARCHAR {Token (TokKeyword "VARCHAR") _ }
        VARYING {Token (TokKeyword "VARYING") _ }
        VERBOSE {Token (TokKeyword "VERBOSE") _ }
        VIEW {Token (TokKeyword "VIEW") _ }
        VOLATILE {Token (TokKeyword "VOLATILE") _ }
        WHEN {Token (TokKeyword "WHEN") _ }
        WHERE {Token (TokKeyword "WHERE") _ }
        WITH {Token (TokKeyword "WITH") _ }
        WITHOUT {Token (TokKeyword "WITHOUT") _ }
        WORK {Token (TokKeyword "WORK") _ }
        WRITE {Token (TokKeyword "WRITE") _ }
        YEAR {Token (TokKeyword "YEAR") _ }
        ZONE {Token (TokKeyword "ZONE") _ }
        
        TYPECAST {Token (TokTypecast) _ }
        UNIONJOIN {Token (TokKeyword "UNIONJOIN") _ }
        
        IDENT {Token (TokIdent $$) _ }
        FCONST {Token (TokFconst $$) _ }
        SCONST {Token (TokSconst $$) _ }
        BCONST {Token (TokBconst $$) _ }
        XCONST {Token (TokXconst $$) _ }
        Op {Token (TokOp $$) _ }

        ICONST {Token (TokIconst $$) _ }
        PARAM {Token (TokParam $$) _ }

        ')' {Token (TokSymbol ')') _ }
        '(' {Token (TokSymbol '(') _ }
        ',' {Token (TokSymbol ',') _ }
        '*' {Token (TokSymbol '*') _ }
        '.' {Token (TokSymbol '.') _ }
        '[' {Token (TokSymbol '[') _ }
        ']' {Token (TokSymbol ']') _ }
        '+' {Token (TokSymbol '+') _ }
        '>' {Token (TokSymbol '>') _ }
        '<' {Token (TokSymbol '<') _ }
        '=' {Token (TokSymbol '=') _ }
        ';' {Token (TokSymbol ';') _ }
        '%' {Token (TokSymbol '%') _ }
        '/' {Token (TokSymbol '/') _ }
        '^' {Token (TokSymbol '^') _ }
        ':' {Token (TokSymbol ':') _ }
        '-' {Token (TokSymbol '-') _ }

%left           UNION EXCEPT
%left           INTERSECT
%left           OR
%left           AND
%right          NOT
%right          '='
%nonassoc       '<' '>'
%nonassoc       LIKE ILIKE SIMILAR
%nonassoc       ESCAPE
%nonassoc       OVERLAPS
%nonassoc       BETWEEN
%nonassoc       IN
%left           POSTFIXOP
%left           Op OPERATOR
%nonassoc       NOTNULL
%nonassoc       ISNULL
%nonassoc       IS NULL TRUE FALSE UNKNOWN
%left           '+' '-'
%left           '*' '/' '%'
%left           '^'
%left           AT ZONE
%right          UMINUS
%left           '[' ']'
%left           '(' ')'
%left           TYPECAST
%left           '.'
%left           JOIN UNIONJOIN CROSS LEFT FULL RIGHT INNER NATURAL

%%

start   :: { ASTPostgreSQL }
start   : stmtmulti { AST $1 }

stmtmulti       :: { Statements }
stmtmulti
        : stmtmulti ';' stmt { $1 ++ $3 }
        | stmt { $1 }
        

stmt    :: { [Statement] }
stmt
        : CreateStmt { [$1] }
        | InsertStmt { [$1] }
        | {- empty -} { [] }

CreateStmt      :: { Statement }
CreateStmt
        : CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')' OptInherit OptWithOids OnCommitOption OptTableSpace { CreateStmt $2 $4 Nothing $6 (Just $8) $9 $10 $11 }
        | CREATE OptTemp TABLE qualified_name OF qualified_name '(' OptTableElementList ')' OptWithOids OnCommitOption OptTableSpace { CreateStmt $2 $4 (Just $6) $8 Nothing $10 $11 $12 }

OptTemp :: { OptTemp }
OptTemp
        : TEMPORARY { Just TmpTemporary }
        | TEMP { Just TmpTemp }
        | LOCAL TEMPORARY { Just TmpLocalTemporary }
        | LOCAL TEMP { Just TmpLocalTemp }
        | GLOBAL TEMPORARY { Just TmpGlobalTemporary }
        | GLOBAL TEMP { Just TmpGlobalTemp }
        | {-EMPTY-} { Nothing }
        

OptTableElementList     :: { OptTableElementList }
OptTableElementList
        : TableElementList { Just $1 }
        | {-EMPTY-} { Nothing }
        
TableElementList        :: { TableElementList }
TableElementList
        : TableElementList_aux { MyLst $1 }

TableElementList_aux    :: { [TableElement] }
TableElementList_aux
        : TableElement { [$1] }
        | TableElementList_aux ',' TableElement { $1 ++ [$3] }
        
TableElement    :: { TableElement }
TableElement
        : columnDef { OneOf3 $1 }
        | TableLikeClause { TwoOf3 $1 }
        | TableConstraint { ThreeOf3 $1 }
        
columnDef       :: { ColumnDef }
columnDef
        : ColId Typename ColQualList { CDef $1 $2 $3 }
        
ColQualList     :: { ColQualList }
ColQualList
        : ColQualList ColConstraint { $1 ++ [$2] }
        | {-EMPTY-} { [] }
        
ColConstraint   :: { ColConstraint }
ColConstraint
        : CONSTRAINT name ColConstraintElem { OneOf3 (CONSTRAINT,$2,$3) }
        | ColConstraintElem { TwoOf3 $1 }
        | ConstraintAttr { ThreeOf3 $1 }

ColConstraintElem       :: { ColConstraintElem }
ColConstraintElem
        : NOT NULL { CstrNotNull }
        | NULL { CstrNull }
        | UNIQUE OptConsTableSpace { CstrUnique $2 }
        | PRIMARY KEY OptConsTableSpace {  CstrPrimaryKey $3 }
        | CHECK '(' a_expr ')' { CstrCheck $3 }
        | DEFAULT b_expr { CstrDefault $2 }
        | REFERENCES qualified_name opt_column_list key_match key_actions { CstrReferences $2 $3 $4 $5 }

ConstraintAttr  :: { ConstraintAttr }
ConstraintAttr
        : DEFERRABLE { CstrAttrDeferrable }
        | NOT DEFERRABLE { CstrAttrNotDeferrable }
        | INITIALLY DEFERRED { CstrAttrInitiallyDeferred }
        | INITIALLY IMMEDIATE { CstrAttrInitiallyImmediate }

TableLikeClause :: { TableLikeClause }
TableLikeClause
        : LIKE qualified_name like_including_defaults { TLike $2 $3 }
        
like_including_defaults :: { LikeIncludingDefaults }
like_including_defaults
        : INCLUDING DEFAULTS { Just LikeIncludingDefaults }
        | EXCLUDING DEFAULTS { Just LikeExcludingDefaults }
        | {- EMPTY -} { Nothing }

TableConstraint :: { TableConstraint }
TableConstraint
        : CONSTRAINT name ConstraintElem { TConstraint (Just $2) $3 }
        | ConstraintElem { TConstraint Nothing $1 }
        
ConstraintElem  :: { ConstraintElem }
ConstraintElem
        : CHECK '(' a_expr ')' { CstrElemCheck $3 }
        | UNIQUE '(' columnList ')' OptConsTableSpace { CstrElemUnique $3 $5 }
        | PRIMARY KEY '(' columnList ')' OptConsTableSpace { CstrElemPrimaryKey $4 $6 }
        | FOREIGN KEY '(' columnList ')' REFERENCES qualified_name opt_column_list key_match key_actions ConstraintAttributeSpec { CstrElemForeignKey $4 $7 $8 $9 $10 $11 }
        
opt_column_list :: { OptColumnList }
opt_column_list
        : '(' columnList ')' { OptColList $ Just $2 }
        | {-EMPTY-} { OptColList Nothing }
        
columnList      :: { ColumnList }
columnList
        : columnList_aux { MyLst $1 }

columnList_aux  :: { [ColumnElem] }
columnList_aux
        : columnElem { [$1] }
        | columnList_aux ',' columnElem {  $1 ++ [$3] }
        
columnElem      :: { ColumnElem }
columnElem
        : ColId { $1 }
        
key_match       :: { KeyMatch }
key_match
        : MATCH FULL { Just MatchFull }
        | MATCH PARTIAL { Just MatchPartial }
        | MATCH SIMPLE { Just MatchSimple }
        | {-EMPTY-} { Nothing }

key_actions     :: { KeyActions }
key_actions
        : key_update { Just $ OneOf3 $1 }
        | key_delete { Just $ TwoOf3 $1 }
        | key_update key_delete { Just $ ThreeOf3 ($1,$2) }
        | key_delete key_update { Just $ ThreeOf3 ($2,$1) }
        | {-EMPTY-} { Nothing }

InsertStmt      :: { Statement }
InsertStmt
        : INSERT INTO qualified_name insert_rest { InsertStmt $3 $4 }   

insert_rest     :: { InsertRest }
insert_rest
        : VALUES '(' insert_target_list ')' { InsValues $3 }
        | DEFAULT VALUES { InsDefaultValues }
        | SelectStmt { InsSelect $1 }
        | '(' insert_column_list ')' VALUES '(' insert_target_list ')' { InsColValues $2 $6 }
        | '(' insert_column_list ')' SelectStmt { InsCol $2 $4 }        

insert_column_list      :: { InsertColumnList } 
insert_column_list
        : insert_column_list_aux { MyLst $1 }   

insert_column_list_aux  :: { [InsertColumnItem] }
insert_column_list_aux
        : insert_column_item { [$1] }
        | insert_column_list_aux ',' insert_column_item { $1 ++ [$3] }
        
insert_column_item      :: { InsertColumnItem }
insert_column_item
        : ColId opt_indirection { InsColItem $1 $2 }

SelectStmt      :: { Statement }
SelectStmt
        : select_no_parens %prec UMINUS { SelectStmt $ Left $1 }
        | select_with_parens %prec UMINUS { SelectStmt $ Right $1 }

select_with_parens      :: { SelectWithParens }
select_with_parens
        : '(' select_no_parens ')' { SlctNo $2 }
        | '(' select_with_parens ')' { SlctWith $2 }

select_no_parens        :: { SelectNoParens }
select_no_parens
        : simple_select { SlctSimple $1 }
        | select_clause sort_clause { SlctBin $1 $2 }
        | select_clause opt_sort_clause for_locking_clause opt_select_limit { SlctMulti1 $1 $2 $3 $4 }
        | select_clause opt_sort_clause select_limit opt_for_locking_clause { SlctMulti2 $1 $2 $3 $4 }

select_clause   :: { SelectClause }
select_clause
        : simple_select { Left $1 }
        | select_with_parens { Right $1 }

simple_select   :: { SimpleSelect }
simple_select
        : SELECT opt_distinct target_list into_clause from_clause where_clause group_clause having_clause { SimpSlct $2 $3 $4 $5 $6 $7 $8 }
        | select_clause UNION opt_all select_clause { UnionSlct $1 $3 $4 }
        | select_clause INTERSECT opt_all select_clause { IntersectSlct $1 $3 $4 }
        | select_clause EXCEPT opt_all select_clause { ExceptSlct $1 $3 $4 }

into_clause     :: { IntoClause }
into_clause
        : INTO OptTempTableName { Just (INTO,$2) }
        | {- empty -} { Nothing }

OptTempTableName        :: { OptTempTableName }
OptTempTableName
        : TEMPORARY opt_table qualified_name { TNTemporary $2 $3 }
        | TEMP opt_table qualified_name { TNTemp $2 $3 }
        | LOCAL TEMPORARY opt_table qualified_name { TNLocalTemporary $3 $4 }
        | LOCAL TEMP opt_table qualified_name { TNLocalTemp $3 $4 }
        | GLOBAL TEMPORARY opt_table qualified_name { TNGlobalTemporary $3 $4 }
        | GLOBAL TEMP opt_table qualified_name { TNGlobalTemp $3 $4 }
        | TABLE qualified_name { TNTable $2 }
        | qualified_name { TN $1 }
        
opt_table       :: { OptTable }
opt_table
        : TABLE { Just TABLE }
        | {- empty -} { Nothing }       

opt_all :: { OptAll }
opt_all : ALL { Just $ Left ALL }
        | DISTINCT { Just $ Right DISTINCT }
        | {- empty -} { Nothing }

opt_distinct    :: { OptDistinct }
opt_distinct
        : DISTINCT { DisctDistinct }
        | DISTINCT ON '(' expr_list ')' { DisctDistinctOn $4 }
        | ALL { DisctAll }
        | {- empty -} { NoDisct }

opt_sort_clause :: { OptSortClause }
opt_sort_clause
        : sort_clause { Just $1 }
        | {- empty -} { Nothing }

sort_clause     :: { SortClause }
sort_clause
        : ORDER BY sortby_list { SortCl $3 }

sortby_list     :: { SortByList }       
sortby_list
        : sortby_list_aux { MyLst $1 }  

sortby_list_aux :: { [SortBy] }
sortby_list_aux
        : sortby { [$1] }
        | sortby_list_aux ',' sortby { $1 ++ [$3] }
        

sortby  :: { SortBy }
sortby  : a_expr USING qual_all_Op { SortByUsing $1 $3 }
        | a_expr ASC { SortByAsc $1 }
        | a_expr DESC { SortByDesc $1 }
        | a_expr { SortByExp $1 }
        
select_limit    :: { SelectLimit }
select_limit
        : LIMIT select_limit_value OFFSET select_offset_value { SlctLimitOffset $2 $4 }
        | OFFSET select_offset_value LIMIT select_limit_value { SlctLimitOffset $4 $2 }
        | LIMIT select_limit_value { SlctLimit $2 }
        | OFFSET select_offset_value { SlctOffset $2 }
        | LIMIT select_limit_value ',' select_offset_value { SlctLimitOffset $2 $4 }

opt_select_limit        :: { OptSelectLimit }
opt_select_limit
        : select_limit { Just $1 }
        | {- empty -} { Nothing }
        
select_limit_value      :: { SelectLimitValue }
select_limit_value
        : a_expr { Left $1 }
        | ALL { Right ALL }     

select_offset_value     :: { SelectOffsetValue }
select_offset_value
        : a_expr { $1 }

group_clause    :: { GroupClause }
group_clause
        : GROUP BY expr_list { GrpClause $ Just $3 }
        | {- empty -} { GrpClause Nothing }
        
having_clause   :: { HavingClause }
having_clause
        : HAVING a_expr { HavClause $ Just $2 }
        | {- empty -} { HavClause Nothing }

for_locking_clause      :: { ForLockingClause }
for_locking_clause
        : FOR UPDATE locked_rels_list opt_nowait { ForLckUpdate $3 $4 }
        | FOR SHARE locked_rels_list opt_nowait { ForLckShare $3 $4 }
        | FOR READ ONLY { ForLckReadOnly }
        
opt_for_locking_clause  :: { OptForLockingClause }
opt_for_locking_clause
        : for_locking_clause { Just $1 }
        | {- empty -} { Nothing }
        

locked_rels_list        :: { LockedRelsList }
locked_rels_list
        : OF name_list { LockedRelsLst $ Just $2 }
        | {- empty -} { LockedRelsLst Nothing }

from_clause     :: { FromClause }
from_clause
        : FROM from_list { FromClauseConst $ Just $2 }
        | {- empty -} { FromClauseConst Nothing }       

from_list       :: { FromList }
from_list
        : from_list_aux { MyLst $1 }

from_list_aux   :: { [TableRef] }
from_list_aux
        : table_ref { [$1] }
        | from_list_aux ',' table_ref { $1 ++ [$3] }

table_ref       :: { TableRef }
table_ref
        : relation_expr { TableRefExpr $1 Nothing }
        | relation_expr alias_clause { TableRefExpr $1 (Just $2) }
        | func_table { TableRefFunc $1 Nothing }
        | func_table alias_clause { TableRefFunc $1 (Just $2) }
        | func_table AS '(' TableFuncElementList ')' { TableRefFunc2 $1 (OneOf3 AS) $4 }
        | func_table AS ColId '(' TableFuncElementList ')' { TableRefFunc2 $1(ThreeOf3 (AS,$3)) $5 }
        | func_table ColId '(' TableFuncElementList ')' { TableRefFunc2 $1 (TwoOf3 $2) $4 }
        | select_with_parens { TableRefSelect $1 Nothing }
        | select_with_parens alias_clause { TableRefSelect $1 (Just $2) }
        | joined_table { TableRefJoin $1 Nothing }
        | '(' joined_table ')' alias_clause { TableRefJoin $2 (Just $4) }

joined_table    :: { JoinedTable }
joined_table
        : '(' joined_table ')' { JoinedTableJoined $2 }
        | table_ref CROSS JOIN table_ref { JoinedTableCrossJoin $1 $4 }
        | table_ref UNIONJOIN table_ref { JoinedTableUnionjoin $1 $3 }
        | table_ref join_type JOIN table_ref join_qual { JoinedTableJoin $1 (Just $2) $4 $5 }
        | table_ref JOIN table_ref join_qual { JoinedTableJoin $1 Nothing $3 $4 }
        | table_ref NATURAL join_type JOIN table_ref { JoinedTableNatural $1 (Just $3) $5 }
        | table_ref NATURAL JOIN table_ref { JoinedTableNatural $1 Nothing $4 }

alias_clause    :: { AliasClause }      
alias_clause
        : AS ColId '(' name_list ')' { AliasClauseConst (Just AS) $2 (Just $4) }
        | AS ColId { AliasClauseConst (Just AS) $2 Nothing }
        | ColId '(' name_list ')' { AliasClauseConst Nothing $1 (Just $3) }
        | ColId { AliasClauseConst Nothing $1 Nothing }


join_type       :: { JoinType } 
join_type
        : FULL join_outer { Left $ (OneOf3 FULL,$2) }
        | LEFT join_outer { Left $ (TwoOf3 LEFT,$2) }
        | RIGHT join_outer { Left $ (ThreeOf3 RIGHT,$2) }
        | INNER { Right INNER }

join_outer      :: { JoinOuter }
join_outer
        : OUTER { Just OUTER }
        | {- empty -} { Nothing }

join_qual       :: { JoinQual }
join_qual
        : USING '(' name_list ')' { JoinQualConst $ Left $3 }
        | ON a_expr { JoinQualConst $ Right $2 }

relation_expr   :: { RelationExpr }
relation_expr
        : qualified_name { RelationExprConst Nothing $1 Nothing }
        | qualified_name '*' { RelationExprConst Nothing $1 (Just STAR) }
        | ONLY qualified_name { RelationExprConst (Just ONLY) $2 Nothing }
        | ONLY '(' qualified_name ')' { RelationExprConst (Just ONLY) $3 Nothing }

func_table      :: { FuncTable }
func_table
        : func_expr { $1 }

where_clause    :: { WhereClause }
where_clause
        : WHERE a_expr { WhereClauseConst $ Just $2 }
        | {- empty -} { WhereClauseConst Nothing }

TableFuncElementList    :: { TableFuncElementList }
TableFuncElementList
        : TableFuncElementList_aux { MyLst $1 }

TableFuncElementList_aux        :: { [TableFuncElement] }
TableFuncElementList_aux
        : TableFuncElement { [$1] }
        | TableFuncElementList_aux ',' TableFuncElement { $1 ++ [$3] }

TableFuncElement        :: { TableFuncElement }
TableFuncElement
        : ColId Typename { ($1,$2) }

Typename        :: { Typename }
Typename
        : SimpleTypename opt_array_bounds { TypenameConst Nothing $1 (Left $2) }
        | SETOF SimpleTypename opt_array_bounds { TypenameConst (Just SETOF) $2 (Left $3) }
        | SimpleTypename ARRAY '[' Iconst ']' { TypenameConst Nothing $1 (Right $4)  }
        | SETOF SimpleTypename ARRAY '[' Iconst ']' { TypenameConst (Just SETOF) $2 (Right $5) }

opt_array_bounds        :: { OptArrayBounds }   
opt_array_bounds
        : opt_array_bounds '[' ']' { SingleArray $1 }
        | opt_array_bounds '[' Iconst ']' { IconstArray $1 $3 }
        | {- empty -} { EmptyArray }
        
SimpleTypename  :: { SimpleTypename }
SimpleTypename
        : GenericType { SimpTypeGeneric $1 }
        | Numeric { SimpTypeNum $1 }
        | Bit { SimpTypeBit $1 }
        | Character { SimpTypeChar $1 }
        | ConstDatetime { SimpTypeDate $1 }
        | ConstInterval opt_interval { SimpTypeInterval $1 Nothing $2 }
        | ConstInterval '(' Iconst ')' opt_interval { SimpTypeInterval $1 (Just $3) $5 }
        | type_name attrs { SimpType $1 $2 }

ConstTypename   :: { ConstTypename }
ConstTypename
        : GenericType { ConstTypeGeneric $1 }
        | Numeric { ConstTypeNum $1 }
        | ConstBit { ConstTypeBit $1 }
        | ConstCharacter { ConstTypeChar $1 }
        | ConstDatetime { ConstTypeDate $1 }

GenericType     :: { GenericType }
GenericType
        : type_name { $1 }

Numeric :: { Numeric }
Numeric
        : INT { NumInt }
        | INTEGER { NumInteger }
        | SMALLINT { NumSmallInt }
        | BIGINT { NumBigInt }
        | REAL { NumReal }
        | FLOAT opt_float { NumFloat $2 }
        | DOUBLE PRECISION { NumDouble }
        | DECIMAL opt_decimal { NumDecimal $2 }
        | DEC opt_decimal { NumDecimal $2 }
        | NUMERIC opt_numeric { NumNumeric $2 }
        | BOOLEAN { NumBool }
        
opt_float       :: { OptFloat }
opt_float
        : '(' Iconst ')' { OptFloatConst $ Just $2 }
        | {- empty -} { OptFloatConst Nothing }
        
opt_numeric     :: { OptNumeric }
opt_numeric
        : '(' Iconst ',' Iconst ')' { OptNumericConst $ Just ($2,Just $4) }
        | '(' Iconst ')' { OptNumericConst $ Just ($2,Nothing) }
        | {- empty -} { OptNumericConst Nothing }

        
opt_decimal     :: { OptDecimal }
opt_decimal
        : '(' Iconst ',' Iconst ')' { OptNumericConst $ Just ($2,Just $4) }
        | '(' Iconst ')' { OptNumericConst $ Just ($2,Nothing) }
        | {- empty -} { OptNumericConst Nothing }

Bit     :: { Bit }
Bit     : BitWithLength { Left $1 }
        | BitWithoutLength { Right $1 }

ConstBit        :: { ConstBit }
ConstBit
        : BitWithLength { Left $1 }
        | BitWithoutLength { Right $1 } 

BitWithLength   :: { BitWithLength }
BitWithLength
        : BIT opt_varying '(' Iconst ')' { BitDef $2 (Just $4) }

BitWithoutLength        :: { BitWithoutLength }
BitWithoutLength
        : BIT opt_varying { BitDef $2 Nothing }

Character       :: { Character }
Character
        : CharacterWithLength { $1 }
        | CharacterWithoutLength { $1 }

ConstCharacter  :: { ConstCharacter }
ConstCharacter
        : CharacterWithLength { $1 }
        | CharacterWithoutLength { $1 }
        
CharacterWithLength     :: { CharacterWithLength }
CharacterWithLength
        : character '(' Iconst ')' opt_charset { CharDef $1 (Just $3) $5 }
        
CharacterWithoutLength  :: { CharacterWithoutLength }
CharacterWithoutLength
        : character opt_charset { CharDef $1 Nothing $2 }

character       :: { Character2 }       
character
        : CHARACTER opt_varying { Char2Character $2 }
        | CHAR opt_varying { Char2Character $2 }
        | VARCHAR { Char2VarChar }
        | NATIONAL CHARACTER opt_varying { Char2National $3 }
        | NATIONAL CHAR opt_varying { Char2National $3 }
        | NCHAR opt_varying { Char2National $2 }

opt_varying     :: { OptVarying }
opt_varying
        : VARYING { Just VARYING }
        | {- empty -} { Nothing }

opt_charset     :: { OptCharset }
opt_charset
        : CHARACTER SET ColId { OptCharConst $ Just $3 }
        | {- empty -} { OptCharConst Nothing }
        
ConstDatetime   :: { ConstDatetime }
ConstDatetime
        : TIMESTAMP '(' Iconst ')' opt_timezone { ConstTimestamp (Just $3) $5 }
        | TIMESTAMP opt_timezone { ConstTimestamp Nothing $2 }
        | TIME '(' Iconst ')' opt_timezone { ConstTimestamp (Just $3) $5 }
        | TIME opt_timezone { ConstTimestamp Nothing $2 }       

ConstInterval   :: { ConstInterval }
ConstInterval
        : INTERVAL { INTERVAL }
        


opt_timezone    :: { OptTimezone }
opt_timezone
        : WITH TIME ZONE { WithTimeZone }
        | WITHOUT TIME ZONE { WithoutTimeZone }
        | {- empty -} { NoTimeZoneDecl }

opt_interval    :: { OptInterval }
opt_interval
        : YEAR { IntervalYear }
        | MONTH { IntervalMonth }
        | DAY   { IntervalDay }
        | HOUR { IntervalHour }
        | MINUTE { IntervalMinute }
        | SECOND { IntervalSecond }
        | YEAR TO MONTH { IntervalYearToMonth }
        | DAY TO HOUR { IntervalDayToHour }
        | DAY TO MINUTE { IntervalDayToMinute }
        | DAY TO SECOND { IntervalDayToSecond }
        | HOUR TO MINUTE { IntervalHourToMinute }
        | HOUR TO SECOND { IntrevalHourToSecond }
        | MINUTE TO SECOND { IntervalMinuteToSecond }
        | {- empty -} { NoInterval }

a_expr  :: { AExpr }
a_expr
        : c_expr {  AExpCExp $1 }
        | a_expr TYPECAST Typename { AExpTypecast $1 $3 }
        | a_expr AT TIME ZONE a_expr { AExpTZ $1 $5 }
        | '+' a_expr %prec UMINUS { AExpPositive $2 }
        | '-' a_expr %prec UMINUS { AExpNegative $2 }
        | a_expr '+' a_expr { AExpMath $1 (OneOf9 PLUS) $3 }
        | a_expr '-' a_expr { AExpMath $1 (TwoOf9 MINUS) $3 }
        | a_expr '*' a_expr { AExpMath $1 (ThreeOf9 STAR) $3 }
        | a_expr '/' a_expr { AExpMath $1 (FourOf9 SLASH) $3 }
        | a_expr '%' a_expr { AExpMath $1 (FiveOf9 PERCENTAGE) $3 }
        | a_expr '^' a_expr { AExpMath $1 (SixOf9 HAT) $3 }
        | a_expr '<' a_expr { AExpMath $1 (SevenOf9 SMALLER) $3 }
        | a_expr '>' a_expr { AExpMath $1 (EightOf9 GREATER) $3 }
        | a_expr '=' a_expr { AExpMath $1 (NineOf9 EQUAL) $3 }
        | a_expr qual_Op a_expr %prec Op { AExpQual (Just $1) $2 $3 }
        | qual_Op a_expr %prec Op { AExpQual Nothing $1 $2 }
        | a_expr qual_Op %prec POSTFIXOP { AExpQual Nothing $2 $1 }
        | a_expr AND a_expr { AExpAnd $1 $3 }
        | a_expr OR a_expr { AExpOr $1 $3 }
        | NOT a_expr { AExpNot $2 }
        | a_expr LIKE a_expr { AExpLike $1 $3 Nothing }
        | a_expr LIKE a_expr ESCAPE a_expr { AExpLike $1 $3 (Just $5) }
        | a_expr NOT LIKE a_expr { AExpNotLike $1 $4 Nothing }
        | a_expr NOT LIKE a_expr ESCAPE a_expr { AExpNotLike $1 $4 (Just $6) }
        | a_expr ILIKE a_expr { AExpILike $1 $3 Nothing }
        | a_expr ILIKE a_expr ESCAPE a_expr { AExpILike $1 $3 (Just $5) }
        | a_expr NOT ILIKE a_expr { AExpNotILike $1 $4 Nothing }
        | a_expr NOT ILIKE a_expr ESCAPE a_expr { AExpNotILike $1 $4 (Just $6) }
        | a_expr SIMILAR TO a_expr %prec SIMILAR { AExpSimilar $1 $4 Nothing }
        | a_expr SIMILAR TO a_expr ESCAPE a_expr { AExpSimilar $1 $4 (Just $6) }
        | a_expr NOT SIMILAR TO a_expr %prec SIMILAR { AExpNotSimilar $1 $5 Nothing }
        | a_expr NOT SIMILAR TO a_expr ESCAPE a_expr { AExpNotSimilar $1 $5 (Just $7) }
        | a_expr ISNULL { AExpIsNull $1 }
        | a_expr IS NULL { AExpIsNull $1 }
        | a_expr NOTNULL { AExpNotNull $1 }
        | a_expr IS NOT NULL { AExpIsNotNull $1 }
        | row OVERLAPS row { AExpOverlaps $1 $3 }
        | a_expr IS TRUE { AExpIsTrue $1 }
        | a_expr IS NOT TRUE { AExpIsNotTrue $1 }
        | a_expr IS FALSE { AExpIsFalse $1 }
        | a_expr IS NOT FALSE { AExpIsNotFalse $1 }
        | a_expr IS UNKNOWN { AExpIsUnknown $1 }
        | a_expr IS NOT UNKNOWN { AExpIsNotUnknown $1 }
        | a_expr IS DISTINCT FROM a_expr %prec IS { AExpIsDistinct $1 $5 }
        | a_expr IS OF '(' type_list ')' %prec IS { AExpIsOf $1 $5 }
        | a_expr IS NOT OF '(' type_list ')' %prec IS { AExpIsNotOf $1 $6 }
        | a_expr BETWEEN opt_asymmetric b_expr AND b_expr %prec BETWEEN { AExpBetween $1 $3 $4 $6 }
        | a_expr NOT BETWEEN opt_asymmetric b_expr AND b_expr %prec BETWEEN { AExpNotBetween $1 $4 $5 $7 }
        | a_expr BETWEEN SYMMETRIC b_expr AND b_expr %prec BETWEEN { AExpBetweenSymmetric $1 $4 $6 }
        | a_expr NOT BETWEEN SYMMETRIC b_expr AND b_expr %prec BETWEEN { AExpNotBetweenSymmetric $1 $5 $7 }
        | a_expr IN in_expr { AExpIn $1 $3 }
        | a_expr NOT IN in_expr { AExprNotIn $1 $4 }
        | a_expr subquery_Op sub_type select_with_parens %prec Op { AExpSub $1 $2 $3 (Left $4) }
        | a_expr subquery_Op sub_type '(' a_expr ')' %prec Op { AExpSub $1 $2 $3 (Right $5) }
        | UNIQUE select_with_parens %prec Op { AExpUnique $2 }

b_expr  :: { BExpr }
b_expr  : c_expr { BExpCExp $1 }
        | b_expr TYPECAST Typename { BExpTypecast $1 $3 }
        | '+' b_expr %prec UMINUS { BExpPositive $2 }
        | '-' b_expr %prec UMINUS { BExpNegative $2 }
        | b_expr '+' b_expr { BExpMath $1 (OneOf9 PLUS) $3 }
        | b_expr '-' b_expr { BExpMath $1 (TwoOf9 MINUS) $3 }
        | b_expr '*' b_expr { BExpMath $1 (ThreeOf9 STAR) $3 }
        | b_expr '/' b_expr { BExpMath $1 (FourOf9 SLASH) $3 }
        | b_expr '%' b_expr { BExpMath $1 (FiveOf9 PERCENTAGE) $3 }
        | b_expr '^' b_expr { BExpMath $1 (SixOf9 HAT) $3 }
        | b_expr '<' b_expr { BExpMath $1 (SevenOf9 SMALLER) $3 }
        | b_expr '>' b_expr { BExpMath $1 (EightOf9 GREATER) $3 }
        | b_expr '=' b_expr { BExpMath $1 (NineOf9 EQUAL) $3 }
        | b_expr qual_Op b_expr %prec Op { BExpQual (Just $1) $2 $3 }
        | qual_Op b_expr %prec Op { BExpQual Nothing $1 $2 }
        | b_expr qual_Op %prec POSTFIXOP { BExpQual Nothing $2 $1 }
        | b_expr IS DISTINCT FROM b_expr %prec IS { BExpIsDistinct $1 $5 }
        | b_expr IS OF '(' type_list ')' %prec IS { BExpIsOf $1 $5 }
        | b_expr IS NOT OF '(' type_list ')' %prec IS { BExpIsNotOf $1 $6 }

c_expr  :: { CExpr }
c_expr  : columnref { CExpCol $1 }
        | AexprConst { CExpAExpC $1 }
        | PARAM opt_indirection { CExpParam $2 }
        | '(' a_expr ')' opt_indirection { CExpAExp $2 $4 }
        | case_expr { CExpCase $1 }
        | func_expr { CExpFunc $1 }
        | select_with_parens %prec UMINUS { CExpSelect $1 }
        | EXISTS select_with_parens { CExpExists $2 }
        | ARRAY select_with_parens { CExpArray $ Left $2 }
        | ARRAY array_expr { CExpArray $ Right $2 }
        | row { CExpRow $1 }

func_expr       :: { FuncExpr }
func_expr
        : func_name '(' ')' { FuncExpFunc $1 Nothing }
        | func_name '(' expr_list ')' { FuncExpFunc $1 $ Just $ OneOf4 $3 }
        | func_name '(' ALL expr_list ')' { FuncExpFunc $1 $ Just $ TwoOf4 $4 }
        | func_name '(' DISTINCT expr_list ')' { FuncExpFunc $1 $ Just $ ThreeOf4 $4 }
        | func_name '(' '*' ')' { FuncExpFunc $1 $ Just $ FourOf4 STAR }
        | CURRENT_DATE { FuncExpCurrentDate }
        | CURRENT_TIME { FuncExpCurrentTime Nothing }
        | CURRENT_TIME '(' Iconst ')' { FuncExpCurrentTime $ Just $3 }
        | CURRENT_TIMESTAMP { FuncExpCurrentTimestamp Nothing }
        | CURRENT_TIMESTAMP '(' Iconst ')' { FuncExpCurrentTimestamp $ Just $3 }
        | LOCALTIME { FuncExpLocalTime Nothing }
        | LOCALTIME '(' Iconst ')' { FuncExpLocalTime $ Just $3 }
        | LOCALTIMESTAMP { FuncExpLocalTimestamp Nothing }
        | LOCALTIMESTAMP '(' Iconst ')' { FuncExpLocalTimestamp $ Just $3 }
        | CURRENT_ROLE { FuncExpCurrentRole }
        | CURRENT_USER { FuncExpCurrentUser }
        | SESSION_USER { FuncExpSessionUser }
        | USER { FuncExpUser }
        | CAST '(' a_expr AS Typename ')' { FuncExpCast $3 $5 }
        | EXTRACT '(' extract_list ')' { FuncExpExtract $3 }
        | OVERLAY '(' overlay_list ')' { FuncExpOverlay $3 }
        | POSITION '(' position_list ')' { FuncExpPosition $3 }
        | SUBSTRING '(' substr_list ')' { FuncExpSubstring $3 }
        | TREAT '(' a_expr AS Typename ')' { FuncExpTreat $3 $5 }
        | TRIM '(' BOTH trim_list ')' { FuncExpTrim $ OneOf4 $4 }
        | TRIM '(' LEADING trim_list ')' { FuncExpTrim $ TwoOf4 $4 }
        | TRIM '(' TRAILING trim_list ')' { FuncExpTrim $ ThreeOf4 $4 }
        | TRIM '(' trim_list ')' { FuncExpTrim $ FourOf4 $3 }
        | CONVERT '(' a_expr USING any_name ')' { FuncExpConvert $ Left ($3,$5) }
        | CONVERT '(' expr_list ')' { FuncExpConvert $ Right $3 }
        | NULLIF '(' a_expr ',' a_expr ')' { FuncExpNullif $3 $5 }
        | COALESCE '(' expr_list ')' { FuncExpCoalesce $3 }
        | GREATEST '(' expr_list ')' { FuncExpGreatest $3 }
        | LEAST '(' expr_list ')' { FuncExpLeast $3 }

row     :: { Row }
row     : ROW '(' expr_list ')' { RowExpr $3 }
        | ROW '(' ')' { RowSingle }
        | '(' expr_list ',' a_expr ')' { RowExprs $2 $4 }

sub_type        :: { SubType }
sub_type
        : ANY { OneOf3 ANY }
        | SOME { TwoOf3 SOME }
        | ALL { ThreeOf3 ALL }

all_Op  :: { AllOp }
all_Op  : Op { Left $1 }
        | MathOp { Right $1 }
        
MathOp  :: { MathOp }
MathOp  : '+' { OneOf9 PLUS }
        | '-' { TwoOf9 MINUS }
        | '*' { ThreeOf9 STAR }
        | '/' { FourOf9 SLASH }
        | '%' { FiveOf9 PERCENTAGE }
        | '^' { SixOf9 HAT }
        | '<' { SevenOf9 SMALLER }
        | '>' { EightOf9 GREATER }
        | '=' { NineOf9 EQUAL }

qual_Op :: { QualOp }
qual_Op : Op { QualOper $ Left $1 }
        | OPERATOR '(' any_operator ')' { QualOper $ Right $3 }
        
qual_all_Op     :: { QualAllOp }
qual_all_Op
        : all_Op { QualAllOper $ Left $1 }
        | OPERATOR '(' any_operator ')' { QualAllOper $ Right $3 }
        
subquery_Op     :: { SubQueryOp }
subquery_Op
        : all_Op { SubQAll $1 }
        | OPERATOR '(' any_operator ')' { SubQOp $3 }
        | LIKE { SubQLike }
        | NOT LIKE { SubQNotLike }
        | ILIKE { SubQIlike }
        | NOT ILIKE { SubQNotIlike }            

expr_list       :: { ExprList }
expr_list
        : a_expr { MyLst [$1] }
        | expr_list ',' a_expr { MyLst $ (tkMyList $1) ++ [$3] }

extract_list    :: { ExtractList }
extract_list
        : extract_arg FROM a_expr { ExtractLst $1 $3 }
        | {- empty -} { ExtractEmpty }  

type_list       :: { TypeList }
type_list
        : type_list_aux { MyLst $1 }

type_list_aux   :: { [Typename] }
type_list_aux
        : type_list_aux ',' Typename { $1 ++ [$3] }
        | Typename { [$1] }     

array_expr_list :: { ArrayExprList }
array_expr_list
        : array_expr_list_aux { MyLst $1 }

array_expr_list_aux     :: { [ArrayExpr] }
array_expr_list_aux
        : array_expr { [$1] }
        | array_expr_list_aux ',' array_expr { $1 ++ [$3] }
        

array_expr      :: { ArrayExpr }
array_expr
        : '[' expr_list ']' { ArrayExp $ Left $2 }
        | '[' array_expr_list ']' { ArrayExp $ Right $2 }

extract_arg     :: { ExtractArg }
extract_arg
        : IDENT { OneOf8 $1 }
        | YEAR { TwoOf8 YEAR }
        | MONTH { ThreeOf8 MONTH }
        | DAY   { FourOf8 DAY }
        | HOUR { FiveOf8 HOUR }
        | MINUTE { SixOf8 MINUTE }
        | SECOND { SevenOf8 SECOND }
        | SCONST { EightOf8 $1 }

overlay_list    :: { OverlayList }
overlay_list
        : a_expr overlay_placing substr_from substr_for { OverLayLst $1 $2 $3 (Just $4) }
        | a_expr overlay_placing substr_from { OverLayLst $1 $2 $3 Nothing }

overlay_placing :: { OverlayPlacing }
overlay_placing
        : PLACING a_expr { OverlayPlace $2 }

position_list   :: { PositionList }
position_list
        : b_expr IN b_expr { PosLst $1 $3 }
        | {- empty -} { PosLstEmpty }

substr_list     :: { SubstrList }
substr_list
        : a_expr substr_from substr_for { SStrFromFor $1 $2 $3 }
        | a_expr substr_for substr_from { SStrFromFor $1 $3 $2 }
        | a_expr substr_from { SStrFrom $1 $2 }
        | a_expr substr_for { SStrFor $1 $2 }
        | expr_list { SStrLst $1 }
        | {- empty -} { SStrEmpty }
        
substr_from     :: { SubstrFrom }
substr_from
        : FROM a_expr { SubstringFrom $2 }

substr_for      :: { SubstrFor }
substr_for
        : FOR a_expr { SubstringFor $2 }

trim_list       :: { TrimList }
trim_list
        : a_expr FROM expr_list { (Just (Just $1,FROM),$3) }
        | FROM expr_list { (Just (Nothing,FROM),$2) }
        | expr_list { (Nothing,$1) }

in_expr :: { InExpr }
in_expr : select_with_parens { InExpSelect $1 }
        | '(' expr_list ')' { InExpLst $2 }

case_expr       :: { CaseExpr }
case_expr
        : CASE case_arg when_clause_list case_default END { CaseExp $2 $3 $4 }

when_clause_list        :: { WhenClauseList }
when_clause_list
-- There must be at least one
        : when_clause { [$1] }
        | when_clause_list when_clause { $1 ++ [$2] }   

when_clause     :: { WhenClause }
when_clause
        : WHEN a_expr THEN a_expr { WhenClauseConst $2 $4 }

case_default    :: { CaseDefault }
case_default
        : ELSE a_expr { CaseDef $ Just $2 }
        | {- empty -} { CaseDef Nothing }

case_arg        :: { CaseArg }
case_arg
        : a_expr { Just $1 }
        | {- empty -} { Nothing }

columnref       :: { Columnref }
columnref
        : relation_name { ColRefRel $1 }
        | relation_name indirection { ColRefRelInd $1 $2 }

indirection_el  :: { IndirectionEl }
indirection_el
        : '.' attr_name { IndAttr $2 }
        | '.' '*' { IndStar }
        | '[' a_expr ']' { IndExp $2 }
        | '[' a_expr ':' a_expr ']' { IndBinExp $2 $4 }

indirection     :: { Indirection }
indirection
        : indirection_el { [$1] }
        | indirection indirection_el { $1 ++ [$2] }

opt_indirection :: { OptIndirection }
opt_indirection
        : {- empty -} { [] }
        | opt_indirection indirection_el { $1 ++ [$2] } 

opt_asymmetric  :: { OptAsymmetric }
opt_asymmetric
        : ASYMMETRIC { Just ASYMMETRIC }
        | {- empty -} { Nothing }

target_list     :: { TargetList }
target_list
        : target_list_aux { MyLst $1 }

target_list_aux :: { [TargetEl] }
target_list_aux
        : target_el { [$1] }
        | target_list_aux ',' target_el { $1 ++ [$3] }

target_el       :: { TargetEl }
target_el
        : a_expr AS ColLabel { TargetElAs $1 $3 }
        | a_expr { TargetElExp $1 }
        | '*' { TargetElStar }

ColId   :: { ColId }
ColId   : IDENT { OneOf3 $1 }
        | unreserved_keyword { TwoOf3 $1 }
        | col_name_keyword { ThreeOf3 $1 }

type_name       :: { TypeName }
type_name
        : IDENT { Left $1 }
        | unreserved_keyword { Right $1 }

function_name   :: { FunctionName }
function_name
        : IDENT { OneOf3 $1 }
        | unreserved_keyword { TwoOf3 $1 }
        | func_name_keyword { ThreeOf3 $1 }

ColLabel        :: { ColLabel }
ColLabel
        : IDENT { OneOf5 $1 }
        | unreserved_keyword { TwoOf5 $1 }
        | col_name_keyword { ThreeOf5 $1 }
        | func_name_keyword { FourOf5 $1 }
        | reserved_keyword { FiveOf5 $1 }

unreserved_keyword      :: { UnreservedKeyword }
unreserved_keyword
        : ABORT { UnreservedKeywordABORT }
        | ABSOLUTE { UnreservedKeywordABSOLUTE }
        | ACCESS { UnreservedKeywordACCESS } 
        | ACTION { UnreservedKeywordACTION } 
        | ADD { UnreservedKeywordADD } 
        | ADMIN { UnreservedKeywordADMIN } 
        | AFTER { UnreservedKeywordAFTER } 
        | AGGREGATE { UnreservedKeywordAGGREGATE } 
        | ALSO { UnreservedKeywordALSO } 
        | ALTER { UnreservedKeywordALTER } 
        | ASSERTION { UnreservedKeywordASSERTION } 
        | ASSIGNMENT { UnreservedKeywordASSIGNMENT } 
        | AT { UnreservedKeywordAT } 
        | BACKWARD { UnreservedKeywordBACKWARD } 
        | BEFORE { UnreservedKeywordBEFORE } 
        | BEGIN { UnreservedKeywordBEGIN }
        | BY { UnreservedKeywordBY } 
        | CACHE { UnreservedKeywordCACHE } 
        | CALLED { UnreservedKeywordCALLED } 
        | CASCADE { UnreservedKeywordCASCADE } 
        | CHAIN { UnreservedKeywordCHAIN } 
        | CHARACTERISTICS { UnreservedKeywordCHARACTERISTICS } 
        | CHECKPOINT { UnreservedKeywordCHECKPOINT } 
        | CLASS { UnreservedKeywordCLASS } 
        | CLOSE { UnreservedKeywordCLOSE } 
        | CLUSTER { UnreservedKeywordCLUSTER } 
        | COMMENT { UnreservedKeywordCOMMENT } 
        | COMMIT { UnreservedKeywordCOMMIT } 
        | COMMITTED { UnreservedKeywordCOMMITTED } 
        | CONNECTION { UnreservedKeywordCONNECTION } 
        | CONSTRAINTS { UnreservedKeywordCONSTRAINTS } 
        | CONVERSION { UnreservedKeywordCONVERSION }
        | COPY { UnreservedKeywordCOPY } 
        | CREATEDB { UnreservedKeywordCREATEDB } 
        | CREATEROLE { UnreservedKeywordCREATEROLE } 
        | CREATEUSER { UnreservedKeywordCREATEUSER } 
        | CSV { UnreservedKeywordCSV } 
        | CURSOR { UnreservedKeywordCURSOR } 
        | CYCLE { UnreservedKeywordCYCLE } 
        | DATABASE { UnreservedKeywordDATABASE } 
        | DAY { UnreservedKeywordDAY } 
        | DEALLOCATE { UnreservedKeywordDEALLOCATE } 
        | DECLARE { UnreservedKeywordDECLARE } 
        | DEFAULTS { UnreservedKeywordDEFAULTS } 
        | DEFERRED { UnreservedKeywordDEFERRED } 
        | DEFINER { UnreservedKeywordDEFINER } 
        | DELETE { UnreservedKeywordDELETE }
        | DELIMITER { UnreservedKeywordDELIMITER } 
        | DELIMITERS { UnreservedKeywordDELIMITERS } 
        | DISABLE { UnreservedKeywordDISABLE }
        | DOMAIN { UnreservedKeywordDOMAIN }
        | DOUBLE { UnreservedKeywordDOUBLE }
        | DROP { UnreservedKeywordDROP } 
        | EACH { UnreservedKeywordEACH } 
        | ENABLE { UnreservedKeywordENABLE }
        | ENCODING { UnreservedKeywordENCODING } 
        | ENCRYPTED { UnreservedKeywordENCRYPTED } 
        | ESCAPE { UnreservedKeywordESCAPE } 
        | EXCLUDING { UnreservedKeywordEXCLUDING } 
        | EXCLUSIVE { UnreservedKeywordEXCLUSIVE } 
        | EXECUTE { UnreservedKeywordEXECUTE } 
        | EXPLAIN { UnreservedKeywordEXPLAIN } 
        | EXTERNAL { UnreservedKeywordEXTERNAL } 
        | FETCH { UnreservedKeywordFETCH } 
        | FIRST { UnreservedKeywordFIRST }
        | FORCE { UnreservedKeywordFORCE } 
        | FORWARD { UnreservedKeywordFORWARD } 
        | FUNCTION { UnreservedKeywordFUNCTION } 
        | GLOBAL { UnreservedKeywordGLOBAL }  
        | GRANTED { UnreservedKeywordGRANTED } 
        | HANDLER { UnreservedKeywordHANDLER } 
        | HEADER { UnreservedKeywordHEADER } 
        | HOLD { UnreservedKeywordHOLD } 
        | HOUR { UnreservedKeywordHOUR }
        | IMMEDIATE { UnreservedKeywordIMMEDIATE } 
        | IMMUTABLE { UnreservedKeywordIMMUTABLE } 
        | IMPLICIT { UnreservedKeywordIMPLICIT }
        | INCLUDING { UnreservedKeywordINCLUDING } 
        | INCREMENT { UnreservedKeywordINCREMENT } 
        | INDEX { UnreservedKeywordINDEX } 
        | INHERIT { UnreservedKeywordINHERIT } 
        | INHERITS { UnreservedKeywordINHERITS } 
        | INPUT { UnreservedKeywordINPUT } 
        | INSENSITIVE { UnreservedKeywordINSENSITIVE } 
        | INSERT { UnreservedKeywordINSERT } 
        | INSTEAD { UnreservedKeywordINSTEAD } 
        | INVOKER { UnreservedKeywordINVOKER } 
        | ISOLATION { UnreservedKeywordISOLATION } 
        | KEY { UnreservedKeywordKEY } 
        | LANCOMPILER { UnreservedKeywordLANCOMPILER } 
        | LANGUAGE { UnreservedKeywordLANGUAGE } 
        | LARGE { UnreservedKeywordLARGE }
        | LAST { UnreservedKeywordLAST }
        | LEVEL { UnreservedKeywordLEVEL } 
        | LISTEN { UnreservedKeywordLISTEN } 
        | LOAD { UnreservedKeywordLOAD } 
        | LOCAL { UnreservedKeywordLOCAL } 
        | LOCATION { UnreservedKeywordLOCATION } 
        | LOCK { UnreservedKeywordLOCK }
        | LOGIN { UnreservedKeywordLOGIN }
        | MATCH { UnreservedKeywordMATCH } 
        | MAXVALUE { UnreservedKeywordMAXVALUE } 
        | MINUTE { UnreservedKeywordMINUTE }
        | MINVALUE { UnreservedKeywordMINVALUE } 
        | MODE { UnreservedKeywordMODE } 
        | MONTH { UnreservedKeywordMONTH }
        | MOVE { UnreservedKeywordMOVE } 
        | NAMES { UnreservedKeywordNAMES } 
        | NEXT { UnreservedKeywordNEXT } 
        | NO { UnreservedKeywordNO } 
        | NOCREATEDB { UnreservedKeywordNOCREATEDB } 
        | NOCREATEROLE { UnreservedKeywordNOCREATEROLE } 
        | NOCREATEUSER { UnreservedKeywordNOCREATEUSER } 
        | NOINHERIT { UnreservedKeywordNOINHERIT } 
        | NOLOGIN { UnreservedKeywordNOLOGIN }
        | NOSUPERUSER { UnreservedKeywordNOSUPERUSER } 
        | NOTHING { UnreservedKeywordNOTHING } 
        | NOTIFY { UnreservedKeywordNOTIFY } 
        | NOWAIT { UnreservedKeywordNOWAIT } 
        | OBJECT { UnreservedKeywordOBJECT }
        | OF { UnreservedKeywordOF } 
        | OIDS { UnreservedKeywordOIDS } 
        | OPERATOR { UnreservedKeywordOPERATOR } 
        | OPTION { UnreservedKeywordOPTION } 
        | OWNER { UnreservedKeywordOWNER } 
        | PARTIAL { UnreservedKeywordPARTIAL } 
        | PASSWORD { UnreservedKeywordPASSWORD } 
        | PREPARE { UnreservedKeywordPREPARE } 
        | PREPARED { UnreservedKeywordPREPARED } 
        | PRESERVE { UnreservedKeywordPRESERVE } 
        | PRIOR { UnreservedKeywordPRIOR } 
        | PRIVILEGES { UnreservedKeywordPRIVILEGES } 
        | PROCEDURAL { UnreservedKeywordPROCEDURAL } 
        | PROCEDURE { UnreservedKeywordPROCEDURE } 
        | QUOTE { UnreservedKeywordQUOTE } 
        | READ { UnreservedKeywordREAD } 
        | RECHECK { UnreservedKeywordRECHECK } 
        | REINDEX { UnreservedKeywordREINDEX } 
        | RELATIVE { UnreservedKeywordRELATIVE }
        | RELEASE { UnreservedKeywordRELEASE } 
        | RENAME { UnreservedKeywordRENAME } 
        | REPEATABLE { UnreservedKeywordREPEATABLE } 
        | REPLACE { UnreservedKeywordREPLACE } 
        | RESET { UnreservedKeywordRESET } 
        | RESTART { UnreservedKeywordRESTART } 
        | RESTRICT { UnreservedKeywordRESTRICT } 
        | RETURNS { UnreservedKeywordRETURNS } 
        | REVOKE { UnreservedKeywordREVOKE } 
        | ROLE { UnreservedKeywordROLE } 
        | ROLLBACK { UnreservedKeywordROLLBACK } 
        | ROWS { UnreservedKeywordROWS } 
        | RULE { UnreservedKeywordRULE } 
        | SAVEPOINT { UnreservedKeywordSAVEPOINT } 
        | SCHEMA { UnreservedKeywordSCHEMA } 
        | SCROLL { UnreservedKeywordSCROLL } 
        | SECOND { UnreservedKeywordSECOND }
        | SECURITY { UnreservedKeywordSECURITY } 
        | SEQUENCE { UnreservedKeywordSEQUENCE } 
        | SERIALIZABLE { UnreservedKeywordSERIALIZABLE } 
        | SESSION { UnreservedKeywordSESSION } 
        | SET { UnreservedKeywordSET } 
        | SHARE { UnreservedKeywordSHARE } 
        | SHOW { UnreservedKeywordSHOW } 
        | SIMPLE { UnreservedKeywordSIMPLE } 
        | STABLE { UnreservedKeywordSTABLE } 
        | START { UnreservedKeywordSTART } 
        | STATEMENT { UnreservedKeywordSTATEMENT } 
        | STATISTICS { UnreservedKeywordSTATISTICS } 
        | STDIN { UnreservedKeywordSTDIN } 
        | STDOUT { UnreservedKeywordSTDOUT } 
        | STORAGE { UnreservedKeywordSTORAGE } 
        | SUPERUSER { UnreservedKeywordSUPERUSER }
        | SYSID { UnreservedKeywordSYSID } 
        | SYSTEM { UnreservedKeywordSYSTEM }
        | STRICT { UnreservedKeywordSTRICT }
        | TABLESPACE { UnreservedKeywordTABLESPACE } 
        | TEMP { UnreservedKeywordTEMP } 
        | TEMPLATE { UnreservedKeywordTEMPLATE } 
        | TEMPORARY { UnreservedKeywordTEMPORARY } 
        | TOAST { UnreservedKeywordTOAST } 
        | TRANSACTION { UnreservedKeywordTRANSACTION } 
        | TRIGGER { UnreservedKeywordTRIGGER } 
        | TRUNCATE { UnreservedKeywordTRUNCATE } 
        | TRUSTED { UnreservedKeywordTRUSTED } 
        | TYPE { UnreservedKeywordTYPE }
        | UNCOMMITTED { UnreservedKeywordUNCOMMITTED } 
        | UNENCRYPTED { UnreservedKeywordUNENCRYPTED } 
        | UNKNOWN { UnreservedKeywordUNKNOWN } 
        | UNLISTEN { UnreservedKeywordUNLISTEN } 
        | UNTIL { UnreservedKeywordUNTIL } 
        | UPDATE { UnreservedKeywordUPDATE } 
        | VACUUM { UnreservedKeywordVACUUM } 
        | VALID { UnreservedKeywordVALID } 
        | VALIDATOR { UnreservedKeywordVALIDATOR } 
        | VALUES { UnreservedKeywordVALUES } 
        | VARYING { UnreservedKeywordVARYING } 
        | VIEW { UnreservedKeywordVIEW } 
        | VOLATILE { UnreservedKeywordVOLATILE } 
        | WITH { UnreservedKeywordWITH } 
        | WITHOUT { UnreservedKeywordWITHOUT } 
        | WORK { UnreservedKeywordWORK } 
        | WRITE { UnreservedKeywordWRITE } 
        | YEAR { UnreservedKeywordYEAR }
        | ZONE { UnreservedKeywordZONE } 

col_name_keyword        :: { ColNameKeyword }
col_name_keyword
        : BIGINT { ColNameKeywordBIGINT } 
        | BIT { ColNameKeywordBIT } 
        | BOOLEAN { ColNameKeywordBOOLEAN }
        | CHAR { ColNameKeywordCHAR }
        | CHARACTER { ColNameKeywordCHARACTER } 
        | COALESCE { ColNameKeywordCOALESCE } 
        | CONVERT { ColNameKeywordCONVERT } 
        | DEC { ColNameKeywordDEC } 
        | DECIMAL { ColNameKeywordDECIMAL }
        | EXISTS { ColNameKeywordEXISTS } 
        | EXTRACT { ColNameKeywordEXTRACT } 
        | FLOAT { ColNameKeywordFLOAT }
        | GREATEST { ColNameKeywordGREATEST } 
        | INOUT { ColNameKeywordINOUT } 
        | INT { ColNameKeywordINT }
        | INTEGER { ColNameKeywordINTEGER } 
        | INTERVAL { ColNameKeywordINTERVAL } 
        | LEAST { ColNameKeywordLEAST } 
        | NATIONAL { ColNameKeywordNATIONAL } 
        | NCHAR { ColNameKeywordNCHAR } 
        | NONE { ColNameKeywordNONE } 
        | NULLIF { ColNameKeywordNULLIF } 
        | NUMERIC { ColNameKeywordNUMERIC } 
        | OUT { ColNameKeywordOUT }
        | OVERLAY { ColNameKeywordOVERLAY } 
        | POSITION { ColNameKeywordPOSITION } 
        | PRECISION { ColNameKeywordPRECISION } 
        | REAL { ColNameKeywordREAL } 
        | ROW { ColNameKeywordROW } 
        | SETOF { ColNameKeywordSETOF } 
        | SMALLINT { ColNameKeywordSMALLINT } 
        | SUBSTRING { ColNameKeywordSUBSTRING } 
        | TIME { ColNameKeywordTIME } 
        | TIMESTAMP { ColNameKeywordTIMESTAMP } 
        | TREAT { ColNameKeywordTREAT } 
        | TRIM { ColNameKeywordTRIM } 
        | VARCHAR { ColNameKeywordVARCHAR } 

func_name_keyword       :: { FuncNameKeyword }
func_name_keyword
        : AUTHORIZATION { FuncNameAUTHORIZATION } 
        | BETWEEN { FuncNameBETWEEN } 
        | BINARY { FuncNameBINARY } 
        | CROSS { FuncNameCROSS } 
        | FREEZE { FuncNameFREEZE } 
        | FULL { FuncNameFULL } 
        | ILIKE { FuncNameILIKE } 
        | INNER { FuncNameINNER }
        | IS { FuncNameIS } 
        | ISNULL { FuncNameISNULL } 
        | JOIN { FuncNameJOIN } 
        | LEFT { FuncNameLEFT } 
        | LIKE { FuncNameLIKE } 
        | NATURAL { FuncNameNATURAL } 
        | NOTNULL { FuncNameNOTNULL } 
        | OUTER { FuncNameOUTER }
        | OVERLAPS { FuncNameOVERLAPS } 
        | RIGHT { FuncNameRIGHT } 
        | SIMILAR { FuncNameSIMILAR } 
        | VERBOSE { FuncNameVERBOSE } 

reserved_keyword        :: { ReservedKeyword }
reserved_keyword
        : ALL { ReservedKeywordALL }
        | ANALYSE { ReservedKeywordANALYSE }
        | ANALYZE { ReservedKeywordANALYZE }
        | AND { ReservedKeywordAND }
        | ANY { ReservedKeywordANY }
        | ARRAY { ReservedKeywordARRAY }
        | AS { ReservedKeywordAS }
        | ASC { ReservedKeywordASC }
        | ASYMMETRIC { ReservedKeywordASYMMETRIC }
        | BOTH { ReservedKeywordBOTH }
        | CASE { ReservedKeywordCASE }
        | CAST { ReservedKeywordCAST }
        | CHECK { ReservedKeywordCHECK }
        | COLLATE { ReservedKeywordCOLLATE }
        | COLUMN { ReservedKeywordCOLUMN }
        | CONSTRAINT { ReservedKeywordCONSTRAINT }
        | CREATE { ReservedKeywordCREATE }
        | CURRENT_DATE { ReservedKeywordCURRENT_DATE }
        | CURRENT_ROLE { ReservedKeywordCURRENT_ROLE }
        | CURRENT_TIME { ReservedKeywordCURRENT_TIME }
        | CURRENT_TIMESTAMP { ReservedKeywordCURRENT_TIMESTAMP }
        | CURRENT_USER { ReservedKeywordCURRENT_USER }
        | DEFAULT { ReservedKeywordDEFAULT }
        | DEFERRABLE { ReservedKeywordDEFERRABLE }
        | DESC { ReservedKeywordDESC }
        | DISTINCT { ReservedKeywordDISTINCT }
        | DO { ReservedKeywordDO }
        | ELSE { ReservedKeywordELSE }
        | END { ReservedKeywordEND }
        | EXCEPT { ReservedKeywordEXCEPT }
        | FALSE { ReservedKeywordFALSE }
        | FOR { ReservedKeywordFOR }
        | FOREIGN { ReservedKeywordFOREIGN }
        | FROM { ReservedKeywordFROM }
        | GRANT { ReservedKeywordGRANT }
        | GROUP { ReservedKeywordGROUP }
        | HAVING { ReservedKeywordHAVING }
        | IN { ReservedKeywordIN }
        | INITIALLY { ReservedKeywordINITIALLY }
        | INTERSECT { ReservedKeywordINTERSECT }
        | INTO { ReservedKeywordINTO }
        | LEADING { ReservedKeywordLEADING }
        | LIMIT { ReservedKeywordLIMIT }
        | LOCALTIME { ReservedKeywordLOCALTIME }
        | LOCALTIMESTAMP { ReservedKeywordLOCALTIMESTAMP }
        | NEW { ReservedKeywordNEW }
        | NOT { ReservedKeywordNOT }
        | NULL { ReservedKeywordNULL }
        | OFF { ReservedKeywordOFF }
        | OFFSET { ReservedKeywordOFFSET }
        | OLD { ReservedKeywordOLD }
        | ON { ReservedKeywordON }
        | ONLY { ReservedKeywordONLY }
        | OR { ReservedKeywordOR }
        | ORDER { ReservedKeywordORDER }
        | PLACING { ReservedKeywordPLACING }
        | PRIMARY { ReservedKeywordPRIMARY }
        | REFERENCES { ReservedKeywordREFERENCES }
        | SELECT { ReservedKeywordSELECT }
        | SESSION_USER { ReservedKeywordSESSION_USER }
        | SOME { ReservedKeywordSOME }
        | SYMMETRIC { ReservedKeywordSYMMETRIC }
        | TABLE { ReservedKeywordTABLE }
        | THEN { ReservedKeywordTHEN }
        | TO { ReservedKeywordTO }
        | TRAILING { ReservedKeywordTRAILING }
        | TRUE { ReservedKeywordTRUE }
        | UNION { ReservedKeywordUNION }
        | UNIQUE { ReservedKeywordUNIQUE }
        | USER { ReservedKeywordUSER }
        | USING { ReservedKeywordUSING }
        | WHEN { ReservedKeywordWHEN }
        | WHERE { ReservedKeywordWHERE }

SpecialRuleRelation     :: { SpecialRuleRelation }
SpecialRuleRelation
        : OLD { Left OLD }
        | NEW { Right NEW }

qualified_name_list     :: { QualifiedNameList }
qualified_name_list
        : qualified_name_list_aux { MyLst $1 }

qualified_name_list_aux :: { [QualifiedName] }
qualified_name_list_aux
        : qualified_name { [$1] }
        | qualified_name_list_aux ',' qualified_name { $1 ++ [$3] }

qualified_name  :: { QualifiedName }
qualified_name
        : relation_name { QualNameRel $1 }
        | relation_name indirection { QualNameRelInd $1 $2 }

name_list       :: { NameList }
name_list
        : name_list_aux { MyLst $1 }

name_list_aux   :: { [Name] }
name_list_aux
        : name { [$1] }
        | name_list_aux ',' name { $1 ++ [$3] }

name    :: { Name }
name    : ColId { $1 }

relation_name   :: { RelationName }
relation_name
        : SpecialRuleRelation { Left $1 }
        | ColId { Right $1 }

attr_name       :: { AttrName }
attr_name
        : ColLabel { $1 }

func_name       :: { FuncName }
func_name
        : function_name { FuncNameFunc $1 }
        | relation_name indirection { FuncNameRelInd $1 $2 }

Iconst  :: { Iconst }
Iconst  : ICONST { $1 }

Sconst  :: { Sconst }
Sconst  : SCONST { $1 }

AexprConst      :: { AExprConst }
AexprConst
        : Iconst { AExpCI $1 }
        | FCONST { AExpCF $1 }
        | Sconst { AExpCS $1 }
        | BCONST { AExpCB $1 }
        | XCONST { AExpCX $1 }
        | ConstTypename Sconst { AExpCType $1 $2 }
        | ConstInterval Sconst opt_interval { AExpCInt $1 Nothing $2 $3 }
        | ConstInterval '(' Iconst ')' Sconst opt_interval { AExpCInt $1 (Just $3) $5 $6 }
        | TRUE { AExpCTrue }
        | FALSE { AExpCFalse }
        | NULL { AExpCNull }
                
any_name        :: { AnyName }
any_name
        : ColId { ($1,Nothing) }
        | ColId attrs { ($1,Just $2) }

attrs   :: { Attrs }
attrs   : attrs_aux { AttrsCont $1 }

attrs_aux       :: { [AttrName] }       
attrs_aux
        : '.' attr_name { [$2] }
        | attrs_aux '.' attr_name { $1 ++ [$3] }

any_operator    :: { AnyOperator }
any_operator
        : all_Op { AnyOpAll $1 }
        | ColId '.' any_operator { AnyOpCol $1 $3 }

opt_nowait      :: { OptNowait }
opt_nowait
        : NOWAIT { Just NOWAIT }
        | {- empty -} { Nothing }

insert_target_list      :: { InsertTargetList }
insert_target_list
        : insert_target_list_aux { MyLst $1 }
        
insert_target_list_aux  :: { [InsertTargetEl] }
insert_target_list_aux
        : insert_target_el { [$1] }
        | insert_target_list_aux ',' insert_target_el { $1 ++ [$3] }

key_update      :: { KeyUpdate }
key_update
        : ON UPDATE key_action { OnUpdate $3 }
        
key_delete      :: { KeyDelete }
key_delete
        : ON DELETE key_action { OnDelete $3 }
        
key_action      :: { KeyAction }
key_action
        : NO ACTION { KeyNoAction }
        | RESTRICT { KeyRestrict }
        | CASCADE { KeyCascade }
        | SET NULL { KeySetNull }
        | SET DEFAULT { KeySetDefault }
        
insert_target_el        :: { InsertTargetEl }
insert_target_el
        : a_expr { Left $1 }
        | DEFAULT { Right DEFAULT }
        
ConstraintAttributeSpec :: { ConstraintAttributeSpec }
ConstraintAttributeSpec
        : ConstraintDeferrabilitySpec { (Just $1,Nothing) }
        | ConstraintDeferrabilitySpec ConstraintTimeSpec { (Just $1,Just $2) }
        | ConstraintTimeSpec { (Nothing,Just $1) }
        | ConstraintTimeSpec ConstraintDeferrabilitySpec { (Just $2,Just $1) }
        | {- empty -} { (Nothing,Nothing) }

ConstraintDeferrabilitySpec     :: { ConstraintDeferrabilitySpec }      
ConstraintDeferrabilitySpec
        : NOT DEFERRABLE { Left (NOT,DEFERRABLE) }
        | DEFERRABLE { Right DEFERRABLE }
        
ConstraintTimeSpec      :: { ConstraintTimeSpec }
ConstraintTimeSpec
        : INITIALLY IMMEDIATE { CnstrTimeSpec $ Left IMMEDIATE }
        | INITIALLY DEFERRED { CnstrTimeSpec $ Right DEFERRED }

OptInherit      :: { OptInherit }
OptInherit
        : INHERITS '(' qualified_name_list ')' { OptInherits $ Just $3 }
        | {-EMPTY-} { OptInherits Nothing }
        
OptWithOids     :: { OptWithOids }
OptWithOids
        : WITH OIDS { WithOids }
        | WITHOUT OIDS { WithoutOids }
        | {- empty -} { NoOids }
        
OnCommitOption  :: { OnCommitOption }
OnCommitOption
        : ON COMMIT DROP { Just OnCommitDrop }
        | ON COMMIT DELETE ROWS { Just OnCommitDeleteRows }
        | ON COMMIT PRESERVE ROWS { Just OnCommitPreserveRows }
        | {- empty -} { Nothing }
        
OptTableSpace   :: { OptTableSpace }
OptTableSpace
        : TABLESPACE name { OptTableSpaceConst $ Just $2 }
        | {- empty -} { OptTableSpaceConst Nothing }
        

OptConsTableSpace       :: { OptConsTableSpace }
OptConsTableSpace
        : USING INDEX TABLESPACE name { OptConsTableSpaceConst $ Just $4 }
        | {- empty -} { OptConsTableSpaceConst Nothing }

{
happyError :: [Token] -> a
happyError (x:_) = error $ "Parser Error: " ++ show x
-- ^ returns the first non-valid token

-- | parses SQL string content to 'ASTPostgreSQL'
astPostgreSQL :: String -> ASTPostgreSQL
astPostgreSQL str =
        case (lexPostgreSQL str) of
         (Left err)   -> error ("Lexer error: " ++ show err)
         (Right toks) -> parsePostgreSQL toks
}

Theme by Vikram Singh | Powered by WebSVN v2.3.3