File: apollo-triggers.plpgsql

package info (click to toggle)
libchado-perl 1.23-2
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 23,976 kB
  • ctags: 10,378
  • sloc: xml: 192,540; sql: 165,945; perl: 28,339; sh: 101; python: 73; makefile: 46
file content (1021 lines) | stat: -rw-r--r-- 49,740 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
-- these are nearly identical to the triggers that flybase uses, but will
-- serve as the foundation of general triggers for GMOD.  Things that need to
-- be done:
--
--* indentify the items that have to be dynamically (at make time) extrapolated.
--* allow a more flexible naming scheme
--* remove the portion creating a flybase dbxref.
--* probably 20 more things I haven't thought of yet.



--gets the next available uniquename; note that it is
--destructive because it calls nextval on a sequence 
CREATE OR REPLACE FUNCTION next_uniquename() RETURNS varchar AS '
DECLARE
  prename      varchar;
  f_uniquename varchar;
  prefix       varchar;
  suffix       varchar;
  id           varchar;
  maxid        int;
BEGIN
  SELECT INTO prefix cp.value FROM cvtermprop cp, cvterm, cv
                             WHERE cvterm.name = ''prefix'' and
                                   cp.cvterm_id = cvterm.cvterm_id and
                                   cvterm.cv_id = cv.cv_id and
                                   cv.name = ''apollo'';
  SELECT INTO suffix cp.value FROM cvtermprop cp, cvterm, cv
                             WHERE cvterm.name = ''suffix'' and
                                   cp.cvterm_id = cvterm.cvterm_id and
                                   cvterm.cv_id = cv.cv_id and
                                   cv.name = ''apollo'';

  SELECT INTO maxid nextval(''uniquename_id_generator'');
  RAISE NOTICE ''maxid is:%'', maxid;
  id:=lpad(maxid, 6, ''000000'');
  f_uniquename:=CAST(prefix||id||suffix as VARCHAR);
  RETURN f_uniquename;
END;
'LANGUAGE plpgsql;

DROP TRIGGER tr_feature_del  ON feature;
CREATE OR REPLACE function fn_feature_del() RETURNS TRIGGER AS '
DECLARE 
  f_type cvterm.name%TYPE;
  f_id_gene feature.feature_id%TYPE;
  f_id_transcript feature.feature_id%TYPE;
  f_id_exon feature.feature_id%TYPE;
  f_id_exon_temp feature.feature_id%TYPE; 
  f_id_protein feature.feature_id%TYPE;
  f_id_allele feature.feature_id%TYPE;
  fr_object_id feature.feature_id%TYPE;
  f_type_gene CONSTANT varchar :=''gene'';
  f_type_exon CONSTANT varchar :=''exon'';
  f_type_transcript CONSTANT varchar :=''mRNA'';	
  f_type_snoRNA CONSTANT varchar :=''snoRNA'';
  f_type_ncRNA CONSTANT varchar :=''ncRNA'';
  f_type_snRNA CONSTANT varchar :=''snRNA'';
  f_type_tRNA CONSTANT varchar :=''tRNA'';
  f_type_rRNA CONSTANT varchar :=''rRNA'';
  f_type_promoter CONSTANT varchar :=''promoter'';
  f_type_repeat_region CONSTANT varchar :=''repeat_region'';
  f_type_miRNA CONSTANT varchar :=''miRNA'';
  f_type_transposable_element CONSTANT varchar :=''transposable_element'';
  f_type_pseudo CONSTANT varchar :=''pseudogene'';
  f_type_protein CONSTANT varchar :=''polypeptide'';
  f_type_allele CONSTANT varchar :=''alleleof'';
  f_return feature.feature_id%TYPE;
  f_row feature%ROWTYPE;
  fr_row_transcript feature_relationship%ROWTYPE;
  fr_row_exon feature_relationship%ROWTYPE;
  fr_row_protein feature_relationship%ROWTYPE;
  message   varchar(255);
