DatabaseProcApplicationCreatedLinks
sybsystemprocssp_changegroup  14 déc. 14Defects Propagation Dependencies

1     
2     /* Sccsid = "%Z% generic/sproc/src/%M% %I% %G%" */
3     /*	4.8	1.1	06/14/90	sproc/src/changegroup */
4     
5     /*
6     ** Messages for "sp_changegroup"        17370
7     **
8     ** 17289, "Set your curwrite to the hurdle of current database."
9     ** 17333, "No such group exists."
10    **      (is now: "No group with the specified name exists.")
11    ** 17232, "No such user exists."
12    **      (is now: "No user with the specified name exists in the current
13    ** database.")
14    ** 17370, "Group changed."
15    ** 17756, "The execution of the stored procedure '%1!' in database
16    **         '%2!' was aborted because there was an error in writing the
17    **         replication log record."
18    ** 18773, "HA_LOG: HA consistency check failure in '%1!' on the companion server '%2!'"
19    ** 18776, "Please also run stored procedure '%1!' on the companion server '%2!'."
20    ** 18792, "Unable to find a group with name '%1!' and id '%2!' in sysusers."
21    ** 18793, "Unable to find a user with name '%1!' and id '%2!' in sysusers."
22    ** 17019, "Failed to delete the predicate '%1!'."
23    */
24    
25    /* 
26    ** IMPORTANT: Please read the following instructions before
27    **   making changes to this stored procedure.
28    **
29    **	To make this stored procedure compatible with High Availability (HA),
30    **	changes to certain system tables must be propagated 
31    **	to the companion server under some conditions.
32    **	The tables include (but are not limited to):
33    **		syslogins, sysservers, sysattributes, systimeranges,
34    **		sysresourcelimits, sysalternates, sysdatabases,
35    **		syslanguages, sysremotelogins, sysloginroles,
36    **		sysalternates (master DB only), systypes (master DB only),
37    **		sysusers (master DB only), sysprotects (master DB only)
38    **	please refer to the HA documentation for detail.
39    **
40    **	Here is what you need to do: 
41    **	For each insert/update/delete statement, add three sections to
42    **	-- start HA transaction prior to the statement
43    **	-- add the statement
44    **	-- add HA synchronization code to propagate the change to the companion
45    **
46    **	For example, if you are adding 
47    **		insert master.dbo.syslogins ......
48    **	the code should look like:
49    **	1. Before that SQL statement:
50    **		
51    **	2. Now, the SQL statement:
52    **		insert master.dbo.syslogins ......
53    **	3. Add a HA synchronization section right after the SQL statement:
54    **		
55    **
56    **	You may need to do similar change for each built-in function you
57    **	want to add.
58    **
59    **	After that, you need to add a separate part at a place where it can not
60    **	be reached by the normal execution path:
61    **	clean_all:
62    **		
63    **		return (1)
64    */
65    
66    create or replace procedure sp_changegroup
67        @grpname varchar(30), /* group name */
68        @username varchar(30) /* user name to add to group */
69    as
70    
71        declare @gid int /* group id */
72        declare @uid int /* user id */
73        declare @msg varchar(1024)
74        declare @id int /* object id */
75        declare @grantee int /* grantee */
76        declare @action smallint /* action (i.e select, insert) */
77        declare @protecttype tinyint /* grant/revoke/option */
78        declare @columns varbinary(133) /* column priv bit map */
79        declare @grantor int /* grantor */
80        declare @predid int /* predicate id */
81        declare @grp_predid int /* predicate id for group */
82        declare @pub_predid int /* predicate id for public */
83        declare @gcolumns varbinary(133) /* group column privileges */
84        declare @pcolumns varbinary(133) /* public column privileges */
85        declare @aggrprivs tinyint /* object level privs of group and public */
86        declare @predname varchar(767)
87        declare @aggrcolumns varbinary(133) /* aggregate of group and public privileges */
88        declare @col_count smallint
89        declare @dummy int
90        declare @dbname varchar(30)
91        declare @HA_CERTIFIED tinyint /* Is the SP HA certified ? */
92        declare @retstat int
93        declare @builtin_retstat int
94        declare @gp_enabled int
95        declare @nullarg char(1)
96        declare @status1 int
97        declare @status2 int
98    
99    
100       select @status1 = 1
101       select @status2 = 1
102   
103       select @dbname = db_name()
104   
105   
106   
107       select @HA_CERTIFIED = 0
108   
109   
110   
111   
112       /* Check to see if we are using HA specific SP for a HA enabled server */
113       exec @retstat = sp_ha_check_certified 'sp_changegroup', @HA_CERTIFIED
114       if (@retstat != 0)
115           return (1)
116   
117       if @@trancount = 0
118       begin
119           set chained off
120       end
121   
122       set transaction isolation level 1
123   
124       /*
125       **  Only the Database Owner (DBO) or
126       **  Accounts with SA or SSO role can execute it.
127       **  If the user has SA role, it's uid will
128       **  be DBO uid (1). If granular permissions is enabled then
129       **  users with 'manage any user' permission can execute it.
130       */
131       select @nullarg = NULL
132       execute @status1 = sp_aux_checkroleperm "sso_role",
133           "manage any user", @dbname, @gp_enabled output
134   
135       if (@status1 != 0)
136       begin
137           if (@gp_enabled = 0)
138           begin
139               if (user_id() != 1)
140               begin
141                   execute @status2 = sp_aux_checkroleperm "sa_role",
142                       @nullarg, @nullarg, @gp_enabled output
143   
144                   if (@status2 > 0)
145                   begin
146                       /* 
147                       ** proc_role() will raise permission errors
148                       ** and send audit records to the audit trail.
149                       */
150                       select @dummy = proc_role("sa_role")
151                       select @dummy = proc_role("sso_role")
152                       return (1)
153                   end
154               end
155           end
156           else
157           begin
158               /* 
159               ** Call proc_auditperm here to do auditing and error 
160               ** message. 
161               */
162               select @dummy = proc_auditperm("manage any user",
163                       @status1, @dbname)
164               return (1)
165           end
166       end
167   
168       /* 
169       ** Send apropriate audit records, already determined user has one
170       ** of the roles or the permission. 
171       */
172       if (@gp_enabled = 0)
173       begin
174           if (@status1 = 0)
175               select @dummy = proc_role("sso_role")
176   
177           if (@status2 = 0)
178               select @dummy = proc_role("sa_role")
179       end
180       else
181       begin
182           select @dummy = proc_auditperm("manage any user",
183                   @status1, @dbname)
184       end
185   
186       /* See if the group name exists. */
187       select @gid = uid from sysusers
188       where name = @grpname
189           and (uid = gid)
190           and not exists (select name from master.dbo.syssrvroles where name = @grpname)
191   
192       /* If no such group, quit. */
193       if @gid is NULL
194       begin
195           /* 17333, "No group with the specified name exists." */
196           raiserror 17333
197           return (1)
198       end
199   
200       /* See if the user name exists. */
201       select @uid = uid from sysusers
202       where name = @username
203           and ((uid >= @@minuserid and uid < @@mingroupid and uid != 0)
204               or uid > @@maxgroupid)
205   
206       /* If no such user in the database, quit. */
207       if @uid is NULL
208       begin
209   
210           /*
211           ** 17232, "No such user exists."
212           */
213           raiserror 17232
214           return (1)
215       end
216   
217       select @dbname = db_name()
218       /*
219       ** At this stage everything is consistent with respect to parameters.
220       ** Now we need to update the GRANTS/REVOKES to the user with respect to
221       ** the new group
222       */
223   
224       begin transaction rs_logexec
225   
226       /* Cursor to find tuples in sysprotects for which grantee is @uid */
227       declare priv_curs cursor for
228       select id, uid, action, protecttype, columns, grantor, predid
229       from sysprotects
230       where uid = @uid
231       for update
232   
233       /* Open the cursor and start fetching from it */
234   
235       open priv_curs
236   
237   
238       fetch priv_curs into @id, @grantee, @action, @protecttype, @columns, @grantor,
239           @predid
240   
241       /* Loop for all qualifying rows */
242       while (@@sqlstatus != 2)
243       begin
244           if (@@sqlstatus = 1)
245           begin
246               /* Error in fetching from the cursor */
247               raiserror 17333
248               rollback transaction rs_logexec
249               return (1)
250           end
251   
252           /*
253           ** 193 is SELECT, 197 is UPDATE, 151 is REFERENCES, 353 is DECRYPT. 
254           **	These are column level privileges 
255           */
256           if ((@action != 193) and (@action != 197) and (@action != 151) and
257                   (@action != 353))
258           begin
259               /*
260               ** These are object level privileges 
261               ** Note that grant with grant can't be given to group/PUBLIC thus
262               ** not considered  
263               */
264               if (@protecttype = 1)
265               begin
266                   /* It is a grant row  */
267                   /* Initialize aggregate privs */
268                   select @aggrprivs = 0
269   
270                   /* Check if this grant is available to public */
271                   if (exists (select * from sysprotects
272                               where (id = @id) and
273                                   (uid = 0) and
274                                   (action = @action) and
275                                   (protecttype = @protecttype) and
276                                   (grantor = @grantor)))
277                   begin
278                       select @aggrprivs = 1
279                   end
280   
281                   if (@aggrprivs = 1)
282                   begin
283                       /* 
284                       ** The grant of this privilege is available thru PUBLIC
285                       ** check if there is a revoke to the new group 
286                       */
287                       if (exists (select * from sysprotects
288                                   where (id = @id) and
289                                       (uid = @gid) and
290                                       (action = @action) and
291                                       (protecttype = 2) and
292                                       (grantor = @grantor)))
293                       begin
294                           /* 
295                           ** The revoke from group nullifies the grant from 
296                           ** PUBLIC 
297                           */
298                           select @aggrprivs = 0
299                       end
300                   end
301                   else
302                   begin
303                       /* 
304                       ** The privilege was not available thru PUBLIC, check if
305                       ** it is available thru group 
306                       */
307                       if (exists (select * from sysprotects
308                                   where (id = @id) and
309                                       (uid = @gid) and
310                                       (action = @action) and
311                                       (protecttype = 1) and
312                                       (grantor = @grantor) and
313                                       (predid is NULL)))
314                       begin
315                           /* The privilege is inherited from the group */
316                           select @aggrprivs = 1
317                       end
318                   end
319   
320   
321                   /* 
322                   ** Delete the grant to the user, if inherited due to the 
323                   ** membership in the group or public 
324                   */
325   
326                   if (@aggrprivs = 1)
327                   begin
328   
329                       if (@predid != NULL)
330                       begin
331                           /* 
332                           ** Only delete the predicate if no other
333                           ** permission granted with same predicate
334                           */
335                           if (not exists (select * from sysprotects
336                                       where (predid = @predid) and
337                                           (action != @action or
338                                               uid != @uid)))
339                           begin
340                               select @predname = name
341                               from sysobjects
342                               where id = @predid
343   
344                               /*
345                               ** Call the builtin to delete the
346                               ** predicate. If it encounters an
347                               ** error, it will raise an exception
348                               ** and output a message to the client.
349                               */
350                               select @builtin_retstat =
351                                   rm_predicate(@predid)
352   
353                               if (@builtin_retstat = 0)
354                               begin
355                                   /* 
356                                   ** 17019, "Failed to delete the
357                                   ** predicate '%1!'."
358                                   */
359                                   raiserror 17019, @predname
360                                   rollback transaction rs_logexec
361                                   return (1)
362                               end
363   
364                           end
365                       end
366   
367                       delete from sysprotects where current of priv_curs
368                   end
369               end
370               else if (@protecttype = 2)
371               begin
372                   /* It is a revoke */
373                   if ((exists (select * from sysprotects
374                                   where (id = @id) and
375                                       (uid = @gid) and
376                                       (action = @action) and
377                                       (protecttype = @protecttype
378                                           or protecttype = 1) and
379                                       (grantor = @grantor)))
380                           or
381                           (not exists (select * from sysprotects
382                                   where (id = @id) and
383                                       (uid = @gid or uid = 0) and
384                                       (action = @action) and
385                                       (protecttype = 1) and
386                                       (grantor = @grantor))))
387                   begin
388                       /* 
389                       ** - The privilege is already revoked from the group 
390                       ** - or public has predicated privilege, user has been
391                       **   revoked permission and group has been granted
392                       **   predicated/non-predicated permission 
393                       ** - or there is no explicit grant of this privilege to 
394                       **   either group or public 
395                       ** so this revoke row not needed
396                       */
397                       delete from sysprotects where current of priv_curs
398   
399                   end
400               end
401           end
402           else
403           begin
404               /* Column level privileges */
405               /* Initialize column privilege map for public and group */
406               select @pcolumns = 0x00
407               select @gcolumns = 0x00
408   
409               /* 
410               ** Get the number of columns in this table. It is only used for
411               ** column level privileges 
412               */
413               select @col_count = count(*)
414               from syscolumns
415               where id = @id
416   
417               /* Find the column level privileges to PUBLIC */
418               if (exists (select * from sysprotects
419                           where (id = @id) and
420                               (uid = 0) and
421                               (action = @action) and
422                               (protecttype = 1) and
423                               (grantor = @grantor)))
424               begin
425                   select @pcolumns = columns, @pub_predid = predid
426                   from sysprotects
427                   where (id = @id) and
428                       (uid = 0) and
429                       (action = @action) and
430                       (protecttype = 1) and
431                       (grantor = @grantor)
432               end
433   
434               /* Find the column level privilege to the new group */
435               if (exists (select * from sysprotects
436                           where (id = @id) and
437                               (uid = @gid) and
438                               (action = @action) and
439                               (protecttype = 1) and
440                               (grantor = @grantor)))
441               begin
442                   select @gcolumns = columns, @grp_predid = predid
443                   from sysprotects
444                   where (id = @id) and
445                       (uid = @gid) and
446                       (action = @action) and
447                       (protecttype = 1) and
448                       (grantor = @grantor)
449               end
450   
451               /* 
452               ** Find the union of column privileges from public as
453               ** new group  
454               */
455               exec sybsystemprocs.dbo.syb_aux_privunion @pcolumns, @gcolumns, @col_count, @aggrcolumns output
456   
457               /* 
458               ** Find if there is a revoke row for the above privilege 
459               ** in the group 
460               */
461               select @gcolumns = 0x00
462               if (exists (select * from sysprotects
463                           where (id = @id) and
464                               (uid = @gid) and
465                               (action = @action) and
466                               (protecttype = 2) and
467                               (grantor = @grantor)))
468               begin
469                   select @gcolumns = columns from sysprotects
470                   where (id = @id) and
471                       (uid = @gid) and
472                       (action = @action) and
473                       (protecttype = 2) and
474                       (grantor = @grantor)
475   
476               end
477   
478               /* 
479               ** Subtract the revoke to columns from the group. In order to 
480               ** subtract, xor operation will do as the revoke column bit can only 
481               ** be for columns for which the user has inherited grant 
482               */
483   
484               exec sybsystemprocs.dbo.syb_aux_privexor @aggrcolumns, @gcolumns, @col_count, @aggrcolumns output
485   
486               /* 
487               ** Find if there is a grant row for the above privilege 
488               ** in the group. It is only possible to have both rows for
489               ** public and group if the privilege to public is predicated.	 
490               */
491               if (@pub_predid != NULL)
492               begin
493                   if (exists (select * from sysprotects
494                               where (id = @id) and
495                                   (uid = @gid) and
496                                   (action = @action) and
497                                   (protecttype = 1) and
498                                   (grantor = @grantor)))
499                   begin
500                       select @gcolumns = 0x00
501   
502                       select @gcolumns = columns from sysprotects
503                       where (id = @id) and
504                           (uid = @gid) and
505                           (action = @action) and
506                           (protecttype = 1) and
507                           (grantor = @grantor)
508   
509                       /* 
510                       ** Subtract the grant to columns from the group. In 
511                       ** order to subtract, xor operation will do as the grant
512                       ** column bit can ** only be for columns for which the 
513                       ** user has inherited grant 
514                       */
515                       exec sybsystemprocs.dbo.syb_aux_privexor @aggrcolumns, @gcolumns, @col_count, @aggrcolumns output
516   
517                   end
518   
519               end
520   
521               /* 
522               ** At this stage, aggrcolumns contains the effective column privileges
523               ** that are inherited 
524               */
525   
526               if (@protecttype = 1)
527               begin
528                   /* We encountered an explicit user specific grant row */
529                   exec sybsystemprocs.dbo.syb_aux_privnots @aggrcolumns, @col_count, @aggrcolumns output
530   
531                   exec sybsystemprocs.dbo.syb_aux_privsand @columns, @aggrcolumns, @col_count, @columns output
532   
533                   if (@grp_predid = NULL)
534                   begin
535                       if (@columns = 0x00)
536                       begin
537                           if (@predid != NULL)
538                           begin
539                               /* 
540                               ** Only delete the predicate if no other
541                               ** permission granted with same 
542                               ** predicate
543                               */
544                               if (not exists (select *
545                                           from sysprotects
546                                           where (predid = @predid) and
547                                               (action != @action or
548                                                   uid != @uid)))
549                               begin
550                                   select @predname = name
551                                   from sysobjects
552                                   where id = @predid
553   
554                                   /*
555                                   ** Call the builtin to delete 
556                                   ** the predicate. If it 
557                                   ** encounters an error, it will
558                                   ** raise an exception and output
559                                   ** a message to the client.
560                                   */
561                                   select @builtin_retstat =
562                                       rm_predicate(@predid)
563   
564                                   if (@builtin_retstat = 0)
565                                   begin
566                                       /* 
567                                       ** "17019, Failed to 
568                                       ** delete the predicate
569                                       ** '%1!'."
570                                       */
571                                       raiserror 17019,
572                                           @predname
573                                       rollback transaction
574                                       rs_logexec
575                                       return (1)
576                                   end
577                               end
578                           end
579   
580                           /* 
581                           ** Delete the grant row if no column is left. 
582                           ** This implies that all explicit user grants 
583                           ** were also inherited due to the user's 
584                           ** membership in the group or PUBLIC. Only 
585                           ** delete the grant row to the user if 
586                           ** the grant row to group is not predicated.	
587                           */
588                           delete sysprotects where current of priv_curs
589   
590                       end
591                       else
592                       begin
593                           /* Update the list of columns in the grant */
594                           update sysprotects set columns = @columns
595                           where current of priv_curs
596                       end
597                   end
598               end
599               else if (@protecttype = 2)
600               begin
601                   /* It is a revoke row */
602                   exec sybsystemprocs.dbo.syb_aux_privsand @columns, @aggrcolumns, @col_count, @columns output
603   
604                   /* 
605                   ** We only keep those revoke bits for which there is an inherited
606                   ** grant from the user's membership in the group or PUBLIC 
607                   */
608                   if (@columns = 0x00)
609                   begin
610                       /* Delete the revoke row if no column is left */
611                       delete sysprotects where current of priv_curs
612                   end
613                   else
614                   begin
615                       /* Update the list of columns in the revoke */
616                       update sysprotects set columns = @columns
617                       where current of priv_curs
618                   end
619               end
620           end
621   
622           /* Get the next qualifying tuple */
623           fetch priv_curs into @id, @grantee, @action, @protecttype, @columns, @grantor, @predid
624       end
625   
626       /* Everything is consistent so change the group. */
627       update sysusers
628       set gid = @gid
629       from sysusers
630       where uid = @uid
631   
632       /*
633       ** Write the log record to replicate this invocation 
634       ** of the stored procedure.
635       */
636       if (logexec() != 1)
637       begin
638           /*
639           ** 17756, "The execution of the stored procedure '%1!' in
640           **         database '%2!' was aborted because there was an
641           **         error in writing the replication log record."
642           */
643           raiserror 17756, "sp_changegroup", @dbname
644   
645           rollback transaction rs_logexec
646           return (1)
647       end
648   
649       commit transaction rs_logexec
650   
651       /*
652       **  We need to invalidate the protection cache since objects have
653       **  changed ownership.  This command will invalidate the current
654       **  protection cache so when protections are checked the new and
655       **  correct protections will be used.
656       */
657       grant all to null
658       /*
659       ** 17370, "Group changed."
660       */
661       exec sp_getmessage 17370, @msg output
662       print @msg
663   
664   
665   
666       return (0)
667   


