comparison lib/ur/basis.urs @ 1394:d328983dc5a6

Allow subqueries to reference aggregate-only columns of free tables; treat non-COUNT aggregate functions as possibly returning NULL
author Adam Chlipala <adam@chlipala.net>
date Sat, 15 Jan 2011 14:53:13 -0500
parents 65fbb250b875
children 5f4fee8a4dcd
comparison
equal deleted inserted replaced
1393:802c179dac1f 1394:d328983dc5a6
289 -> sql_constraint fs [] 289 -> sql_constraint fs []
290 290
291 291
292 (*** Queries *) 292 (*** Queries *)
293 293
294 con sql_query :: {{Type}} -> {{Type}} -> {Type} -> Type 294 con sql_query :: {{Type}} -> {{Type}} -> {{Type}} -> {Type} -> Type
295 con sql_query1 :: {{Type}} -> {{Type}} -> {{Type}} -> {Type} -> Type 295 con sql_query1 :: {{Type}} -> {{Type}} -> {{Type}} -> {{Type}} -> {Type} -> Type
296 296
297 con sql_subset :: {{Type}} -> {{Type}} -> Type 297 con sql_subset :: {{Type}} -> {{Type}} -> Type
298 val sql_subset : keep_drop :: {({Type} * {Type})} 298 val sql_subset : keep_drop :: {({Type} * {Type})}
299 -> sql_subset 299 -> sql_subset
300 (map (fn fields :: ({Type} * {Type}) => fields.1 ++ fields.2) keep_drop) 300 (map (fn fields :: ({Type} * {Type}) => fields.1 ++ fields.2) keep_drop)
312 val sql_from_nil : free ::: {{Type}} -> sql_from_items free [] 312 val sql_from_nil : free ::: {{Type}} -> sql_from_items free []
313 val sql_from_table : free ::: {{Type}} -> t ::: Type -> fs ::: {Type} 313 val sql_from_table : free ::: {{Type}} -> t ::: Type -> fs ::: {Type}
314 -> fieldsOf t fs -> name :: Name 314 -> fieldsOf t fs -> name :: Name
315 -> t -> sql_from_items free [name = fs] 315 -> t -> sql_from_items free [name = fs]
316 val sql_from_query : free ::: {{Type}} -> fs ::: {Type} -> name :: Name 316 val sql_from_query : free ::: {{Type}} -> fs ::: {Type} -> name :: Name
317 -> sql_query free [] fs 317 -> sql_query free [] [] fs
318 -> sql_from_items free [name = fs] 318 -> sql_from_items free [name = fs]
319 val sql_from_comma : free ::: {{Type}} -> tabs1 ::: {{Type}} -> tabs2 ::: {{Type}} 319 val sql_from_comma : free ::: {{Type}} -> tabs1 ::: {{Type}} -> tabs2 ::: {{Type}}
320 -> [tabs1 ~ tabs2] 320 -> [tabs1 ~ tabs2]
321 => sql_from_items free tabs1 -> sql_from_items free tabs2 321 => sql_from_items free tabs1 -> sql_from_items free tabs2
322 -> sql_from_items free (tabs1 ++ tabs2) 322 -> sql_from_items free (tabs1 ++ tabs2)
351 -> sql_from_items free (map (map (fn p :: (Type * Type) => p.1)) tabs2) 351 -> sql_from_items free (map (map (fn p :: (Type * Type) => p.1)) tabs2)
352 -> sql_exp (free ++ map (map (fn p :: (Type * Type) => p.1)) (tabs1 ++ tabs2)) [] [] bool 352 -> sql_exp (free ++ map (map (fn p :: (Type * Type) => p.1)) (tabs1 ++ tabs2)) [] [] bool
353 -> sql_from_items free (map (map (fn p :: (Type * Type) => p.2)) (tabs1 ++ tabs2)) 353 -> sql_from_items free (map (map (fn p :: (Type * Type) => p.2)) (tabs1 ++ tabs2))
354 354
355 val sql_query1 : free ::: {{Type}} 355 val sql_query1 : free ::: {{Type}}
356 -> afree ::: {{Type}}
356 -> tables ::: {{Type}} 357 -> tables ::: {{Type}}
357 -> grouped ::: {{Type}} 358 -> grouped ::: {{Type}}
358 -> selectedFields ::: {{Type}} 359 -> selectedFields ::: {{Type}}
359 -> selectedExps ::: {Type} 360 -> selectedExps ::: {Type}
360 -> empties :: {Unit} 361 -> empties :: {Unit}
361 -> [free ~ tables] 362 -> [free ~ tables]
362 => [free ~ grouped] 363 => [free ~ grouped]
364 => [afree ~ tables]
363 => [empties ~ selectedFields] 365 => [empties ~ selectedFields]
364 => {Distinct : bool, 366 => {Distinct : bool,
365 From : sql_from_items free tables, 367 From : sql_from_items free tables,
366 Where : sql_exp (free ++ tables) [] [] bool, 368 Where : sql_exp (free ++ tables) afree [] bool,
367 GroupBy : sql_subset tables grouped, 369 GroupBy : sql_subset tables grouped,
368 Having : sql_exp (free ++ grouped) tables [] bool, 370 Having : sql_exp (free ++ grouped) (afree ++ tables) [] bool,
369 SelectFields : sql_subset grouped (map (fn _ => []) empties ++ selectedFields), 371 SelectFields : sql_subset grouped (map (fn _ => []) empties ++ selectedFields),
370 SelectExps : $(map (sql_exp (free ++ grouped) tables []) 372 SelectExps : $(map (sql_exp (free ++ grouped) (afree ++ tables) [])
371 selectedExps) } 373 selectedExps) }
372 -> sql_query1 free tables selectedFields selectedExps 374 -> sql_query1 free afree tables selectedFields selectedExps
373 375
374 type sql_relop 376 type sql_relop
375 val sql_union : sql_relop 377 val sql_union : sql_relop
376 val sql_intersect : sql_relop 378 val sql_intersect : sql_relop
377 val sql_except : sql_relop 379 val sql_except : sql_relop
378 val sql_relop : free ::: {{Type}} 380 val sql_relop : free ::: {{Type}}
381 -> afree ::: {{Type}}
379 -> tables1 ::: {{Type}} 382 -> tables1 ::: {{Type}}
380 -> tables2 ::: {{Type}} 383 -> tables2 ::: {{Type}}
381 -> selectedFields ::: {{Type}} 384 -> selectedFields ::: {{Type}}
382 -> selectedExps ::: {Type} 385 -> selectedExps ::: {Type}
383 -> sql_relop 386 -> sql_relop
384 -> sql_query1 free tables1 selectedFields selectedExps 387 -> sql_query1 free afree tables1 selectedFields selectedExps
385 -> sql_query1 free tables2 selectedFields selectedExps 388 -> sql_query1 free afree tables2 selectedFields selectedExps
386 -> sql_query1 free [] selectedFields selectedExps 389 -> sql_query1 free afree [] selectedFields selectedExps
387 val sql_forget_tables : free ::: {{Type}} -> tables ::: {{Type}} -> selectedFields ::: {{Type}} -> selectedExps ::: {Type} 390 val sql_forget_tables : free ::: {{Type}} -> afree ::: {{Type}} -> tables ::: {{Type}} -> selectedFields ::: {{Type}} -> selectedExps ::: {Type}
388 -> sql_query1 free tables selectedFields selectedExps 391 -> sql_query1 free afree tables selectedFields selectedExps
389 -> sql_query1 free [] selectedFields selectedExps 392 -> sql_query1 free afree [] selectedFields selectedExps
390 393
391 type sql_direction 394 type sql_direction
392 val sql_asc : sql_direction 395 val sql_asc : sql_direction
393 val sql_desc : sql_direction 396 val sql_desc : sql_direction
394 397
406 type sql_offset 409 type sql_offset
407 val sql_no_offset : sql_offset 410 val sql_no_offset : sql_offset
408 val sql_offset : int -> sql_offset 411 val sql_offset : int -> sql_offset
409 412
410 val sql_query : free ::: {{Type}} 413 val sql_query : free ::: {{Type}}
414 -> afree ::: {{Type}}
411 -> tables ::: {{Type}} 415 -> tables ::: {{Type}}
412 -> selectedFields ::: {{Type}} 416 -> selectedFields ::: {{Type}}
413 -> selectedExps ::: {Type} 417 -> selectedExps ::: {Type}
414 -> [free ~ tables] 418 -> [free ~ tables]
415 => {Rows : sql_query1 free tables selectedFields selectedExps, 419 => {Rows : sql_query1 free afree tables selectedFields selectedExps,
416 OrderBy : sql_order_by (free ++ tables) selectedExps, 420 OrderBy : sql_order_by (free ++ tables) selectedExps,
417 Limit : sql_limit, 421 Limit : sql_limit,
418 Offset : sql_offset} 422 Offset : sql_offset}
419 -> sql_query free selectedFields selectedExps 423 -> sql_query free afree selectedFields selectedExps
420 424
421 val sql_field : otherTabs ::: {{Type}} -> otherFields ::: {Type} 425 val sql_field : otherTabs ::: {{Type}} -> otherFields ::: {Type}
422 -> fieldType ::: Type -> agg ::: {{Type}} 426 -> fieldType ::: Type -> agg ::: {{Type}}
423 -> exps ::: {Type} 427 -> exps ::: {Type}
424 -> tab :: Name -> field :: Name 428 -> tab :: Name -> field :: Name
491 495
492 class sql_summable 496 class sql_summable
493 val sql_summable_int : sql_summable int 497 val sql_summable_int : sql_summable int
494 val sql_summable_float : sql_summable float 498 val sql_summable_float : sql_summable float
495 val sql_summable_option : t ::: Type -> sql_summable t -> sql_summable (option t) 499 val sql_summable_option : t ::: Type -> sql_summable t -> sql_summable (option t)
496 val sql_avg : t ::: Type -> sql_summable t -> sql_aggregate t t 500 val sql_avg : t ::: Type -> nt ::: Type -> sql_summable t -> nullify t nt -> sql_aggregate t nt
497 val sql_sum : t ::: Type -> sql_summable t -> sql_aggregate t t 501 val sql_sum : t ::: Type -> nt ::: Type -> sql_summable t -> nullify t nt -> sql_aggregate t nt
498 502
499 class sql_maxable 503 class sql_maxable
500 val sql_maxable_int : sql_maxable int 504 val sql_maxable_int : sql_maxable int
501 val sql_maxable_float : sql_maxable float 505 val sql_maxable_float : sql_maxable float
502 val sql_maxable_string : sql_maxable string 506 val sql_maxable_string : sql_maxable string
503 val sql_maxable_time : sql_maxable time 507 val sql_maxable_time : sql_maxable time
504 val sql_maxable_option : t ::: Type -> sql_maxable t -> sql_maxable (option t) 508 val sql_maxable_option : t ::: Type -> sql_maxable t -> sql_maxable (option t)
505 val sql_max : t ::: Type -> sql_maxable t -> sql_aggregate t t 509 val sql_max : t ::: Type -> nt ::: Type -> sql_maxable t -> nullify t nt -> sql_aggregate t nt
506 val sql_min : t ::: Type -> sql_maxable t -> sql_aggregate t t 510 val sql_min : t ::: Type -> nt ::: Type -> sql_maxable t -> nullify t nt -> sql_aggregate t nt
507 511
508 con sql_nfunc :: Type -> Type 512 con sql_nfunc :: Type -> Type
509 val sql_nfunc : tables ::: {{Type}} -> agg ::: {{Type}} -> exps ::: {Type} 513 val sql_nfunc : tables ::: {{Type}} -> agg ::: {{Type}} -> exps ::: {Type}
510 -> t ::: Type 514 -> t ::: Type
511 -> sql_nfunc t -> sql_exp tables agg exps t 515 -> sql_nfunc t -> sql_exp tables agg exps t
524 -> sql_injectable_prim t 528 -> sql_injectable_prim t
525 -> sql_exp tables agg exps t 529 -> sql_exp tables agg exps t
526 -> sql_exp tables agg exps (option t) 530 -> sql_exp tables agg exps (option t)
527 531
528 val sql_subquery : tables ::: {{Type}} -> agg ::: {{Type}} -> exps ::: {Type} -> nm ::: Name -> t ::: Type 532 val sql_subquery : tables ::: {{Type}} -> agg ::: {{Type}} -> exps ::: {Type} -> nm ::: Name -> t ::: Type
529 -> sql_query tables [] [nm = t] 533 -> sql_query tables agg [] [nm = t]
530 -> sql_exp tables agg exps t 534 -> sql_exp tables agg exps t
531 535
532 (*** Executing queries *) 536 (*** Executing queries *)
533 537
534 val query : tables ::: {{Type}} -> exps ::: {Type} 538 val query : tables ::: {{Type}} -> exps ::: {Type}
535 -> [tables ~ exps] => 539 -> [tables ~ exps] =>
536 state ::: Type 540 state ::: Type
537 -> sql_query [] tables exps 541 -> sql_query [] [] tables exps
538 -> ($(exps ++ map (fn fields :: {Type} => $fields) tables) 542 -> ($(exps ++ map (fn fields :: {Type} => $fields) tables)
539 -> state 543 -> state
540 -> transaction state) 544 -> transaction state)
541 -> state 545 -> state
542 -> transaction state 546 -> transaction state
836 (** Information flow security *) 840 (** Information flow security *)
837 841
838 type sql_policy 842 type sql_policy
839 843
840 val sendClient : tables ::: {{Type}} -> exps ::: {Type} 844 val sendClient : tables ::: {{Type}} -> exps ::: {Type}
841 -> [tables ~ exps] => sql_query [] tables exps 845 -> [tables ~ exps] => sql_query [] [] tables exps
842 -> sql_policy 846 -> sql_policy
843 847
844 val sendOwnIds : sql_sequence -> sql_policy 848 val sendOwnIds : sql_sequence -> sql_policy
845 849
846 val mayInsert : fs ::: {Type} -> tables ::: {{Type}} -> [[New] ~ tables] 850 val mayInsert : fs ::: {Type} -> tables ::: {{Type}} -> [[New] ~ tables]
847 => sql_query [] ([New = fs] ++ tables) [] 851 => sql_query [] [] ([New = fs] ++ tables) []
848 -> sql_policy 852 -> sql_policy
849 853
850 val mayDelete : fs ::: {Type} -> tables ::: {{Type}} -> [[Old] ~ tables] 854 val mayDelete : fs ::: {Type} -> tables ::: {{Type}} -> [[Old] ~ tables]
851 => sql_query [] ([Old = fs] ++ tables) [] 855 => sql_query [] [] ([Old = fs] ++ tables) []
852 -> sql_policy 856 -> sql_policy
853 857
854 val mayUpdate : fs ::: {Type} -> tables ::: {{Type}} -> [[Old, New] ~ tables] 858 val mayUpdate : fs ::: {Type} -> tables ::: {{Type}} -> [[Old, New] ~ tables]
855 => sql_query [] ([Old = fs, New = fs] ++ tables) [] 859 => sql_query [] [] ([Old = fs, New = fs] ++ tables) []
856 -> sql_policy 860 -> sql_policy
857 861
858 val also : sql_policy -> sql_policy -> sql_policy 862 val also : sql_policy -> sql_policy -> sql_policy
859 863
860 val debug : string -> transaction unit 864 val debug : string -> transaction unit