BEGIN
   RAISE NOTICE ''enter f_d, feature uniquename:%, type_id:%'',OLD.uniquename, OLD.type_id;
   f_return:=OLD.feature_id;
   SELECT INTO f_type c.name from feature f, cvterm c where f.feature_id=OLD.feature_id and f.type_id=c.cvterm_id;
   IF f_type=f_type_gene THEN
       SELECT INTO f_id_allele fr.subject_id from  feature_relationship fr, cvterm c where  (fr.object_id=OLD.feature_id or fr.subject_id=OLD.feature_id)  and fr.type_id=c.cvterm_id and c.name=f_type_allele;
       IF NOT FOUND THEN 
           FOR fr_row_transcript IN SELECT * from feature_relationship fr where fr.object_id=OLD.feature_id LOOP
               SELECT INTO f_id_transcript  f.feature_id from feature f, cvterm c where f.feature_id=fr_row_transcript.subject_id and f.type_id=c.cvterm_id and (c.name=f_type_transcript or c.name=f_type_ncRNA or c.name=f_type_snoRNA or c.name=f_type_snRNA or c.name=f_type_tRNA  or c.name=f_type_rRNA  or c.name=f_type_pseudo  or c.name=f_type_miRNA or c.name=f_type_transposable_element or c.name=f_type_promoter or c.name=f_type_repeat_region); 
               SELECT INTO f_id_gene f.feature_id from feature f, feature_relationship fr, cvterm c where f.feature_id=fr.object_id and fr.subject_id=f_id_transcript and f.type_id=c.cvterm_id and c.name=f_type_gene and f.feature_id !=OLD.feature_id;
               IF f_id_gene IS NULL and f_id_transcript IS NOT NULL THEN
                   RAISE NOTICE ''delete lonely transcript:%'', f_id_transcript;
                   message:=CAST(''delete lonely transcript''||f_id_transcript AS TEXT);
                   insert into trigger_log(value, table_name, id) values(message, ''feature'', f_id_transcript);
                   delete from feature where feature_id=f_id_transcript;
               ELSIF f_id_gene IS NOT NULL AND F_id_transcript IS NOT NULL THEN
                   RAISE NOTICE ''There is another gene:% associated with this transcript:%, so this transcript will be kept'',f_id_gene, f_id_transcript;
                   message:=CAST(''There is another gene:''||f_id_gene||'' associated with this transcript:''||f_id_transcript AS TEXT); 
               END IF;
           END LOOP;
           message:=CAST(''delete gene:''||OLD.feature_id AS TEXT);
           insert into trigger_log(value, table_name, id) values(message, ''feature'', OLD.feature_id);
       ELSE
           RAISE NOTICE ''there is other allele associated with this gene:%'', f_id_allele;
              message:=CAST(''There is other allele associated with this gene:''||f_id_allele AS TEXT); 
           insert into trigger_log(value, table_name, id) values(message, ''feature'', f_id_transcript);
           return NULL;
       END IF;
   ELSIF (f_type=f_type_transcript or f_type=f_type_ncRNA or f_type=f_type_snoRNA or f_type=f_type_snRNA or f_type=f_type_tRNA  or f_type=f_type_rRNA or f_type=f_type_pseudo or  f_type=f_type_miRNA or f_type=f_type_transposable_element or f_type=f_type_promoter or f_type=f_type_repeat_region) THEN
       FOR fr_row_exon IN SELECT * from feature_relationship fr where fr.object_id=OLD.feature_id LOOP
           select INTO f_id_exon f.feature_id from feature f, cvterm c where f.feature_id=fr_row_exon.subject_id and f.type_id=c.cvterm_id and c.name=f_type_exon;
           SELECT INTO f_id_transcript f.feature_id from feature f, feature_relationship fr, cvterm c where f.feature_id=fr.object_id and fr.subject_id=f_id_exon and f.type_id=c.cvterm_id and (c.name=f_type_transcript or c.name=f_type_ncRNA or c.name=f_type_snoRNA or c.name=f_type_snRNA or c.name=f_type_tRNA  or c.name=f_type_rRNA  or c.name=f_type_pseudo  or c.name=f_type_miRNA or c.name=f_type_transposable_element or c.name=f_type_promoter or c.name=f_type_repeat_region) and f.feature_id!=OLD.feature_id;
           IF f_id_transcript IS NULL and f_id_exon IS NOT NULL THEN
               RAISE NOTICE ''delete lonely exon:%'', f_id_exon;
               delete from feature where feature_id=f_id_exon; 
               message:=CAST(''delete lonely exon:''||f_id_exon AS TEXT); 
               insert into trigger_log(value, table_name, id) values(message, ''feature'', f_id_exon);        
           ELSIF f_id_transcript IS NOT NULL and f_id_exon IS NOT NULL THEN
               RAISE NOTICE ''There is another transcript:% associated with this exon:%, so this exon will be kept'', f_id_transcript, f_id_exon;
               message:=CAST(''There is another transcript:''||f_id_transcript||'' associated with this exon:''||f_id_exon AS TEXT); 
               insert into trigger_log(value, table_name, id) values(message, ''feature'', f_id_exon);  
           END IF;    
       END LOOP;

       FOR fr_row_protein IN SELECT * from feature_relationship fr where fr.object_id=OLD.feature_id LOOP
           SELECT INTO f_id_protein f.feature_id from feature f, cvterm c where f.feature_id=fr_row_protein.subject_id and f.type_id=c.cvterm_id and c.name=f_type_protein;
           SELECT INTO f_id_transcript f.feature_id from feature f, feature_relationship fr, cvterm c where f.feature_id=fr.object_id and fr.subject_id=f_id_protein and f.type_id=c.cvterm_id and (c.name=f_type_transcript or c.name=f_type_ncRNA or c.name=f_type_snoRNA or c.name=f_type_snRNA or c.name=f_type_tRNA  or c.name=f_type_rRNA   or c.name=f_type_pseudo or  c.name=f_type_miRNA or c.name=f_type_transposable_element or c.name=f_type_promoter or c.name=f_type_repeat_region) and f.feature_id !=OLD.feature_id;
           IF f_id_transcript IS NULL and f_id_protein IS NOT NULL THEN
               RAISE NOTICE ''delete lonely polypeptide:%'', f_id_protein;
               delete from feature where feature_id=f_id_protein;
               message:=CAST(''delete lonely polypeptide:''||f_id_protein AS TEXT); 
               insert into trigger_log(value, table_name, id) values(message, ''feature'', f_id_protein);  
           ELSIF f_id_transcript IS NOT NULL and f_id_protein IS NOT NULL THEN
               RAISE NOTICE ''There is another transcript:% associated with this polypeptide:%, so this exon will be kept'', f_id_transcript, f_id_protein;
           END IF;
       END LOOP;
   END IF;
   RAISE NOTICE ''leave f_d ....'';
   RETURN OLD; 
END;
'LANGUAGE 'plpgsql';

GRANT ALL ON FUNCTION fn_feature_del() TO PUBLIC;

CREATE TRIGGER tr_feature_del BEFORE DELETE ON feature for EACH ROW EXECUTE PROCEDURE fn_feature_del();

DROP TRIGGER feature_assignname_tr_i ON feature;
CREATE OR REPLACE FUNCTION feature_assignname_fn_i() RETURNS TRIGGER AS '
DECLARE
  maxid      int;
  pos        int;
  id         varchar(255);
  max_id     int;
  is_anal    feature.is_analysis%TYPE;
  prefix     cvtermprop.value%TYPE;
  suffix     cvtermprop.value%TYPE;
  f_row_g    feature%ROWTYPE;
  f_row_e    feature%ROWTYPE;
  f_row_t    feature%ROWTYPE;
  f_row_p    feature%ROWTYPE;
  f_type     cvterm.name%TYPE;
  f_type_id  cvterm.cvterm_id%TYPE;
  letter_t   varchar;
  letter_p   varchar;
  f_uniquename_temp    feature.uniquename%TYPE;
  f_uniquename         feature.uniquename%TYPE;
  f_uniquename_tr      feature.uniquename%TYPE;
  f_uniquename_exon    feature.uniquename%TYPE;
  f_uniquename_protein feature.uniquename%TYPE;
  f_name               feature.name%TYPE;
  s_type_id            synonym.type_id%TYPE;
  s_id                 synonym.synonym_id%TYPE;
  c_cv_id              cv.cv_id%TYPE;
  f_s_id               feature_synonym.feature_synonym_id%TYPE;
  fr_row feature_relationship%ROWTYPE;
  f_type_gene CONSTANT varchar :=''gene'';
  f_type_exon CONSTANT varchar :=''exon'';
  f_type_transcript CONSTANT varchar :=''mRNA'';
  f_type_snoRNA CONSTANT varchar :=''snoRNA'';
  f_type_ncRNA CONSTANT varchar :=''ncRNA'';
  f_type_snRNA CONSTANT varchar :=''snRNA'';
  f_type_tRNA CONSTANT varchar :=''tRNA'';
  f_type_rRNA CONSTANT varchar :=''rRNA'';
  f_type_promoter CONSTANT varchar :=''promoter'';
  f_type_repeat_region CONSTANT varchar :=''repeat_region'';
  f_type_miRNA CONSTANT varchar :=''miRNA'';
  f_type_transposable_element CONSTANT varchar :=''transposable_element'';
  f_type_pseudo CONSTANT varchar :=''pseudogene'';
  f_type_protein CONSTANT varchar :=''polypeptide'';
  f_type_allele CONSTANT varchar :=''alleleof'';
  f_type_remark CONSTANT varchar :=''remark'';
  f_dbname_gadfly CONSTANT varchar :=''DB:GR'';
  f_dbname_FB CONSTANT varchar :=''null'';
  o_genus  CONSTANT varchar :=''Oryza'';
  o_species  CONSTANT varchar:=''sativa'';
  c_name_synonym CONSTANT varchar:=''synonym'';
  cv_cvname_synonym CONSTANT varchar:=''null'';
  p_miniref         CONSTANT varchar:=''none'';
  p_id  pub.pub_id%TYPE;