exec sp_procxmode 'sp_changegroup', 'AnyMode'
go

Grant Execute on sp_changegroup to public
go
DEFECTS
 MINU 4 Unique Index with nullable columns sybsystemprocs..sysprotects sybsystemprocs..sysprotects
 QPUI 4 Join or Sarg with Un-Rooted Partial Index Use SARG Candidate index: sysprotects.csysprotects unique clustered
(id, action, grantor, uid, protecttype, predid)
Intersection: {uid}
230
 QPUI 4 Join or Sarg with Un-Rooted Partial Index Use SARG Candidate index: sysprotects.csysprotects unique clustered
(id, action, grantor, uid, protecttype, predid)
Intersection: {uid, predid, action}
336
 QPUI 4 Join or Sarg with Un-Rooted Partial Index Use SARG Candidate index: sysprotects.csysprotects unique clustered
(id, action, grantor, uid, protecttype, predid)
Intersection: {uid, predid, action}
546
 QTYP 4 Comparison type mismatch Comparison type mismatch: tinyint vs int 291
 QTYP 4 Comparison type mismatch Comparison type mismatch: tinyint vs int 311
 QTYP 4 Comparison type mismatch Comparison type mismatch: tinyint vs int 378
 QTYP 4 Comparison type mismatch Comparison type mismatch: tinyint vs int 385
 QTYP 4 Comparison type mismatch Comparison type mismatch: tinyint vs int 422
 QTYP 4 Comparison type mismatch Comparison type mismatch: tinyint vs int 430
 QTYP 4 Comparison type mismatch Comparison type mismatch: tinyint vs int 439
 QTYP 4 Comparison type mismatch Comparison type mismatch: tinyint vs int 447
 QTYP 4 Comparison type mismatch Comparison type mismatch: tinyint vs int 466
 QTYP 4 Comparison type mismatch Comparison type mismatch: tinyint vs int 473
 QTYP 4 Comparison type mismatch Comparison type mismatch: tinyint vs int 497
 QTYP 4 Comparison type mismatch Comparison type mismatch: tinyint vs int 506
 MAW1 3 Warning message on %name% sybsystemprocs..sysprotects.id: Warning message on sysprotects 228
 MAW1 3 Warning message on %name% sybsystemprocs..sysprotects.id: Warning message on sysprotects 272
 MAW1 3 Warning message on %name% sybsystemprocs..sysprotects.id: Warning message on sysprotects 288
 MAW1 3 Warning message on %name% sybsystemprocs..sysprotects.id: Warning message on sysprotects 308
 MAW1 3 Warning message on %name% sybsystemprocs..sysobjects.id: Warning message on sysobjects 342
 MAW1 3 Warning message on %name% sybsystemprocs..sysprotects.id: Warning message on sysprotects 374
 MAW1 3 Warning message on %name% sybsystemprocs..sysprotects.id: Warning message on sysprotects 382
 MAW1 3 Warning message on %name% sybsystemprocs..syscolumns.id: Warning message on syscolumns 415
 MAW1 3 Warning message on %name% sybsystemprocs..sysprotects.id: Warning message on sysprotects 419
 MAW1 3 Warning message on %name% sybsystemprocs..sysprotects.id: Warning message on sysprotects 427
 MAW1 3 Warning message on %name% sybsystemprocs..sysprotects.id: Warning message on sysprotects 436
 MAW1 3 Warning message on %name% sybsystemprocs..sysprotects.id: Warning message on sysprotects 444
 MAW1 3 Warning message on %name% sybsystemprocs..sysprotects.id: Warning message on sysprotects 463
 MAW1 3 Warning message on %name% sybsystemprocs..sysprotects.id: Warning message on sysprotects 470
 MAW1 3 Warning message on %name% sybsystemprocs..sysprotects.id: Warning message on sysprotects 494
 MAW1 3 Warning message on %name% sybsystemprocs..sysprotects.id: Warning message on sysprotects 503
 MAW1 3 Warning message on %name% sybsystemprocs..sysobjects.id: Warning message on sysobjects 552
 MBLI 3 Integer Value of Binary Literal is Platform Dependant 406
 MBLI 3 Integer Value of Binary Literal is Platform Dependant 407
 MBLI 3 Integer Value of Binary Literal is Platform Dependant 461
 MBLI 3 Integer Value of Binary Literal is Platform Dependant 500
 MBLI 3 Integer Value of Binary Literal is Platform Dependant 535
 MBLI 3 Integer Value of Binary Literal is Platform Dependant 608
 MGTP 3 Grant to public master..syssrvroles  
 MGTP 3 Grant to public sybsystemprocs..sp_changegroup  
 MGTP 3 Grant to public sybsystemprocs..syscolumns  
 MGTP 3 Grant to public sybsystemprocs..sysobjects  
 MGTP 3 Grant to public sybsystemprocs..sysprotects  
 MGTP 3 Grant to public sybsystemprocs..sysusers  
 MNAC 3 Not using ANSI 'is null' 329
 MNAC 3 Not using ANSI 'is null' 491
 MNAC 3 Not using ANSI 'is null' 533
 MNAC 3 Not using ANSI 'is null' 537
 MNER 3 No Error Check should check @@error after delete 367
 MNER 3 No Error Check should check @@error after delete 397
 MNER 3 No Error Check should check return value of exec 455
 MNER 3 No Error Check should check return value of exec 484
 MNER 3 No Error Check should check return value of exec 515
 MNER 3 No Error Check should check return value of exec 529
 MNER 3 No Error Check should check return value of exec 531
 MNER 3 No Error Check should check @@error after delete 588
 MNER 3 No Error Check should check @@error after update 594
 MNER 3 No Error Check should check return value of exec 602
 MNER 3 No Error Check should check @@error after delete 611
 MNER 3 No Error Check should check @@error after update 616
 MNER 3 No Error Check should check @@error after update 627
 MNER 3 No Error Check should check return value of exec 661
 MUCO 3 Useless Code Useless Brackets 114
 MUCO 3 Useless Code Useless Brackets 115
 MUCO 3 Useless Code Useless Brackets 135
 MUCO 3 Useless Code Useless Brackets 137
 MUCO 3 Useless Code Useless Brackets 139
 MUCO 3 Useless Code Useless Brackets 144
 MUCO 3 Useless Code Useless Brackets 152
 MUCO 3 Useless Code Useless Brackets 164
 MUCO 3 Useless Code Useless Brackets 172
 MUCO 3 Useless Code Useless Brackets 174
 MUCO 3 Useless Code Useless Brackets 177
 MUCO 3 Useless Code Useless Brackets 197
 MUCO 3 Useless Code Useless Brackets 214
 MUCO 3 Useless Code Useless Brackets 242
 MUCO 3 Useless Code Useless Brackets 244
 MUCO 3 Useless Code Useless Brackets 249
 MUCO 3 Useless Code Useless Brackets 256
 MUCO 3 Useless Code Useless Brackets 264
 MUCO 3 Useless Code Useless Brackets 271
 MUCO 3 Useless Code Useless Brackets 281
 MUCO 3 Useless Code Useless Brackets 287
 MUCO 3 Useless Code Useless Brackets 307
 MUCO 3 Useless Code Useless Brackets 326
 MUCO 3 Useless Code Useless Brackets 329
 MUCO 3 Useless Code Useless Brackets 335
 MUCO 3 Useless Code Useless Brackets 353
 MUCO 3 Useless Code Useless Brackets 361
 MUCO 3 Useless Code Useless Brackets 370
 MUCO 3 Useless Code Useless Brackets 373
 MUCO 3 Useless Code Useless Brackets 418
 MUCO 3 Useless Code Useless Brackets 435
 MUCO 3 Useless Code Useless Brackets 462
 MUCO 3 Useless Code Useless Brackets 491
 MUCO 3 Useless Code Useless Brackets 493
 MUCO 3 Useless Code Useless Brackets 526
 MUCO 3 Useless Code Useless Brackets 533
 MUCO 3 Useless Code Useless Brackets 535
 MUCO 3 Useless Code Useless Brackets 537
 MUCO 3 Useless Code Useless Brackets 544
 MUCO 3 Useless Code Useless Brackets 564
 MUCO 3 Useless Code Useless Brackets 575
 MUCO 3 Useless Code Useless Brackets 599
 MUCO 3 Useless Code Useless Brackets 608
 MUCO 3 Useless Code Useless Brackets 636
 MUCO 3 Useless Code Useless Brackets 646
 MUCO 3 Useless Code Useless Brackets 666
 MUUF 3 Update or Delete with Useless From Clause 627
 QAFM 3 Var Assignment from potentially many rows 425
 QAFM 3 Var Assignment from potentially many rows 442
 QAFM 3 Var Assignment from potentially many rows 469
 QAFM 3 Var Assignment from potentially many rows 502
 QISO 3 Set isolation level 122
 QPRI 3 Join or Sarg with Rooted Partial Index Use SARG Candidate index: sysprotects.csysprotects unique clustered
