This repository was archived by the owner on Jun 3, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 250
Expand file tree
/
Copy pathrhn_server.pkb
More file actions
822 lines (753 loc) · 24.3 KB
/
rhn_server.pkb
File metadata and controls
822 lines (753 loc) · 24.3 KB
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
-- oracle equivalent source sha1 8f107c46693d3aabea4a71dd366ee1347d4cf0be
--
-- Copyright (c) 2008--2014 Red Hat, Inc.
--
-- This software is licensed to you under the GNU General Public License,
-- version 2 (GPLv2). There is NO WARRANTY for this software, express or
-- implied, including the implied warranties of MERCHANTABILITY or FITNESS
-- FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
-- along with this software; if not, see
-- http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
--
-- Red Hat trademarks are not licensed under GPLv2. No permission is
-- granted to use or replicate Red Hat trademarks that are incorporated
-- in this software or its documentation.
--
--
--
--
-- create schema rhn_server;
--update pg_setting
update pg_settings set setting = 'rhn_server,' || setting where name = 'search_path';
create or replace function system_service_level(
server_id_in in numeric,
service_level_in in varchar
) returns numeric as $$
declare
ents cursor is
select label from rhnServerEntitlementView
where server_id = server_id_in;
retval numeric := 0;
begin
for ent in ents loop
retval := rhn_entitlements.entitlement_grants_service (ent.label, service_level_in);
if retval = 1 then
return retval;
end if;
end loop;
return retval;
end$$ language plpgsql;
create or replace function can_change_base_channel(server_id_in IN NUMERIC)
returns numeric
as $$
declare
throwaway numeric;
begin
-- the idea: if we get past this query, the server is
-- neither sat nor proxy, so base channel is changeable
select 1 into throwaway
from rhnServer S
where S.id = server_id_in
and not exists (select 1 from rhnSatelliteInfo SI where SI.server_id = S.id)
and not exists (select 1 from rhnProxyInfo PI where PI.server_id = S.id);
if not found then
return 0;
end if;
return 1;
end$$ language plpgsql;
create or replace function set_custom_value(
server_id_in in numeric,
user_id_in in numeric,
key_label_in in varchar,
value_in in varchar
) returns void
as $$
declare
key_id_val numeric;
begin
select CDK.id into strict key_id_val
from rhnCustomDataKey CDK,
rhnServer S
where S.id = server_id_in
and S.org_id = CDK.org_id
and CDK.label = key_label_in;
begin
insert into rhnServerCustomDataValue (server_id, key_id, value, created_by, last_modified_by)
values (server_id_in, key_id_val, value_in, user_id_in, user_id_in);
exception
when UNIQUE_VIOLATION
then
update rhnServerCustomDataValue
set value = value_in,
last_modified_by = user_id_in
where server_id = server_id_in
and key_id = key_id_val;
end;
end$$ language plpgsql;
create or replace function bulk_set_custom_value(
key_label_in in varchar,
value_in in varchar,
set_label_in in varchar,
set_uid_in in numeric
)
returns integer
as $$
declare
i integer;
server record;
begin
i := 0;
for server in (
SELECT user_id, label, element, element_two
FROM rhnSet
WHERE label = set_label_in
AND user_id = set_uid_in
) loop
if rhn_server.system_service_level(server.element, 'provisioning') = 1 then
perform rhn_server.set_custom_value(server.element, set_uid_in, key_label_in, value_in);
i := i + 1;
end if;
end loop;
return i;
end$$ language plpgsql;
create or replace function bulk_snapshot_tag(
org_id_in in numeric,
tagname_in in varchar,
set_label_in in varchar,
set_uid_in in numeric
) returns void
as $$
declare
server record;
snapshot_id numeric;
begin
for server in (
SELECT user_id, label, element, element_two
FROM rhnSet
WHERE label = set_label_in
AND user_id = set_uid_in
) loop
if rhn_server.system_service_level(server.element, 'provisioning') = 1 then
select max(id) into snapshot_id
from rhnSnapshot
where server_id = server.element;
if snapshot_id is null then
perform rhn_server.snapshot_server(server.element, 'tagging system: ' || tagname_in);
select max(id) into snapshot_id
from rhnSnapshot
where server_id = server.element;
end if;
-- now have a snapshot_id to work with...
begin
perform rhn_server.tag_snapshot(snapshot_id, org_id_in, tagname_in);
exception
when UNIQUE_VIOLATION
then
-- do nothing, be forgiving...
null;
end;
end if;
end loop;
end$$ language plpgsql;
create or replace function tag_delete(
server_id_in in numeric,
tag_id_in in numeric
) returns void
as $$
declare
snapshots cursor is
select snapshot_id
from rhnSnapshotTag
where tag_id = tag_id_in;
tag_id_tmp numeric;
begin
select id into tag_id_tmp
from rhnTag
where id = tag_id_in
for update;
delete
from rhnSnapshotTag
where server_id = server_id_in
and tag_id = tag_id_in;
for snapshot in snapshots loop
return;
end loop;
delete
from rhnTag
where id = tag_id_in;
end$$ language plpgsql;
create or replace function tag_snapshot(
snapshot_id_in in numeric,
org_id_in in numeric,
tagname_in in varchar
) returns void
as $$
begin
insert into rhnSnapshotTag (snapshot_id, server_id, tag_id)
select snapshot_id_in, server_id, lookup_tag(org_id_in, tagname_in)
from rhnSnapshot
where id = snapshot_id_in;
end$$ language plpgsql;
create or replace function bulk_snapshot(
reason_in in varchar,
set_label_in in varchar,
set_uid_in in numeric
) returns void
as $$
declare
server record;
begin
for server in (
SELECT user_id, label, element, element_two
FROM rhnSet
WHERE label = set_label_in
AND user_id = set_uid_in
) loop
if rhn_server.system_service_level(server.element, 'provisioning') = 1 then
perform rhn_server.snapshot_server(server.element, reason_in);
end if;
end loop;
end$$ language plpgsql;
create or replace function snapshot_server(
server_id_in in numeric,
reason_in in varchar
) returns void
as $$
declare
snapshot_id_v numeric;
revisions cursor is
select distinct
cr.id
from rhnConfigRevision cr,
rhnConfigFileName cfn,
rhnConfigFile cf,
rhnConfigChannel cc,
rhnServerConfigChannel scc
where 1=1
and scc.server_id = server_id_in
and scc.config_channel_id = cc.id
and cc.id = cf.config_channel_id
and cf.id = cr.config_file_id
and cr.id = cf.latest_config_revision_id
and cf.config_file_name_id = cfn.id
and cf.id = lookup_first_matching_cf(scc.server_id, cfn.path);
locked integer;
begin
select nextval('rhn_snapshot_id_seq') into snapshot_id_v;
insert into rhnSnapshot (id, org_id, server_id, reason) (
select snapshot_id_v,
s.org_id,
server_id_in,
reason_in
from rhnServer s
where s.id = server_id_in
);
insert into rhnSnapshotChannel (snapshot_id, channel_id) (
select snapshot_id_v, sc.channel_id
from rhnServerChannel sc
where sc.server_id = server_id_in
);
insert into rhnSnapshotServerGroup (snapshot_id, server_group_id) (
select snapshot_id_v, sgm.server_group_id
from rhnServerGroupMembers sgm
where sgm.server_id = server_id_in
);
locked := 0;
<<iloop>>
while true loop
begin
insert into rhnPackageNEVRA (id, name_id, evr_id, package_arch_id)
select nextval('rhn_pkgnevra_id_seq'), sp.name_id, sp.evr_id, sp.package_arch_id
from rhnServerPackage sp
where sp.server_id = server_id_in
and not exists
(select 1
from rhnPackageNEVRA nevra
where nevra.name_id = sp.name_id
and nevra.evr_id = sp.evr_id
and (nevra.package_arch_id = sp.package_arch_id
or (nevra.package_arch_id is null
and sp.package_arch_id is null)));
exit iloop;
exception when unique_violation then
if locked = 1 then
raise;
else
lock table rhnPackageNEVRA in exclusive mode;
locked := 1;
end if;
end;
end loop;
insert into rhnSnapshotPackage (snapshot_id, nevra_id) (
select distinct snapshot_id_v, nevra.id
from rhnServerPackage sp, rhnPackageNEVRA nevra
where sp.server_id = server_id_in
and nevra.name_id = sp.name_id
and nevra.evr_id = sp.evr_id
and (nevra.package_arch_id = sp.package_arch_id
or (nevra.package_arch_id is null
and sp.package_arch_id is null))
);
insert into rhnSnapshotConfigChannel ( snapshot_id, config_channel_id ) (
select snapshot_id_v, scc.config_channel_id
from rhnServerConfigChannel scc
where server_id = server_id_in
);
for revision in revisions loop
insert into rhnSnapshotConfigRevision (
snapshot_id, config_revision_id
) values (
snapshot_id_v, revision.id
);
end loop;
end$$ language plpgsql;
create or replace function remove_action(
server_id_in in numeric,
action_id_in in numeric
) returns void
as $$
declare
-- this really wants "nulls last", but 8.1.7.3.0 sucks ass.
-- instead, we make a local table that holds our
-- list of ids with null prereqs. There's surely a better way
-- (an array instead of a table maybe? who knows...)
-- but I've got code to do this handy that I can look at ;)
chained_actions cursor is
with recursive r(id, prerequisite) as (
select id, prerequisite
from rhnAction
where id = action_id_in
union all
select r1.id, r1.prerequisite
from rhnAction r1, r
where r.id = r1.prerequisite
)
select * from r
order by prerequisite desc;
sessions cursor is
select s.id
from rhnKickstartSession s
where server_id_in in (s.old_server_id, s.new_server_id)
and s.action_id = action_id_in
and not exists (
select 1
from rhnKickstartSessionState ss
where ss.id = s.state_id
and ss.label in ('failed','complete')
);
chain_ends numeric[];
i numeric;
prereq numeric := 1;
begin
select prerequisite
into prereq
from rhnAction
where id = action_id_in;
if prereq is not null then
perform rhn_exception.raise_exception('action_is_child');
end if;
chain_ends := '{}';
i := 1;
for action in chained_actions loop
if action.prerequisite is null then
chain_ends[i] := action.id;
i := i + 1;
else
delete from rhnServerAction
where server_id = server_id_in
and action_id = action.id;
end if;
end loop;
delete from rhnServerAction
where server_id = server_id_in
and action_id = any(chain_ends);
for s in sessions loop
update rhnKickstartSession
set state_id = (
select id
from rhnKickstartSessionState
where label = 'failed'
),
action_id = null
where id = s.id;
perform set_ks_session_history_message(s.id, 'failed', 'Kickstart cancelled due to action removal');
end loop;
end$$ language plpgsql;
create or replace function check_user_access(server_id_in in numeric, user_id_in in numeric)
returns numeric
as $$
declare
has_access numeric;
begin
-- first check; if this returns no rows, then the server/user are in different orgs, and we bail
select 1 into has_access
from rhnServer S,
web_contact wc
where wc.org_id = s.org_id
and s.id = server_id_in
and wc.id = user_id_in;
if not found then
return 0;
end if;
-- okay, so they're in the same org. if we have an org admin, they get a free pass
if rhn_user.check_role(user_id_in, 'org_admin') = 1
then
return 1;
end if;
select 1 into has_access
from rhnServerGroupMembers SGM,
rhnUserServerGroupPerms USG
where SGM.server_group_id = USG.server_group_id
and SGM.server_id = server_id_in
and USG.user_id = user_id_in;
if not found then
return 0;
end if;
return 1;
end$$ language plpgsql;
-- *******************************************************************
-- FUNCTION: can_server_consume_virt_slot
-- Returns 1 if the server id is eligible to consume a virtual slot,
-- else returns 0.
-- Called by: insert_into_servergroup, delete_from_servergroup
-- *******************************************************************
create or replace function can_server_consume_virt_slot(server_id_in in numeric,
group_type_in in varchar)
returns numeric
as $$
declare
server_virt_slots cursor is
select vi.VIRTUAL_SYSTEM_ID
from
rhnVirtualInstance vi
where
-- server id is a virtual instance
vi.VIRTUAL_SYSTEM_ID = server_id_in
-- server id's host is virt entitled
and exists ( select 1
from rhnServerEntitlementView sev
where vi.HOST_SYSTEM_ID = sev.server_id
and sev.label in ('virtualization_host',
'virtualization_host_platform') )
-- server id's host also has the ent we want
and exists ( select 1
from rhnServerEntitlementView sev2
where vi.HOST_SYSTEM_ID = sev2.server_id
and sev2.label = group_type_in );
begin
for server_virt_slot in server_virt_slots loop
return 1;
end loop;
return 0;
end$$ language plpgsql;
create or replace function insert_into_servergroup (
server_id_in in numeric,
server_group_id_in in numeric
) returns void
as $$
declare
used_slots numeric;
max_slots numeric;
org_id numeric;
mgmt_available numeric;
mgmt_upgrade numeric;
mgmt_sgid numeric;
prov_available numeric;
prov_upgrade numeric;
prov_sgid numeric;
group_label varchar;
group_type numeric;
begin
-- first, group_type = null, because it's easy...
-- this will rowlock the servergroup we're trying to change;
-- we probably need to lock the other one, but I think the chances
-- of it being a real issue are very small for now...
select sg.group_type, sg.org_id, sg.current_members, sg.max_members
into group_type, org_id, used_slots, max_slots
from rhnServerGroup sg
where sg.id = server_group_id_in
for update of sg;
if group_type is null then
if used_slots >= max_slots then
perform rhn_exception.raise_exception('servergroup_max_members');
end if;
insert into rhnServerGroupMembers(
server_id, server_group_id
) values (
server_id_in, server_group_id_in
);
update rhnServerGroup
set current_members = current_members + 1
where id = server_group_id_in;
perform rhn_cache.update_perms_for_server_group(server_group_id_in);
return;
end if;
-- now for group_type != null
--
select label
into group_label
from rhnServerGroupType sgt
where sgt.id = group_type;
-- the naive easy path that gets hit most often and has to be quickest.
if group_label in ('sw_mgr_entitled',
'enterprise_entitled',
'monitoring_entitled',
'provisioning_entitled',
'virtualization_host',
'virtualization_host_platform') then
if used_slots >= max_slots and
(rhn_server.can_server_consume_virt_slot(server_id_in, group_label) != 1)
then
perform rhn_exception.raise_exception('servergroup_max_members');
end if;
insert into rhnServerGroupMembers(
server_id, server_group_id
) values (
server_id_in, server_group_id_in
);
-- Only update current members if the system in consuming a
-- physical slot.
if rhn_server.can_server_consume_virt_slot(server_id_in, group_label) = 0 then
update rhnServerGroup
set current_members = current_members + 1
where id = server_group_id_in;
end if;
return;
end if;
end$$ language plpgsql;
create or replace function insert_into_servergroup_maybe (
server_id_in in numeric,
server_group_id_in in numeric
) returns numeric as $$
declare
retval numeric := 0;
servergroups cursor is
select s.id server_id,
sg.id server_group_id
from rhnServerGroup sg,
rhnServer s
where s.id = server_id_in
and sg.id = server_group_id_in
and s.org_id = sg.org_id
and not exists (
select 1
from rhnServerGroupMembers sgm
where sgm.server_id = s.id
and sgm.server_group_id = sg.id
);
begin
for sgm in servergroups loop
perform rhn_server.insert_into_servergroup(sgm.server_id, sgm.server_group_id);
retval := retval + 1;
end loop;
return retval;
end$$ language plpgsql;
create or replace function insert_set_into_servergroup (
server_group_id_in in numeric,
user_id_in in numeric,
set_label_in in varchar
) returns void
as $$
declare
servers cursor is
select st.element id
from rhnSet st
where st.user_id = user_id_in
and st.label = set_label_in
and exists (
select 1
from rhnUserManagedServerGroups umsg
where umsg.server_group_id = server_group_id_in
and umsg.user_id = user_id_in
)
and not exists (
select 1
from rhnServerGroupMembers sgm
where sgm.server_id = st.element
and sgm.server_group_id = server_group_id_in
);
begin
for s in servers loop
perform rhn_server.insert_into_servergroup(s.id, server_group_id_in);
end loop;
end$$ language plpgsql;
create or replace function delete_from_servergroup (
server_id_in in numeric,
server_group_id_in in numeric
) returns void
as $$
declare
server_virt_groups cursor is
select 1
from rhnServerEntitlementVirtual sev
where sev.server_id = server_id_in
and sev.server_group_id = server_group_id_in;
oid numeric;
mgmt_sgid numeric;
label varchar;
group_type numeric;
begin
select sg.group_type, sg.org_id
into group_type, oid
from rhnServerGroupMembers sgm,
rhnServerGroup sg
where sg.id = server_group_id_in
and sg.id = sgm.server_group_id
and sgm.server_id = server_id_in
for update of sg;
if not found then
perform rhn_exception.raise_exception('server_not_in_group');
end if;
-- do group_type is null first
if group_type is null then
delete from rhnServerGroupMembers
where server_group_id = server_group_id_in
and server_id = server_id_in;
update rhnServerGroup
set current_members = current_members - 1
where id = server_group_id_in;
perform rhn_cache.update_perms_for_server_group(server_group_id_in);
return;
end if;
select sgt.label
into label
from rhnServerGroupType sgt
where sgt.id = group_type;
if label in ('sw_mgr_entitled',
'enterprise_entitled',
'provisioning_entitled',
'monitoring_entitled',
'virtualization_host',
'virtualization_host_platform') then
-- Only update current members if the system is consuming
-- a physical slot.
for server_virt_group in server_virt_groups loop
delete from rhnServerGroupMembers
where server_group_id = server_group_id_in
and server_id = server_id_in;
return;
end loop;
delete from rhnServerGroupMembers
where server_group_id = server_group_id_in
and server_id = server_id_in;
update rhnServerGroup
set current_members = current_members - 1
where id = server_group_id_in;
end if;
end$$ language plpgsql;
create or replace function delete_set_from_servergroup (
server_group_id_in in numeric,
user_id_in in numeric,
set_label_in in varchar
) returns void
as $$
declare
servergroups cursor is
select sgm.server_id, sgm.server_group_id
from rhnSet st,
rhnServerGroupMembers sgm
where sgm.server_group_id = server_group_id_in
and st.user_id = user_id_in
and st.label = set_label_in
and sgm.server_id = st.element
and exists (
select 1
from rhnUserManagedServerGroups usgp
where usgp.server_group_id = server_group_id_in
and usgp.user_id = user_id_in
);
begin
for sgm in servergroups loop
perform rhn_server.delete_from_servergroup(sgm.server_id, server_group_id_in);
end loop;
end$$ language plpgsql;
create or replace function clear_servergroup (
server_group_id_in in numeric
) returns void
as $$
declare
servers cursor is
select sgm.server_id id
from rhnServerGroupMembers sgm
where sgm.server_group_id = server_group_id_in;
begin
for s in servers loop
perform rhn_server.delete_from_servergroup(s.id, server_group_id_in);
end loop;
end$$ language plpgsql;
create or replace function delete_from_org_servergroups (
server_id_in in numeric
) returns void
as $$
declare
servergroups cursor is
select sgm.server_group_id id
from rhnServerGroup sg,
rhnServerGroupMembers sgm
where sgm.server_id = server_id_in
and sgm.server_group_id = sg.id
and sg.group_type is null;
begin
for sg in servergroups loop
perform rhn_server.delete_from_servergroup(server_id_in, sg.id);
end loop;
end$$ language plpgsql;
create or replace function get_ip_address (
server_id_in in numeric
) returns varchar as $$
declare
interfaces cursor is
select ni.name as name, na4.address as address
from rhnServerNetInterface ni,
rhnServerNetAddress4 na4
where server_id = server_id_in
and ni.id = na4.interface_id
and na4.address != '127.0.0.1';
addresses cursor is
select ipaddr ip_addr
from rhnServerNetwork
where server_id = server_id_in
and ipaddr != '127.0.0.1';
begin
for addr in addresses loop
return addr.ip_addr;
end loop;
for iface in interfaces loop
return iface.address;
end loop;
return NULL;
end$$ language plpgsql;
create or replace function update_needed_cache(
server_id_in in numeric
) returns void as $$
begin
delete from rhnServerNeededCache
where server_id = server_id_in;
insert into rhnServerNeededCache
(server_id, errata_id, package_id, channel_id)
(select distinct sp.server_id, x.errata_id, p.id, x.channel_id
FROM (SELECT sp_sp.server_id, sp_sp.name_id,
sp_sp.package_arch_id, max(sp_pe.evr) AS max_evr
FROM rhnServerPackage sp_sp
join rhnPackageEvr sp_pe ON sp_pe.id = sp_sp.evr_id
GROUP BY sp_sp.server_id, sp_sp.name_id, sp_sp.package_arch_id) sp
join rhnPackage p ON p.name_id = sp.name_id
join rhnPackageEvr pe ON pe.id = p.evr_id AND sp.max_evr < pe.evr
join rhnPackageUpgradeArchCompat puac
ON puac.package_arch_id = sp.package_arch_id
AND puac.package_upgrade_arch_id = p.package_arch_id
join rhnServerChannel sc ON sc.server_id = sp.server_id
join rhnChannelPackage cp ON cp.package_id = p.id
AND cp.channel_id = sc.channel_id
left join (SELECT ep.errata_id, ce.channel_id, ep.package_id
FROM rhnChannelErrata ce
join rhnErrataPackage ep
ON ep.errata_id = ce.errata_id
join rhnServerChannel sc_sc
ON sc_sc.channel_id = ce.channel_id
WHERE sc_sc.server_id = server_id_in) x
ON x.channel_id = sc.channel_id AND x.package_id = cp.package_id
where sp.server_id = server_id_in);
end$$ language plpgsql;
-- restore the original setting
update pg_settings set setting = overlay( setting placing '' from 1 for (length('rhn_server')+1) ) where name = 'search_path';