BEGIN
  SELECT INTO is_anal is_analysis FROM feature WHERE uniquename = NEW.uniquename and 
                                                     type_id = NEW.type_id and 
                                                     organism_id = NEW.organism_id;
  IF (is_anal) THEN
      RETURN NEW;
  END IF;

  SELECT INTO prefix cp.value FROM cvtermprop cp, cvterm, cv
                             WHERE cvterm.name = ''prefix'' and
                                   cp.cvterm_id = cvterm.cvterm_id and
                                   cvterm.cv_id = cv.cv_id and
                                   cv.name = ''apollo'';
  SELECT INTO suffix cp.value FROM cvtermprop cp, cvterm, cv
                             WHERE cvterm.name = ''suffix'' and
                                   cp.cvterm_id = cvterm.cvterm_id and
                                   cvterm.cv_id = cv.cv_id and
                                   cv.name = ''apollo'';
  SELECT INTO f_type c.name
         from feature f, cvterm c
         where f.type_id=c.cvterm_id and
               f.uniquename=NEW.uniquename and
               f.organism_id =NEW.organism_id;
  SELECT INTO p_id pub_id from pub where uniquename = p_miniref;
  SELECT INTO s_type_id cvterm_id from cvterm c1, cv c2 where c1.name=c_name_synonym and c2.name=cv_cvname_synonym and c1.cv_id=c2.cv_id;

  RAISE NOTICE ''assigning names, prefix:%, suffix:%, type:%, current uniquename:%'',prefix,suffix,f_type,NEW.uniquename;

  IF (NEW.uniquename like prefix||''%:temp%''||suffix OR NEW.uniquename like prefix||''%-temp%'') THEN

      SELECT INTO f_type c.name
         from feature f, cvterm c
         where f.type_id=c.cvterm_id and
               f.uniquename=NEW.uniquename and
               f.organism_id =NEW.organism_id;
      --SELECT INTO p_id pub_id from pub where uniquename = p_miniref;
      --SELECT INTO s_type_id cvterm_id from cvterm c1, cv c2 where c1.name=c_name_synonym and c2.name=cv_cvname_synonym and c1.cv_id=c2.cv_id;

      SELECT INTO f_uniquename * FROM next_uniquename();

      SELECT INTO f_row_g * from feature where uniquename=NEW.uniquename and organism_id=NEW.organism_id;

      IF f_type = f_type_gene THEN

          IF NEW.name like ''%temp%'' or NEW.name IS NULL THEN
               f_name = f_uniquename;
               UPDATE feature set uniquename=f_uniquename, name=f_uniquename where feature_id=f_row_g.feature_id;
          ELSE
               f_name = f_row_g.name;
               UPDATE feature set uniquename=f_uniquename where feature_id=f_row_g.feature_id;
          END IF;

      ELSIF (f_type=f_type_transcript or 
             f_type=f_type_ncRNA or 
             f_type=f_type_snoRNA or 
             f_type=f_type_snRNA or 
             f_type=f_type_tRNA or 
             f_type=f_type_rRNA or 
             f_type=f_type_pseudo or 
             f_type=f_type_miRNA or
             f_type=f_type_protein or
             f_type=f_type_exon) THEN

          IF NEW.name like ''%temp%'' or NEW.name IS NULL THEN
               f_name = null;
          ELSE
               f_name = f_row_g.name;
          END IF;
          UPDATE feature set uniquename=f_uniquename,name=f_name where feature_id=f_row_g.feature_id;

      ELSIF ( f_type=f_type_transposable_element or 
              f_type=f_type_promoter or 
              f_type=f_type_repeat_region or 
              f_type=f_type_remark )  THEN

          IF NEW.name like ''%temp%'' or NEW.name IS NULL THEN
               f_name := CAST(f_uniquename||''-''||f_type  AS TEXT);
               UPDATE feature set uniquename=f_uniquename, name=f_uniquename where feature_id=f_row_g.feature_id;
          ELSE
               f_name = f_row_g.name;
               UPDATE feature set uniquename=f_uniquename, name=f_name where feature_id=f_row_g.feature_id;
          END IF;

      END IF;

      RAISE NOTICE ''new uniquename of this feature is:%'', f_uniquename;

      --insert into synonym, feature_synonym
      SELECT INTO s_id synonym_id from synonym where name=f_uniquename and type_id=s_type_id;
      IF s_id IS NULL THEN
          INSERT INTO synonym(name, synonym_sgml, type_id) values(f_uniquename, f_uniquename, s_type_id);
          SELECT INTO s_id synonym_id from synonym where name=f_uniquename and type_id=s_type_id;
      END IF;
      SELECT INTO f_s_id feature_synonym_id from feature_synonym where feature_id=f_row_g.feature_id and synonym_id=s_id and pub_id=p_id;
      IF f_s_id IS NULL THEN
          INSERT INTO feature_synonym(feature_id, synonym_id, pub_id, is_current) values (f_row_g.feature_id, s_id, p_id, ''true'');
      END IF;
      RAISE NOTICE ''feature_id:%, synonym_id:% for uniquename'', f_row_g.feature_id, s_id;

      IF f_name IS NOT NULL THEN

          SELECT INTO s_id synonym_id from synonym where name=f_name and type_id=s_type_id;
          IF s_id IS NULL THEN
              INSERT INTO synonym(name, synonym_sgml, type_id) values(f_name, f_name, s_type_id);
              SELECT INTO s_id synonym_id from synonym where name=f_name and type_id=s_type_id;
          END IF;
          SELECT INTO f_s_id feature_synonym_id from feature_synonym where feature_id=f_row_g.feature_id and synonym_id=s_id and pub_id=p_id;
          IF f_s_id IS NULL THEN
              INSERT INTO feature_synonym(feature_id, synonym_id, pub_id, is_current) values (f_row_g.feature_id, s_id, p_id, ''true'');
          END IF;
          RAISE NOTICE ''feature_id:%, synonym_id:% for name'', f_row_g.feature_id, s_id;

      END IF;
  END IF;     --ends if uniquename like temp

  return NEW;    
END;
'LANGUAGE plpgsql;

GRANT ALL ON FUNCTION feature_assignname_fn_i() TO PUBLIC;

CREATE TRIGGER feature_assignname_tr_i AFTER INSERT ON feature for EACH ROW EXECUTE PROCEDURE feature_assignname_fn_i();