(id, action, grantor, uid, protecttype, predid)
Intersection: {protecttype, uid, action, grantor, id}
272
 QPRI 3 Join or Sarg with Rooted Partial Index Use SARG Candidate index: sysprotects.csysprotects unique clustered
(id, action, grantor, uid, protecttype, predid)
Intersection: {protecttype, uid, action, grantor, id}
288
 QPRI 3 Join or Sarg with Rooted Partial Index Use SARG Candidate index: sysprotects.csysprotects unique clustered
(id, action, grantor, uid, protecttype, predid)
Intersection: {action, protecttype, id, uid, grantor}
374
 QPRI 3 Join or Sarg with Rooted Partial Index Use SARG Candidate index: sysprotects.csysprotects unique clustered
(id, action, grantor, uid, protecttype, predid)
Intersection: {action, protecttype, id, uid, grantor}
382
 QPRI 3 Join or Sarg with Rooted Partial Index Use SARG Candidate index: syscolumns.csyscolumns unique clustered
(id, number, colid)
Intersection: {id}
415
 QPRI 3 Join or Sarg with Rooted Partial Index Use SARG Candidate index: sysprotects.csysprotects unique clustered
(id, action, grantor, uid, protecttype, predid)
Intersection: {protecttype, uid, action, grantor, id}
419
 QPRI 3 Join or Sarg with Rooted Partial Index Use SARG Candidate index: sysprotects.csysprotects unique clustered
