comparison src/urweb.grm @ 709:0406e9cccb72

FOREIGN KEY, without ability to link NULL to NOT NULL (and with some lingering problems in row inference)
author Adam Chlipala <adamc@hcoop.net>
date Tue, 07 Apr 2009 18:47:47 -0400
parents d8217b4cb617
children 71409a4ccb67
comparison
equal deleted inserted replaced
708:1a317a707d71 709:0406e9cccb72
172 fun tagIn bt = 172 fun tagIn bt =
173 case bt of 173 case bt of
174 "table" => "tabl" 174 "table" => "tabl"
175 | _ => bt 175 | _ => bt
176 176
177 datatype prop_kind = Delete | Update
178
177 %% 179 %%
178 %header (functor UrwebLrValsFn(structure Token : TOKEN)) 180 %header (functor UrwebLrValsFn(structure Token : TOKEN))
179 181
180 %term 182 %term
181 EOF 183 EOF
206 | COUNT | AVG | SUM | MIN | MAX 208 | COUNT | AVG | SUM | MIN | MAX
207 | ASC | DESC 209 | ASC | DESC
208 | INSERT | INTO | VALUES | UPDATE | SET | DELETE | NULL | IS 210 | INSERT | INTO | VALUES | UPDATE | SET | DELETE | NULL | IS
209 | CURRENT_TIMESTAMP 211 | CURRENT_TIMESTAMP
210 | NE | LT | LE | GT | GE 212 | NE | LT | LE | GT | GE
211 | CCONSTRAINT | UNIQUE | PRIMARY | KEY 213 | CCONSTRAINT | UNIQUE | PRIMARY | FOREIGN | KEY | ON | NO | ACTION | RESTRICT | CASCADE | REFERENCES
212 214
213 %nonterm 215 %nonterm
214 file of decl list 216 file of decl list
215 | decls of decl list 217 | decls of decl list
216 | decl of decl list 218 | decl of decl list
227 | commaOpt of unit 229 | commaOpt of unit
228 230
229 | cst of exp 231 | cst of exp
230 | csts of exp 232 | csts of exp
231 | cstopt of exp 233 | cstopt of exp
234
235 | pmode of prop_kind * exp
236 | pkind of prop_kind
237 | prule of exp
238 | pmodes of (prop_kind * exp) list
232 239
233 | sgn of sgn 240 | sgn of sgn
234 | sgntm of sgn 241 | sgntm of sgn
235 | sgi of sgn_item 242 | sgi of sgn_item
236 | sgis of sgn_item list 243 | sgis of sgn_item list
501 val e = (ECApp (e, (CRecord (#2 tnames), loc)), loc) 508 val e = (ECApp (e, (CRecord (#2 tnames), loc)), loc)
502 val e = (EDisjointApp e, loc) 509 val e = (EDisjointApp e, loc)
503 in 510 in
504 (EDisjointApp e, loc) 511 (EDisjointApp e, loc)
505 end) 512 end)
513
514 | FOREIGN KEY tnames REFERENCES texp LPAREN tnames' RPAREN pmodes
515 (let
516 val loc = s (FOREIGNleft, pmodesright)
517
518 val mat = ListPair.foldrEq
519 (fn ((nm1, _), (nm2, _), mat) =>
520 let
521 val e = (EVar (["Basis"], "mat_cons", Infer), loc)
522 val e = (ECApp (e, nm1), loc)
523 val e = (ECApp (e, nm2), loc)
524 val e = (EDisjointApp e, loc)
525 val e = (EDisjointApp e, loc)
526 in
527 (EApp (e, mat), loc)
528 end)
529 (EVar (["Basis"], "mat_nil", Infer), loc)
530 (#1 tnames :: #2 tnames, #1 tnames' :: #2 tnames')
531
532 fun findMode mode =
533 let
534 fun findMode' pmodes =
535 case pmodes of
536 [] => (EVar (["Basis"], "no_action", Infer), loc)
537 | (mode', rule) :: pmodes' =>
538 if mode' = mode then
539 (if List.exists (fn (mode', _) => mode' = mode)
540 pmodes' then
541 ErrorMsg.errorAt loc "Duplicate propagation rule"
542 else
543 ();
544 rule)
545 else
546 findMode' pmodes'
547 in
548 findMode' pmodes
549 end
550
551 val e = (EVar (["Basis"], "foreign_key", Infer), loc)
552 val e = (EApp (e, mat), loc)
553 val e = (EApp (e, texp), loc)
554 in
555 (EApp (e, (ERecord [((CName "OnDelete", loc),
556 findMode Delete),
557 ((CName "OnUpdate", loc),
558 findMode Update)], loc)), loc)
559 end)
560
506 | LBRACE eexp RBRACE (eexp) 561 | LBRACE eexp RBRACE (eexp)
507 562
508 tnameW : tname (let 563 tnameW : tname (let
509 val loc = s (tnameleft, tnameright) 564 val loc = s (tnameleft, tnameright)
510 in 565 in
514 tnames : tnameW (tnameW, []) 569 tnames : tnameW (tnameW, [])
515 | LPAREN tnames' RPAREN (tnames') 570 | LPAREN tnames' RPAREN (tnames')
516 571
517 tnames': tnameW (tnameW, []) 572 tnames': tnameW (tnameW, [])
518 | tnameW COMMA tnames' (#1 tnames', tnameW :: #2 tnames') 573 | tnameW COMMA tnames' (#1 tnames', tnameW :: #2 tnames')
574
575 pmode : ON pkind prule (pkind, prule)
576
577 pkind : DELETE (Delete)
578 | UPDATE (Update)
579
580 prule : NO ACTION (EVar (["Basis"], "no_action", Infer), s (NOleft, ACTIONright))
581 | RESTRICT (EVar (["Basis"], "restrict", Infer), s (RESTRICTleft, RESTRICTright))
582 | CASCADE (EVar (["Basis"], "cascade", Infer), s (CASCADEleft, CASCADEright))
583 | SET NULL (EVar (["Basis"], "set_null", Infer), s (SETleft, NULLright))
584
585 pmodes : ([])
586 | pmode pmodes (pmode :: pmodes)
519 587
520 commaOpt: () 588 commaOpt: ()
521 | COMMA () 589 | COMMA ()
522 590
523 pkopt : (EVar (["Basis"], "no_primary_key", Infer), ErrorMsg.dummySpan) 591 pkopt : (EVar (["Basis"], "no_primary_key", Infer), ErrorMsg.dummySpan)