DROP TRIGGER feature_relationship_tr_d  ON feature_relationship;
CREATE OR REPLACE FUNCTION feature_relationship_fn_d() RETURNS TRIGGER AS '
DECLARE
  maxid         int;
  id            varchar(255);
  loginfo       varchar(255);
  len           int;
  f_row_g       feature%ROWTYPE;
  f_row_e       feature%ROWTYPE;
  f_row_t       feature%ROWTYPE;
  f_row_p       feature%ROWTYPE;
  f_type        cvterm.name%TYPE;
  f_type_temp   cvterm.name%TYPE;
  letter_e      varchar(100);
  letter_t      varchar(100);
  letter_p      varchar(100);
  f_uniquename_gene    feature.uniquename%TYPE;
  f_uniquename_transcript feature.uniquename%TYPE;
  f_uniquename_exon    feature.uniquename%TYPE;
  f_uniquename_protein feature.uniquename%TYPE;
  f_d_id               feature_dbxref.feature_dbxref_id%TYPE;
  d_id                 dbxref.dbxref_id%TYPE;
  s_type_id            synonym.type_id%TYPE;
  s_id                 synonym.synonym_id%TYPE;
  p_id                 pub.pub_id%TYPE;
  fr_row               feature_relationship%ROWTYPE;
  f_accession_temp     varchar(255);
  f_accession          varchar(255);
  f_type_gene          CONSTANT varchar :=''gene'';
  f_type_exon          CONSTANT varchar :=''exon'';
  f_type_transcript    CONSTANT varchar :=''mRNA'';
  f_type_snoRNA        CONSTANT varchar :=''snoRNA'';
  f_type_ncRNA         CONSTANT varchar :=''ncRNA'';
  f_type_snRNA         CONSTANT varchar :=''snRNA'';
  f_type_tRNA          CONSTANT varchar :=''tRNA'';
  f_type_rRNA          CONSTANT varchar :=''rRNA'';
  f_type_promoter      CONSTANT varchar :=''promoter'';
  f_type_repeat_region CONSTANT varchar :=''repeat_region'';
  f_type_miRNA         CONSTANT varchar :=''miRNA'';
  f_type_transposable_element CONSTANT varchar :=''transposable_element'';
  f_type_pseudo        CONSTANT varchar :=''pseudogene'';
  f_type_protein       CONSTANT varchar :=''polypeptide'';
  f_type_allele        CONSTANT varchar :=''alleleof'';
  f_dbname_gadfly      CONSTANT varchar :=''Gadfly'';
  f_dbname_FB          CONSTANT varchar :=''FlyBase'';
  c_name_synonym       CONSTANT varchar:=''synonym'';
  cv_cvname_synonym    CONSTANT varchar:=''synonym type'';
  p_miniref            CONSTANT varchar:=''none'';
BEGIN
 RAISE NOTICE ''enter fr_d, fr.object_id:%, fr.subject_id:%'', OLD.object_id, OLD.subject_id;
 SELECT INTO f_type name from cvterm  where cvterm_id=OLD.type_id;
 IF f_type=f_type_allele THEN
     RAISE NOTICE ''delete relationship beteen gene:% and allele:%'', OLD.object_id, OLD.subject_id; 
 ELSE
     SELECT INTO f_type c.name from feature f, cvterm c  where f.type_id=c.cvterm_id and f.feature_id=OLD.object_id;
     IF f_type=f_type_gene THEN 
         SELECT INTO f_type_temp c.name from feature f, cvterm c where f.feature_id=OLD.subject_id and f.type_id=c.cvterm_id;
         IF (f_type_temp=f_type_transcript or 
             f_type_temp=f_type_ncRNA or 
             f_type_temp=f_type_snoRNA  or 
             f_type_temp=f_type_snRNA  or 
             f_type_temp=f_type_tRNA  or 
             f_type_temp=f_type_rRNA  or 
             f_type_temp=f_type_miRNA  or 
             f_type_temp=f_type_pseudo or 
             f_type_temp=f_type_transposable_element or 
             f_type_temp=f_type_promoter or 
             f_type_temp=f_type_repeat_region ) THEN

             SELECT INTO fr_row * from feature_relationship where object_id<>OLD.object_id and subject_id=OLD.subject_id;
             IF fr_row.object_id IS NULL THEN
                 RAISE NOTICE ''delete this lonely transcript:%'', OLD.subject_id;
                 delete from feature where feature_id=OLD.subject_id;
             END IF;
         ELSE
             RAISE NOTICE ''wrong feature_relationship: gene->NO_transcript:object_id:%, subject_id:%'', OLD.object_id, OLD.subject_id;
         END IF;
     ELSIF (f_type=f_type_transcript or f_type=f_type_snoRNA or f_type=f_type_ncRNA or f_type=f_type_snRNA or f_type=f_type_tRNA or f_type=f_type_miRNA or f_type=f_type_rRNA or f_type=f_type_pseudo or f_type=f_type_transposable_element or f_type=f_type_promoter or f_type=f_type_repeat_region) THEN
         SELECT INTO f_type_temp c.name from feature f, cvterm c where f.feature_id=OLD.subject_id and f.type_id=c.cvterm_id;
         IF f_type_temp=f_type_protein or f_type_temp=f_type_exon THEN
             SELECT INTO fr_row * from feature_relationship where subject_id=OLD.subject_id and object_id<>OLD.object_id;  
             IF fr_row.object_id IS NULL     THEN     
                 RAISE NOTICE ''delete this lonely exon/polypeptide:%'', OLD.subject_id;
                 delete from feature where feature_id=OLD.subject_id;          
             END IF;
         ELSE
             RAISE NOTICE ''wrong relationship: transcript->NO_polypeptide/exon: objfeature:%, subjfeature:%'',OLD.object_id, OLD.subject_id;
         END IF;
     END IF;
 END IF;
 RAISE NOTICE ''leave fr_d ....'';
 RETURN OLD;
END;
'LANGUAGE plpgsql;

GRANT ALL ON FUNCTION feature_relationship_fn_d() TO PUBLIC;

CREATE TRIGGER feature_relationship_tr_d BEFORE DELETE ON feature_relationship  for EACH ROW EXECUTE PROCEDURE feature_relationship_fn_d();

DROP TABLE trigger_log;
CREATE TABLE trigger_log(
   value   varchar(255) not null,
   timeaccessioned   timestamp not null default current_timestamp,
   table_name   varchar(50),
   id      int 
);

GRANT ALL ON TABLE trigger_log TO PUBLIC;


DROP TRIGGER feature_relationship_propagatename_tr_i ON feature_relationship;

CREATE OR REPLACE FUNCTION feature_relationship_propagatename_fn_i() RETURNS TRIGGER AS '
DECLARE
  maxid        int;
  exon_id      int;
  id           varchar(255);
  maxid_fb     int;
  id_fb        varchar(255);
  loginfo      varchar(255);
  len          int;
  prefix       varchar;
  suffix       varchar;
  f_row_g      feature%ROWTYPE;
  f_row_e      feature%ROWTYPE;
  f_row_t      feature%ROWTYPE;
  f_row_p      feature%ROWTYPE;
  fl_row_e     featureloc%ROWTYPE;
  f_type       cvterm.name%TYPE;
  f_type_temp  cvterm.name%TYPE;
  letter_t     varchar(100);
  letter_p     varchar(100);
  f_dbxref_id          feature.dbxref_id%TYPE;
  fb_accession         dbxref.accession%TYPE;
  d_accession          dbxref.accession%TYPE;
  f_name_gene          feature.name%TYPE;
  f_name               feature.name%TYPE;
  f_d_id               feature_dbxref.feature_dbxref_id%TYPE;
  dx_id                dbxref.dbxref_id%TYPE;
  d_id                 db.db_id%TYPE;
  s_type_id            synonym.type_id%TYPE;
  s_id                 synonym.synonym_id%TYPE;
  p_id                 pub.pub_id%TYPE;
  p_type_id            cvterm.cvterm_id%TYPE;
  c_cv_id              cv.cv_id%TYPE;
  f_s_id               feature_synonym.feature_synonym_id%TYPE;
  fr_row               feature_relationship%ROWTYPE;
  f_accession_temp     varchar(255);
  f_accession          varchar(255);
  f_type_gene       CONSTANT varchar :=''gene'';
  f_type_exon       CONSTANT varchar :=''exon'';
  f_type_transcript CONSTANT varchar :=''mRNA'';
  f_type_snoRNA     CONSTANT varchar :=''snoRNA'';
  f_type_ncRNA      CONSTANT varchar :=''ncRNA'';
  f_type_snRNA      CONSTANT varchar :=''snRNA'';
  f_type_tRNA       CONSTANT varchar :=''tRNA'';
  f_type_promoter   CONSTANT varchar :=''promoter'';
  f_type_repeat_region CONSTANT varchar :=''repeat_region'';
  f_type_miRNA      CONSTANT varchar :=''miRNA'';
  f_type_transposable_element CONSTANT varchar :=''transposable_element'';
  f_type_rRNA       CONSTANT varchar :=''rRNA'';
  f_type_pseudo     CONSTANT varchar :=''pseudogene'';
  f_type_protein    CONSTANT varchar :=''polypeptide'';
  f_type_allele     CONSTANT varchar :=''alleleof'';
  f_dbname_gadfly   CONSTANT varchar :=''DB:GR'';
  f_dbname_FB       CONSTANT varchar :=''null'';
  c_name_synonym    CONSTANT varchar:=''synonym'';
  cv_cvname_synonym CONSTANT varchar:=''null'';
  p_miniref         CONSTANT varchar:=''none'';
  p_cvterm_name     CONSTANT varchar:=''computer file'';
  p_cv_name         CONSTANT varchar:=''pub type'';
  fng_type_id       cvterm.cvterm_id%TYPE;