(id, action, grantor, uid, protecttype, predid)
Intersection: {protecttype, uid, action, grantor, id}
427
 QPRI 3 Join or Sarg with Rooted Partial Index Use SARG Candidate index: sysprotects.csysprotects unique clustered
(id, action, grantor, uid, protecttype, predid)
Intersection: {protecttype, uid, action, grantor, id}
436
 QPRI 3 Join or Sarg with Rooted Partial Index Use SARG Candidate index: sysprotects.csysprotects unique clustered
(id, action, grantor, uid, protecttype, predid)
Intersection: {protecttype, uid, action, grantor, id}
444
 QPRI 3 Join or Sarg with Rooted Partial Index Use SARG Candidate index: sysprotects.csysprotects unique clustered
(id, action, grantor, uid, protecttype, predid)
Intersection: {protecttype, uid, action, grantor, id}
463
 QPRI 3 Join or Sarg with Rooted Partial Index Use SARG Candidate index: sysprotects.csysprotects unique clustered
(id, action, grantor, uid, protecttype, predid)
Intersection: {protecttype, uid, action, grantor, id}
470
 QPRI 3 Join or Sarg with Rooted Partial Index Use SARG Candidate index: sysprotects.csysprotects unique clustered
(id, action, grantor, uid, protecttype, predid)
Intersection: {protecttype, uid, action, grantor, id}
494
 QPRI 3 Join or Sarg with Rooted Partial Index Use SARG Candidate index: sysprotects.csysprotects unique clustered