BEGIN
 SELECT INTO prefix cp.value FROM cvtermprop cp, cvterm, cv
                             WHERE cvterm.name = ''prefix'' and
                                   cp.cvterm_id = cvterm.cvterm_id and
                                   cvterm.cv_id = cv.cv_id and
                                   cv.name = ''apollo'';
 SELECT INTO suffix cp.value FROM cvtermprop cp, cvterm, cv
                             WHERE cvterm.name = ''suffix'' and
                                   cp.cvterm_id = cvterm.cvterm_id and
                                   cvterm.cv_id = cv.cv_id and
                                   cv.name = ''apollo'';

 SELECT INTO p_id pub_id from pub where uniquename = p_miniref;
 SELECT INTO s_type_id cvterm_id from cvterm c1, cv c2 where c1.name=c_name_synonym and c2.name=cv_cvname_synonym and c1.cv_id=c2.cv_id;

 RAISE NOTICE ''propagating names, prefix:%, suffix:%'',prefix,suffix;

 RAISE NOTICE ''enter fr_i, fr.object_id:%, fr.subject_id:%'', NEW.object_id, NEW.subject_id;
 SELECT INTO f_type c.name from feature f, cvterm c  where f.type_id=c.cvterm_id and f.feature_id=NEW.object_id;
 SELECT INTO f_name name from feature where feature_id = NEW.subject_id;


 -- OK, the thing having a child added is a gene
 IF ((f_name IS NULL OR f_name like prefix||''%temp%'')
      and f_type=f_type_gene) THEN
     SELECT INTO f_type_temp c.name from feature f, cvterm c where f.feature_id=NEW.subject_id and f.type_id=c.cvterm_id;
     IF (f_type_temp=f_type_transcript or 
         f_type_temp=f_type_snoRNA or 
         f_type_temp=f_type_ncRNA or 
         f_type_temp=f_type_snRNA or 
         f_type_temp=f_type_tRNA or 
         f_type_temp=f_type_rRNA or 
         f_type_temp=f_type_miRNA or 
         f_type_temp=f_type_pseudo or 
         f_type_temp=f_type_transposable_element or 
         f_type_temp=f_type_promoter or 
         f_type_temp=f_type_repeat_region) THEN

         --generate a new name based on the gene name
         --the name is like: genename-transcript#
         SELECT INTO f_name_gene name from feature where feature_id=NEW.object_id;
        -- SELECT INTO maxid to_number(max(substring(name from (length(f_name_gene)+1+10))), ''99999'') FROM feature where name like f_name_gene||''-transcript%'';
         SELECT INTO c_cv_id cv_id FROM cv WHERE name = ''Sequence Ontology Feature Annotation'';
         SELECT INTO fng_type_id cvterm_id FROM cvterm WHERE name = ''transcript'' AND cv_id = c_cv_id;
         SELECT INTO maxid count FROM feature_namegenerator WHERE name = f_name_gene AND type_id = fng_type_id;
         IF maxid IS NULL THEN
             maxid = 1;
         ELSE
             maxid = maxid + 1;
         END IF;

         f_name:=CAST(f_name_gene||''-transcript''||maxid AS TEXT);

         RAISE NOTICE ''start to update feature, gene name:%, new feature name:%'', f_name_gene, f_name;
         UPDATE feature set name=f_name where feature_id=NEW.subject_id;

         DELETE FROM feature_namegenerator WHERE name = f_name_gene AND type_id = fng_type_id;
         INSERT INTO feature_namegenerator (name,type_id,count) VALUES (f_name_gene, fng_type_id, maxid);

         SELECT INTO s_id synonym_id from synonym where name=f_name and type_id=s_type_id;
         IF s_id IS NULL THEN
             INSERT INTO synonym(name, synonym_sgml, type_id) values(f_name, f_name, s_type_id);
             SELECT INTO s_id synonym_id from synonym where name=f_name and type_id=s_type_id;
         END IF;
         RAISE NOTICE ''start to insert feature_synonym:synonym_id:%,feature_id:%, pub_id:%'', s_id, NEW.subject_id, p_id;
         SELECT INTO f_s_id feature_synonym_id from feature_synonym where feature_id=NEW.subject_id and synonym_id=s_id and pub_id=p_id;
         IF f_s_id IS NULL THEN
             INSERT INTO feature_synonym(feature_id, synonym_id, pub_id, is_current) values (NEW.subject_id, s_id, p_id, ''true'');
         END IF;
     END IF;

-- here the thing having a child added is a second level thing (eg, a transcript is getting an exon or protein)
 ELSIF ((f_name IS NULL OR f_name like prefix||''%temp%'') and
          (f_type=f_type_transcript or 
           f_type=f_type_ncRNA  or 
           f_type=f_type_snoRNA or 
           f_type=f_type_snRNA or 
           f_type=f_type_tRNA or 
           f_type=f_type_rRNA or 
           f_type=f_type_miRNA or 
           f_type=f_type_pseudo or 
           f_type=f_type_transposable_element or 
           f_type=f_type_promoter or 
           f_type=f_type_repeat_region) )  THEN
     SELECT INTO f_name_gene f.name from feature f, feature_relationship fr, cvterm c where f.feature_id=fr.object_id and fr.subject_id=NEW.object_id and f.type_id=c.cvterm_id and c.name=f_type_gene;
     SELECT INTO f_type_temp c.name from feature f, cvterm c where f.feature_id=NEW.subject_id and f.type_id=c.cvterm_id;

     --adding a protein to a transcript
     IF f_type_temp=f_type_protein THEN
         IF f_name_gene IS NOT NULL THEN
             SELECT INTO f_row_p * from feature where feature_id=NEW.subject_id;

             --create a new name for this protein (again repeating code in assign_names)
             --SELECT INTO maxid to_number(max(substring(name from (length(f_name_gene)+1+12))), ''99999'') FROM feature where name like f_name_gene||''-polypeptide%'';
             SELECT INTO c_cv_id cv_id FROM cv WHERE name = ''Sequence Ontology'';
             SELECT INTO fng_type_id cvterm_id FROM cvterm WHERE name = f_type_protein AND cv_id = c_cv_id;
             SELECT INTO maxid count FROM feature_namegenerator WHERE name = f_name_gene AND type_id = fng_type_id;
             IF maxid IS NULL THEN
                 maxid = 1;
             ELSE
                 maxid = maxid + 1;
             END IF;

             f_name:=CAST(f_name_gene||''-''||f_type_protein||maxid AS TEXT);

             RAISE NOTICE ''update name of polypeptide:% to new name:%'',f_row_p.name, f_name;
             UPDATE feature set name=f_name where feature_id=NEW.subject_id;

             DELETE FROM feature_namegenerator WHERE name = f_name_gene AND type_id = fng_type_id;
             INSERT INTO feature_namegenerator (name,type_id,count) VALUES (f_name_gene, fng_type_id, maxid);

             SELECT INTO s_id synonym_id from synonym where name=f_name and type_id=s_type_id;
             IF s_id IS NULL THEN
                 INSERT INTO synonym(name, synonym_sgml, type_id) values(f_name, f_name, s_type_id);
                 SELECT INTO s_id synonym_id from synonym where name=f_name and type_id=s_type_id;
             END IF;

             SELECT INTO f_s_id feature_synonym_id from feature_synonym where feature_id=f_row_p.feature_id and synonym_id=s_id;
             IF f_s_id is NULL THEN
                 INSERT INTO feature_synonym(feature_id, synonym_id, pub_id, is_current) values (f_row_p.feature_id, s_id, p_id, ''true'');
             END IF;
         ELSE
             RAISE NOTICE ''Couldnt find a gene to add this polypeptide to (feature_id:%)'', NEW.subject_id ;
         END IF;

     --adding an exon to a transcript
     ELSIF f_type_temp=f_type_exon THEN
         IF f_name_gene IS NOT NULL THEN

             SELECT INTO f_row_e * from feature where feature_id=NEW.subject_id;
             SELECT INTO fl_row_e * from featureloc where feature_id = NEW.subject_id and rank=0;
             IF fl_row_e.fmin IS NULL OR fl_row_e.fmax IS NULL THEN
                 RAISE NOTICE ''cant create exon name for feature_id % since there is no featureloc entry'', NEW.subject_id;
                 RETURN NEW;
             ELSE
                 f_name:=CAST(f_name_gene||'':''||fl_row_e.fmin||''-''||fl_row_e.fmax  AS TEXT);
             END IF;
             RAISE NOTICE ''exon new name:%'', f_name;
             UPDATE feature set name=f_name where feature_id=NEW.subject_id;

             SELECT INTO s_id synonym_id from synonym where name=f_name and type_id=s_type_id;
             IF s_id IS NULL THEN
                 INSERT INTO synonym(name, synonym_sgml, type_id) values(f_name, f_name, s_type_id);
                 SELECT INTO s_id synonym_id from synonym where name=f_name and type_id=s_type_id;
             END IF;

             SELECT INTO f_s_id feature_synonym_id from feature_synonym where feature_id=f_row_e.feature_id and synonym_id=s_id;
             IF f_s_id is NULL THEN
                 INSERT INTO feature_synonym(feature_id, synonym_id, pub_id, is_current) values (f_row_e.feature_id, s_id, p_id, ''true'');
             END IF;
         ELSE
             RAISE NOTICE ''Couldnt find a gene to add this exon to (feature_id:%)'',NEW.subject_id;
         END IF;
     END IF;
 ELSE
 --nothing to do, the name is not null or containing temp
 --    RAISE NOTICE ''no link to gene for this transcript or wrong feature_relationship: transcript->polypeptide/exon:object_id:%, subject_id:%'', NEW.object_id, NEW.subject_id;
 END IF;
 RAISE NOTICE ''leave fr_i ....'';
 RETURN NEW;
END;
'LANGUAGE plpgsql;

GRANT ALL ON FUNCTION feature_relationship_propagatename_fn_i() TO PUBLIC;

CREATE TRIGGER feature_relationship_propagatename_tr_i AFTER INSERT ON feature_relationship FOR EACH ROW EXECUTE PROCEDURE feature_relationship_propagatename_fn_i();


DROP TRIGGER feature_update_name_tr_u ON feature;

CREATE OR REPLACE FUNCTION feature_fn_u() RETURNS TRIGGER AS
'
DECLARE
  f_type          cvterm.name%TYPE;
  f_type_gene     CONSTANT varchar :=''gene'';
  f_row           feature%ROWTYPE;
  s_type_id       synonym.type_id%TYPE;
  s_id            synonym.synonym_id%TYPE;
  f_s_id          feature_synonym.feature_synonym_id%TYPE;
  p_id            pub.pub_id%TYPE;
  p_miniref       CONSTANT varchar:=''none'';
  c_name_synonym  CONSTANT varchar:=''synonym'';
  cv_cvname_synonym CONSTANT varchar:=''null'';
  name_suffix     varchar;
  child_name      varchar;
BEGIN
  IF OLD.uniquename <> NEW.uniquename AND OLD.uniquename NOT LIKE ''%temp%'' THEN
      RAISE NOTICE ''You may not change the uniquename of a feature'';
      RAISE NOTICE ''if you feel you must, contact your database admin'';
      RETURN OLD;
  END IF;
  IF OLD.name = NEW.name THEN
      --not updating name, so go ahead 
      RETURN NEW;
  END IF;


--fetch a few useful things
  SELECT INTO s_type_id cvterm_id from cvterm c1, cv c2 where c1.name=c_name_synonym and c2.name=cv_cvname_synonym and c1.cv_id=c2.cv_id;
  SELECT INTO f_type cv.name FROM feature f, cvterm cv WHERE f.feature_id = OLD.feature_id and f.type_id = cv.cvterm_id; 
  SELECT INTO p_id pub_id from pub where uniquename = p_miniref;



--  IF f_type <> f_type_gene THEN
--      --its not a gene, so go ahead
--      --but insert the new name into the synonym table


  --On gene name update, we also update the gene inner synonym (ie himself)
  --so for all features, the inner synonym gets updated
      IF NEW.name IS NOT NULL THEN
          SELECT INTO s_id synonym_id from synonym where name=NEW.name and type_id=s_type_id;
          IF s_id IS NULL THEN
              INSERT INTO synonym(name, synonym_sgml, type_id) values(NEW.name, NEW.name, s_type_id);
              SELECT INTO s_id synonym_id from synonym where name=NEW.name and type_id=s_type_id;
          END IF;
          SELECT INTO f_s_id feature_synonym_id from feature_synonym where feature_id=NEW.feature_id and synonym_id=s_id and pub_id=p_id;
          IF f_s_id IS NULL THEN
              INSERT INTO feature_synonym(feature_id, synonym_id, pub_id, is_current) values (NEW.feature_id, s_id, p_id, ''true'');
          END IF;
      END IF;
 
  IF f_type <> f_type_gene THEN
      --its not a gene, so go ahead   
      RETURN NEW;
  END IF;

  --OK, so its a gene, and were changing the name...




  --For corectly handling alternate transcript of a gene, we must add a distinct in order not to process the same exon multiple times (exons are shared in chado)
  FOR f_row IN SELECT DISTINCT f.* FROM feature f, get_sub_feature_ids(OLD.feature_id) ch WHERE f.feature_id = ch.feature_id LOOP
      --This one process the transcripts and the proteins