(id, action, grantor, uid, protecttype, predid)
Intersection: {protecttype, uid, action, grantor, id}
503
 VNRD 3 Variable is not read @dummy 182
 CUPD 2 Updatable Cursor Marker (has for update clause) 228
 MSUB 2 Subquery Marker 190
 MSUB 2 Subquery Marker 271
 MSUB 2 Subquery Marker 287
 MSUB 2 Subquery Marker 307
 MSUB 2 Subquery Marker 335
 MSUB 2 Subquery Marker 373
 MSUB 2 Subquery Marker 381
 MSUB 2 Subquery Marker 418
 MSUB 2 Subquery Marker 435
 MSUB 2 Subquery Marker 462
 MSUB 2 Subquery Marker 493
 MSUB 2 Subquery Marker 544
 MTR1 2 Metrics: Comments Ratio Comments: 46% 66
 MTR2 2 Metrics: Cyclomatic Complexity Cyclo: 102 = 109dec - 9exi + 2 66
 MTR3 2 Metrics: Query Complexity Complexity: 306 66

DEPENDENCIES
PROCS AND TABLES USED
reads table master..syssrvroles (1)  
read_writes table sybsystemprocs..sysusers  
reads table sybsystemprocs..syscolumns  
calls proc sybsystemprocs..sp_getmessage  
   calls proc sybsystemprocs..sp_validlang  
      reads table master..syslanguages (1)  
   reads table master..sysmessages (1)  
   reads table master..syslanguages (1)  
   reads table sybsystemprocs..sysusermessages  
calls proc sybsystemprocs..syb_aux_privexor  
   calls proc sybsystemprocs..syb_aux_expandbitmap  
calls proc sybsystemprocs..syb_aux_privunion  
read_writes table sybsystemprocs..sysprotects  
calls proc sybsystemprocs..sp_ha_check_certified  
   reads table tempdb..sysobjects (1)  
reads table sybsystemprocs..sysobjects  
calls proc sybsystemprocs..syb_aux_privnots  
   calls proc sybsystemprocs..syb_aux_expandbitmap  
calls proc sybsystemprocs..sp_aux_checkroleperm  
   reads table master..syscurconfigs (1)  
   reads table master..sysconfigures (1)  
calls proc sybsystemprocs..syb_aux_privsand  
   calls proc sybsystemprocs..syb_aux_expandbitmap