--      IF f_row.name LIKE OLD.name||''-%'' THEN
--          SELECT INTO name_suffix  substring(name from OLD.name||''(-.+)'') FROM feature where feature_id = f_row.feature_id;
--          child_name = NEW.name||name_suffix;
--          UPDATE feature SET name = child_name WHERE feature_id = f_row.feature_id;

--          SELECT INTO s_id synonym_id from synonym where name=child_name and type_id=s_type_id;
--          IF s_id IS NULL THEN
--              INSERT INTO synonym(name, synonym_sgml, type_id) values(child_name, child_name, s_type_id);
--              SELECT INTO s_id synonym_id from synonym where name=child_name and type_id=s_type_id;
--          END IF;
--          SELECT INTO f_s_id feature_synonym_id from feature_synonym where feature_id=f_row.feature_id and synonym_id=s_id and pub_id=p_id;
--          IF f_s_id IS NULL THEN
--              INSERT INTO feature_synonym(feature_id, synonym_id, pub_id, is_current) values (f_row.feature_id, s_id, p_id, ''true'');
--          END IF;
--      END IF;

      --And this one process the exons (of form gene_name:something)
      --Be careful, this could lead to problems with some autogenerated split names which for flybase are also of the form gene_name:#) TODO : move this regexp to something like /gene_name:\d-\d/
      IF  f_row.name LIKE OLD.name||'':%'' THEN
          SELECT INTO name_suffix  substring(name from OLD.name||''(:.+)'') FROM feature where feature_id = f_row.feature_id;
          child_name = NEW.name||name_suffix;
          RAISE NOTICE ''feature_id:%, name:% , new name : %, namesuffix:%, geneName:%'', f_row.feature_id, f_row.name, child_name,name_suffix, NEW.name ;
          UPDATE feature SET name = child_name WHERE feature_id = f_row.feature_id;

          SELECT INTO s_id synonym_id from synonym where name=child_name and type_id=s_type_id;
          IF s_id IS NULL THEN
              INSERT INTO synonym(name, synonym_sgml, type_id) values(child_name, child_name, s_type_id);
              SELECT INTO s_id synonym_id from synonym where name=child_name and type_id=s_type_id;
          END IF;
          SELECT INTO f_s_id feature_synonym_id from feature_synonym where feature_id=f_row.feature_id and synonym_id=s_id and pub_id=p_id;
          IF f_s_id IS NULL THEN
              INSERT INTO feature_synonym(feature_id, synonym_id, pub_id, is_current) values (f_row.feature_id, s_id, p_id, ''true'');          END IF;

      END IF; 

  END LOOP;  
  
  RETURN NEW; 
END;
'LANGUAGE plpgsql;

CREATE TRIGGER feature_update_name_tr_u BEFORE UPDATE ON feature FOR EACH ROW EXECUTE PROCEDURE feature_fn_u();

-- function to fascilitate gene merges
-- returns the uniquename of the merged gene
--WARNING: COMPLETELY UNTESTED
CREATE OR REPLACE FUNCTION apollo_merge(varchar, varchar) RETURNS varchar AS
'
DECLARE
  f1_uniquename		ALIAS FOR $1;
  f2_uniquename		ALIAS FOR $2;
  f_uniquename		feature.uniquename%TYPE;
  f1_fid		feature.feature_id%TYPE;
  f2_fid		feature.feature_id%TYPE;
  f_id			feature.feature_id%TYPE;
  f1_type		cvterm.name%TYPE;
  f2_type		cvterm.name%TYPE;
  f1_organism_id	feature.organism_id%TYPE;
  f2_organism_id        feature.organism_id%TYPE;	
  f_type_gene		CONSTANT varchar :=''gene'';
  c_cvterm_id		cvterm.cvterm_id%TYPE;
  s_id			synonym.synonym_id%TYPE;
  dbxref_id		dbxref.dbxref_id%TYPE;
  fd_row                feature_dbxref%ROWTYPE;
  p_id			pub.pub_id%TYPE;
  fpub_row		feature_pub%ROWTYPE;
  fp_row		featureprop%ROWTYPE;
  fc_row		feature_cvterm%ROWTYPE;
  fs_row		feature_synonym%ROWTYPE;
BEGIN
--check that they are both genes
  SELECT INTO f1_type c.name FROM feature f, cvterm c
                            WHERE f.uniquename = f1_uniquename AND
                                  f.type_id    = c.cvterm_id;
  SELECT INTO f2_type c.name FROM feature f, cvterm c
                            WHERE f.uniquename = f1_uniquename AND
                                  f.type_id    = c.cvterm_id;

  IF f1_type <> f_type_gene OR f2_type <> f_type_gene THEN
      RAISE NOTICE ''The uniquenames for the features provided must be those of genes'';
      RETURN OLD;
  END IF;

--check that they come from the same organism
  SELECT INTO f1_organism_id FROM feature WHERE uniquename=f1_uniquename;
  SELECT INTO f2_organism_id FROM feature WHERE uniquename=f2_uniquename;

  IF f1_organism_id <> f2_organism_id THEN
      RAISE NOTICE ''The merged genes must come from the same organism'';
      RETURN OLD;
  END IF;

  SELECT INTO c_cvterm_id type_id FROM feature
                                 WHERE uniquename = f1_uniquename;

  SELECT INTO f_uniquename next_uniquename();

--create the new gene
  INSERT INTO feature (organism_id, uniquename, type_id)
              VALUES  (f1_organism_id, f_uniquename, c_cvterm_id);

  SELECT INTO f_id feature_id FROM feature
                             WHERE uniquename  = f_uniquename AND
                                   organism_id = f_organism_id AND
                                   type_id     = c_cvterm_id;

  SELECT INTO f1_id feature_id FROM feature
                             WHERE uniquename  = f1_uniquename AND
                                   organism_id = f1_organism_id AND
                                   type_id     = c_cvterm_id;

  SELECT INTO f2_id feature_id FROM feature
                             WHERE uniquename  = f2_uniquename AND
                                   organism_id = f2_organism_id AND
                                   type_id     = c_cvterm_id;

--add synonyms to new feature for all of the synonyms of the old feature
  FOR fs_row IN SELECT * FROM feature_synonym
                               WHERE feature_id = f1_id OR
                                     feature_id = f2_id LOOP
      INSERT INTO feature_synonym (feature_id, synonym_id)
            VALUES (f_id, fs_row.synonym_id);
  END LOOP;

--copy dbxref, featureprop, cvterms, pubs to the new gene
  FOR fd_row IN SELECT * FROM feature_dbxref 
                                   WHERE feature_id = f1_id OR
                                         feature_id = f2_id LOOP
      INSERT INTO feature_dbxref (feature_id,dbxref_id,is_current)
            VALUES (f_id, fd_row.dbxref_id, 0);
  END LOOP;

  FOR fp_row IN SELECT * FROM featureprop
                        WHERE feature_id = f1_id OR
                              feature_id = f2_id LOOP
      INSERT INTO featureprop (feature_id,type_id,value,rank)
            VALUES (f_id,fp_row.type_id,fp_row.value,fp_row.rank);
  END LOOP;

  FOR fc_row IN SELECT * FROM feature_cvterm
                        WHERE feature_id = f1_id OR
                              feature_id = f2_id LOOP
      INSERT INTO feature_cvterm (feature_id,cvterm_id,pub_id,is_not)
            VALUES (f_id,fc_row.cvterm_id,fc_row.pub_id,fc_row.is_not);
  END LOOP; 

  FOR fpub_row IN SELECT * FROM feature_pub
                           WHERE feature_id = f1_id OR
                                 feature_id = f2_id LOOP
      INSERT INTO feature_pub (feature_id,pub_id)
            VALUES (f_id,fpub_row.pub_id);
  END LOOP;

--delete featureloc entries for old genes
  DELETE FROM featureloc WHERE feature_id=f1_id;
  DELETE FROM featureloc WHERE feature_id=f2_id;

--mark old gene features as obsolete
  UPDATE feature SET is_obsolete=true WHERE feature_id=f1_id;
  UPDATE feature SET is_obsolete=true WHERE feature_id=f2_id;

--note in either feature_relationship or featureprop the origin of this gene



  RETURN f_uniquename;
END;
'LANGUAGE plpgsql; 


-- function to fascilitate gene splits
-- Takes three arguments:
--   -the feature_id of the old gene that was split
--   -the feature_id of the new genes
--WARNING: COMPLETELY UNTESTED
CREATE OR REPLACE FUNCTION apollo_split(int,int,int) RETURNS int AS
'
DECLARE
  f_id                  ALIAS FOR $1;
  f1_id                ALIAS FOR $2;
  f2_id                ALIAS FOR $3;
  f_type                cvterm.name%TYPE;
  f_organism_id		feature.organism_id%TYPE;
  f1_organism_id        feature.organism_id%TYPE;
  f2_organism_id        feature.organism_id%TYPE;
  f_type_gene           CONSTANT varchar :=''gene'';
  c_cvterm_id           cvterm.cvterm_id%TYPE;
  fs_row                feature_synonym%ROWTYPE;
  fd_row		feature_dbxref%ROWTYPE;
  fpub_row              pub%ROWTYPE;
  fp_row                featureprop%ROWTYPE;
  fc_row                feature_cvterm%ROWTYPE;
BEGIN

--do some error checking; first, make sure they are all genes
  SELECT INTO f_type c.name FROM feature f, cvterm c
                            WHERE f.feature_id = f_id AND
                                  f.type_id    = c.cvterm_id;

  IF f_type <> f_type_gene THEN
      RAISE NOTICE ''The uniquename for the feature provided must be that of a gene'';
      RETURN OLD;
  END IF;

  SELECT INTO f_type c.name FROM feature f, cvterm c
                            WHERE f.feature_id = f1_id AND
                                  f.type_id    = c.cvterm_id;

  IF f_type <> f_type_gene THEN
      RAISE NOTICE ''The uniquename for the feature provided must be that of a gene'';
      RETURN OLD;
  END IF;

  SELECT INTO f_type c.name FROM feature f, cvterm c
                            WHERE f.feature_id = f2_id AND
                                  f.type_id    = c.cvterm_id;

  IF f_type <> f_type_gene THEN
      RAISE NOTICE ''The uniquename for the feature provided must be that of a gene'';
      RETURN OLD;
  END IF;

--more error checking: are they all from the same organism?
  SELECT INTO f_organism_id organism_id FROM feature
                                        WHERE feature_id = f_id;

  SELECT INTO f1_organism_id organism_id FROM feature
                                        WHERE feature_id = f1_id;

  SELECT INTO f2_organism_id organism_id FROM feature
                                        WHERE feature_id = f2_id;

  IF f_organism_id <> f1_organism_id OR f_organism_id <> f2_organism_id THEN
      RAISE NOTICE ''The new gene and the old genes need to come from the same organism'';
      RETURN OLD;
  END IF;

  SELECT INTO c_cvterm_id type_id FROM feature
                                 WHERE feature_id = f_id;

--add synonyms to new feature for all of the synonyms of the old feature
  FOR fs_row IN SELECT * FROM feature_synonym
                        WHERE feature_id = f_id LOOP
      INSERT INTO feature_synonym (feature_id, synonym_id, pub_id)
            VALUES (f1_id, fs_row.synonym_id, fs_row.pub_id);
      INSERT INTO feature_synonym (feature_id, synonym_id, pub_id)
            VALUES (f2_id, fs_row.synonym_id, fs_row.pub_id);
  END LOOP;

--copy dbxref, featureprop, cvterms, pubs to the new gene
  FOR fd_row IN SELECT * FROM feature_dbxref
                        WHERE feature_id = f_id LOOP
      INSERT INTO feature_dbxref (feature_id,dbxref_id,is_current)
            VALUES (f1_id, fd_row.dbxref_id, 0);
      INSERT INTO feature_dbxref (feature_id,dbxref_id,is_current)
            VALUES (f2_id, fd_row.dbxref_id, 0);
  END LOOP;

  FOR fp_row IN SELECT * FROM featureprop
                        WHERE feature_id = f_id LOOP
      INSERT INTO featureprop (feature_id,type_id,value,rank)
            VALUES (f1_id,fp_row.type_id,fp_row.value,fp_row.rank);
      INSERT INTO featureprop (feature_id,type_id,value,rank)
            VALUES (f2_id,fp_row.type_id,fp_row.value,fp_row.rank);

  END LOOP;

  FOR fc_row IN SELECT * FROM feature_cvterm
                        WHERE feature_id = f_id LOOP
      INSERT INTO feature_cvterm (feature_id,cvterm_id,pub_id,is_not)
            VALUES (f1_id,fc_row.cvterm_id,fc_row.pub_id,fc_row.is_not);
      INSERT INTO feature_cvterm (feature_id,cvterm_id,pub_id,is_not)
            VALUES (f2_id,fc_row.cvterm_id,fc_row.pub_id,fc_row.is_not);
  END LOOP;

  FOR fpub_row IN SELECT * FROM feature_pub
                       WHERE feature_id = f_id LOOP
      INSERT INTO feature_pub (feature_id,pub_id)
            VALUES (f1_id,p_row.pub_id);
      INSERT INTO feature_pub (feature_id,pub_id)
            VALUES (f2_id,p_row.pub_id);
  END LOOP;


--delete featureloc entries for old genes
  DELETE FROM featureloc WHERE feature_id=f_id;

--mark old gene features as obsolete
  UPDATE feature SET is_obsolete=true WHERE feature_id=f_id;

--note in either feature_relationship or featureprop the origin of this gene



  RETURN 1;
END;
'LANGUAGE plpgsql;