Allow arbitrary user to read MonetDB's sys.queue - monetdb

I created a user foouser and a schema fooschema with some tables in it. Foouser executes long-running queries to its tables in fooschema.
Now I'd like to check on the status of the queries. However, foouser does not have sufficient permissions to access sys.queue table/view:
sql>SELECT * FROM sys.queue;
SELECT: access denied for foouser to table 'sys.queue'
sql>SELECT * FROM sys.queue();
SELECT: no such operator 'queue'
The monetdb user has the necessary permissions, but does not see foosuer's queries but only their own:
sql>SELECT * FROM sys.queue;
+---------+---------+----------------------------+----------------------------+----------+---------+-----------+--------------------------+
| qtag | user | started | estimate | progress | status | tag | query |
+=========+=========+============================+============================+==========+=========+===========+==========================+
| 2593257 | monetdb | 2018-04-26 15:06:01.000000 | null | null | running | 2593257#0 | select * from sys.queue; |
+---------+---------+----------------------------+----------------------------+----------+---------+-----------+--------------------------+
So the question is: How can foouser view the status of its own queries? Can I grant foouser the access to sys.queue()? If so, how?

I found a solution which allows a "normal" user to read its own sys.queue. However, this approach grants (for my liking) way to many permissions to the user and is therefore not optimal.
The approach is to grant the role sysadmin to foouser. This has to be done while being logged in as monetdb user (i.e. running mclient -u monetdb):
sql> grant sysadmin to foouser;
operation successful
Afterwards, if you log in as foouser (i.e. mclient -u foouser), you have to select the sysadmin role and can now see you own running queries by looking into sys.queue:
sql>set role sysadmin;
operation successful
sql>select * from sys.queue;
+---------+---------+-------------+-------------+------+---------+-----------+--------------+
| qtag | user | started | estimate | prog | status | tag | query |
: : : : : ress : : : :
+=========+=========+=============+=============+======+=========+===========+==============+
| 1627134 | foouser | 2018-11-09 | null | null | running | 1627134#0 | insert into |
: : : 17:48:57.00 : : : : : REDACTED :
: : : 0000 : : : : : REDACTED :
| 1627135 | foouser | 2018-11-09 | null | null | running | 1627135#0 | select * fro |
: : : 17:48:57.00 : : : : : m sys.queue; :
: : : 0000 : : : : : :
+---------+---------+-------------+-------------+------+---------+-----------+--------------+
2 tuples !1 field truncated!
However, now the (intentionally) restricted user foouser has full administrative permissions what makes the use of a restricted user somewhat pointless.

Related

How to properly apply index_desc hint for a remote database object in oracle database?

We were facing some issues with execution plans while accessing remote database objects with dblink. Here is the query itself run on the remote database:
select --+ index_desc (d DAY_OPERATIONAL_PK)
d.oper_day
from day_operational d
where rownum = 1
The plan for this query is the following :
Plan Hash Value : 2761870770
---------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost | Time |
---------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 8 | 2 | 00:00:01 |
| * 1 | COUNT STOPKEY | | | | | |
| 2 | INDEX FULL SCAN DESCENDING | DAY_OPERATIONAL_PK | 1 | 8 | 2 | 00:00:01 |
---------------------------------------------------------------------------------------------
This one works correct that is it returns the last operational day. In this case 14.09.2021. However if execute this exact same query from other database connecting to this one via dblink, wrong results are returned . In this case the first row of the table is returned - 05.09.2009.
Here is the query:
select --+ index_desc (d DAY_OPERATIONAL_PK)
d.oper_day
from day_operational#iabs d
where rownum = 1
The plan generated for this query in local database is the following:
Plan Hash Value :
---------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost | Time |
---------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT REMOTE | | 1 | 8 | 2 | 00:00:01 |
| * 1 | COUNT STOPKEY | | | | | |
| 2 | INDEX FAST FULL SCAN | XPKDAY_OPERATIONAL | 1 | 8 | 2 | 00:00:01 |
---------------------------------------------------------------------------------------
As it can be seen, the plan generated when connected via dblink uses full table scan and ignores index_desc hint. How could we enforce oracle to use this index? Tried adding driving_site hint but it didn't help
Sorry for confusions. It occured that index names in local database and remote database are not same and therefore hint was ignoring since there was no index with that name in the remote db. With right index names, both the plan and result were correct

Postgres "REASSIGN OWNED" fails with "permission denied for schema public"

In our application we have components that can modify DB structure. At times it is desirable to prohibit this and to do this we reduce the level of privilege of the Postgres group role that owns all of our DB structures (tables, sequences, views, etc.). Additionally, because owners can still do whatever they want to existing structure they own, we reassign ownership of all the structures to a temporary user role who cannot login. The latter step is accomplished by issuing a REASSIGN OWNED BY XXX TO YYY; command. Recently, when testing, we noticed that for one of our databases this command was failing with a "permission denied for schema public" error message. This is odd since all of our DBs define equivalent group roles for reading, writing, and administrative/DDL operations and this operation continues to work fine for other DBs on the same Postgres host. Furthermore I can see no inconsistencies in schema privileges or object ownership. Is there a way to get more information from Postgres about what it is objecting to?
I have run the \dn+ command on both the affected / failing DB and on one behaving normally and see no difference in the privilege of the "superuser" I'm using to issue the commands, not to mention create and administer the roles in question. Most of my searches on the subject yield results where the REASSIGN OWNED BY command is used to help remedy permission denied errors and I've yet to find any information on what to look for if that command itself is throwing such an error. Any help would be greatly appreciated.
The user I'm using is the highest privileged user AWS Aurora provides us. The output from \du for the role is basically unusable since that role is a member of ALL groups for all the DBs on our system resulting in a membership list that is hundreds of elements long and almost unreadable in the terminal let alone here. I'll try and provide more selective information using the pg_roles and pg_auth_members views below.
d0000000033_0000000031=> select current_user;
current_user
--------------
datamart
(1 row)
d0000000033_0000000031=> select * from pg_roles where rolname = 'datamart';
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolconnlimit | rolpassword | rolvaliduntil | rolbypassrls | rolconfig | oid
----------+----------+------------+---------------+-------------+-------------+----------------+--------------+-------------+---------------+--------------+-----------+-------
datamart | f | t | t | t | t | f | -1 | ******** | infinity | f | | 16393
(1 row)
The schema privileges for the DB are as follows:
d0000000033_0000000031=> \dn+ public
List of schemas
Name | Owner | Access privileges | Description
--------+----------+---------------------------------------------+------------------------
public | rdsadmin | datamart=UC/rdsadmin +| standard public schema
| | d0000000033_0000000031_g_admins=UC/rdsadmin+|
| | d0000000033_0000000031_g_writers=U/rdsadmin+|
| | d0000000033_0000000031_g_readers=U/rdsadmin |
(1 row)
The memberships for the associated group roles are:
d0000000033_0000000031=> select r1.rolname as role, r2.rolname as member, r3.rolname as grantor, am.admin_option
from pg_roles r1
inner join pg_auth_members am on r1.oid = am.roleid
inner join pg_roles r2 on r2.oid = am.member
inner join pg_roles r3 on r3.oid = am.grantor
where r1.rolname like 'd0000000033_0000000031_g%';
role | member | grantor | admin_option
----------------------------------+---------------------------------+----------+--------------
d0000000033_0000000031_g_admins | datamart | datamart | t
d0000000033_0000000031_g_admins | clari_global_admins | datamart | f
d0000000033_0000000031_g_admins | d0000000033_0000000031_u_admin | datamart | f
d0000000033_0000000031_g_readers | datamart | datamart | t
d0000000033_0000000031_g_readers | clari_global_readers | datamart | f
d0000000033_0000000031_g_readers | d0000000033_0000000031_u_reader | datamart | f
d0000000033_0000000031_g_writers | datamart | datamart | t
d0000000033_0000000031_g_writers | clari_global_writers | datamart | f
d0000000033_0000000031_g_writers | d0000000033_0000000031_u_writer | datamart | f
(9 rows)
The details for the associated roles are:
d0000000033_0000000031=> select * from pg_roles where rolname like 'd0000000033_0000000031%' or rolname like 'clari_global%';
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolconnlimit | rolpassword | rolvaliduntil | rolbypassrls | rolconfig | oid
----------------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+-------------+---------------+--------------+-----------+-------
clari_global_admins | f | f | f | f | f | f | -1 | ******** | | f | | 25971
clari_global_readers | f | t | f | f | f | f | -1 | ******** | | f | | 25973
clari_global_writers | f | f | f | f | f | f | -1 | ******** | | f | | 25972
d0000000033_0000000031_g_admins | f | f | f | f | f | f | -1 | ******** | | f | | 96724
d0000000033_0000000031_g_readers | f | f | f | f | f | f | -1 | ******** | | f | | 96730
d0000000033_0000000031_g_writers | f | f | f | f | f | f | -1 | ******** | | f | | 96725
d0000000033_0000000031_u_admin | f | t | f | f | t | f | -1 | ******** | | f | | 97411
d0000000033_0000000031_u_reader | f | t | f | f | t | f | -1 | ******** | | f | | 97078
d0000000033_0000000031_u_writer | f | t | f | f | t | f | -1 | ******** | | f | | 96731
(9 rows)
I just realized I missed an important piece of information RE the user I'm reassigning ownership to:
d0000000033_0000000031=> \du d0000000033_0000000031_u_restricted;
List of roles
Role name | Attributes | Member of
-------------------------------------+--------------+-----------
d0000000033_0000000031_u_restricted | Cannot login | {}
The flow of commands leading up to the failure of the REASSIGN OWNED BY is this:
REVOKE ALL ON SCHEMA public FROM d0000000033_0000000031_g_admins;
GRANT USAGE ON SCHEMA public TO d0000000033_0000000031_g_admins;
CREATE ROLE d0000000033_0000000031_u_restricted WITH ADMIN datamart;
GRANT ALL ON SCHEMA public TO d0000000033_0000000031_u_restricted;
REASSIGN OWNED BY d0000000033_0000000031_g_admins TO d0000000033_0000000031_u_restricted;
Executing these for the affected DB I get:
d0000000033_0000000031=> REVOKE ALL ON SCHEMA public FROM d0000000033_0000000031_g_admins;
WARNING: no privileges could be revoked for "public"
REVOKE
d0000000033_0000000031=> GRANT USAGE ON SCHEMA public TO d0000000033_0000000031_g_admins;
WARNING: no privileges were granted for "public"
GRANT
d0000000033_0000000031=> CREATE ROLE d0000000033_0000000031_u_restricted WITH ADMIN datamart;
CREATE ROLE
d0000000033_0000000031=> GRANT ALL ON SCHEMA public TO d0000000033_0000000031_u_restricted;
WARNING: no privileges were granted for "public"
GRANT
d0000000033_0000000031=> REASSIGN OWNED BY d0000000033_0000000031_g_admins TO d0000000033_0000000031_u_restricted;
ERROR: permission denied for schema public
Executing the same for my unaffected DB I get:
d0000000033_0000000029=> REVOKE ALL ON SCHEMA public FROM d0000000033_0000000029_g_admins;
WARNING: no privileges could be revoked for "public"
REVOKE
d0000000033_0000000029=> GRANT USAGE ON SCHEMA public TO d0000000033_0000000029_g_admins;
WARNING: no privileges were granted for "public"
GRANT
d0000000033_0000000029=> CREATE ROLE d0000000033_0000000029_u_restricted WITH ADMIN datamart;
CREATE ROLE
d0000000033_0000000029=> GRANT ALL ON SCHEMA public TO d0000000033_0000000029_u_restricted;
WARNING: no privileges were granted for "public"
GRANT
d0000000033_0000000029=> REASSIGN OWNED BY d0000000033_0000000029_g_admins TO d0000000033_0000000029_u_restricted;
REASSIGN OWNED

Laravel 5 Joining Tables and Calculating Fields

I have 2 tables which have been joined.
Table : affiliate
Fields : company,affid
+---------------------------+
|company|affid |
|Test1 | t1 ||Test1 | t2 |
Table : applicant
Fields : affid,commission
+---------------------------+
|affid |commission |
|t1 | 25 ||t2 | 30 |
Each company has for example 2 affid's.
So company name : Test1
Has affid : t1,t2
What i am trying to do is pull a table that shows the company name and its total commission.
+---------------------------+
|company|commission|
|Test1 | 55 |
This is what i have , what changes do i need to make ?
$data = DB::table('applicant')
->join('affiliate','applicant.affid','=','affiliate.affid')
->select(DB::raw('company,SUM(commission) as commission,'))
->groupBy('company')
->get();

Materialized View having UNKNOWN staleness - Oracle 11G

I am working on Oracle 11G.
One of my Materialized view has become UNKNOWN (MY_MAT_VW1). You can check the output of the ALL_MVIEWS below.
OWNER | MVIEW_NAME | CONTAINER_NAME | QUERY | QUERY_LEN | UPDATABLE | UPDATE_LOG | MASTER_ROLLBACK_SEG | MASTER_LINK | REWRITE_ENABLED | REWRITE_CAPABILITY | REFRESH_MODE | REFRESH_METHOD | BUILD_MODE | FAST_REFRESHABLE | LAST_REFRESH_TYPE | LAST_REFRESH_DATE | STALENESS | AFTER_FAST_REFRESH | UNKNOWN_PREBUILT | UNKNOWN_PLSQL_FUNC | UNKNOWN_EXTERNAL_TABLE | UNKNOWN_CONSIDER_FRESH | UNKNOWN_IMPORT | UNKNOWN_TRUSTED_FD | COMPILE_STATE | USE_NO_INDEX | STALE_SINCE | NUM_PCT_TABLES | NUM_FRESH_PCT_REGIONS | NUM_STALE_PCT_REGIONS
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
MY_DB | MY_MAT_VW1 | MY_MAT_VW1 | select.. | 6728 | N | | | | N | GENERAL | DEMAND | COMPLETE | IMMEDIATE | NO | COMPLETE | 14-Nov-16 | UNKNOWN | NA | N | Y | N | N | N | N | VALID | N | 0 | | |
MY_DB | MY_MAT_VW2 | MY_MAT_VW2 | select.. | 7074 | N | | | | N | TEXTMATCH | DEMAND | COMPLETE | IMMEDIATE | NO | COMPLETE | 13-Nov-16 | FRESH | NA | N | N | N | N | N | N | FRESH | N | 0 | 0 | |
The queries for the materialized view contain complex joins between multiple tables, inline views and unions.
As per my understanding (UNKNOWN_PLSQL_FUNC column) I guess there is a PLSQL Function which is causing the staleness to become UNKNOWN. However I am not sure which one.
I tried re-compiling and refreshing it but no luck.
Can anyone provide me some information on how to detect the root cause and make sure it does not become UNKNOWN again.
Also is there any implication of it on the data stored within it?
Below is just a sample I've created to replicate the scenario.
SELECT * FROM ENTITY_T;
ID | ENTITY_TYPE | FIRST_NAME | LAST_NAME | LEGAL_NAME
--------------------------------------------------
1 | INDIVIDUAL | JOHN | LESSEN |
2 | INDIVIDUAL | ROSAN | MEL |
3 | CORP | SIGMA | | SIGMA CORPORATION
--Function to get name base upon type
CREATE OR REPLACE FUNCTION GET_NAME (P_ID IN NUMBER)
RETURN VARCHAR2
DETERMINISTIC
AS
LV_NAME VARCHAR2(200);
BEGIN
SELECT CASE ENTITY_TYPE WHEN 'INDIVIDUAL' THEN FIRST_NAME ||' '|| LAST_NAME
WHEN 'CORP' THEN LEGAL_NAME
ELSE 'NONE'
END INTO LV_NAME
FROM ENTITY_T
WHERE ID=P_ID;
RETURN LV_NAME;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN 'NO ID FOUND';
WHEN OTHERS THEN
RETURN 'OTHER ERROR';
END;
--Materialized view creation
CREATE MATERIALIZED VIEW TEST_MV
AS
SELECT ID,ENTITY_TYPE,GET_NAME(ID) NAME
FROM ENTITY_T;
SELECT MVIEW_NAME,STALENESS,AFTER_FAST_REFRESH,UNKNOWN_PLSQL_FUNC,COMPILE_STATE,STALE_SINCE
FROM ALL_MVIEWS WHERE MVIEW_NAME='TEST_MV';
MVIEW_NAME | STALENESS | AFTER_FAST_REFRESH | UNKNOWN_PLSQL_FUNC | COMPILE_STATE | STALE_SINCE
----------------------------------------------------------------------------------------------
TEST_MV | UNKNOWN | NA | Y | VALID |
The Oracle Issue/Doc ID 757537.1 mentioned by JSapkota states clearly, that this is not a bug, but correct/expected behaviour:
STALENESS of the mview, refering to PL/SQL function is set to UNKOWN
as one cannot determine PL/SQL function changes. Current behaviour is
correct as per the design & code.
I guess using DETERMINISTIC functions instead of the default scope could prevent it.
As per the My Oracle Support this could be a bug(7582462).
As there is no solution to this bug, you have to deal with fact that staleness will show unknown, or not use functions on Materialized View definition.
Reference:DBA_MVIEWS Shows STALENESS Value of UNKNOWN After Refresh (Doc ID 757537.1)

How to repeat query in Oracle Forms upon dynamically changing ORDER_BY clause?

I have an Oracle Forms 6i form with a data block that consists of several columns.
------------------------------------------------------------------------------
| FIRST_NAME | LAST_NAME | DEPARTMENT | BIRTH_DATE | JOIN_DATE | RETIRE_DATE |
------------------------------------------------------------------------------
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
------------------------------------------------------------------------------
The user can press F7 (to Enter in Query Mode, for example, he/she types JOH% in the first_name and H% in the DEPARTMENT field) , then F8 to execute the query and see the results. In this example, a list of all employees with their last name starting with JOH and working in any department starting with H will be listed. Here is a sample output of that query
------------------------------------------------------------------------------
| FIRST_NAME | LAST_NAME | DEPARTMENT | BIRTH_DATE | JOIN_DATE | RETIRE_DATE |
------------------------------------------------------------------------------
| MIKE | JOHN | HUMAN RES. | 05-MAY-82 | 02-FEB-95 | |
| BEN | JOHNATHAN | HOUSING | 23-APR-76 | 16-AUG-98 | |
| SMITH | JOHN | HOUSING | 11-DEC-78 | 30-JUL-91 | |
| | | | | | |
------------------------------------------------------------------------------
I then added a small button on top of each column to allow the user to sort the data by the desired column, by executing WHEN-BUTTON-PRESSED trigger:
set_block_property('dept', order_by, 'first_name desc');
The good news is that the ORDER_BY does change. The bad news is that the user never notice the change because he/she will need to do another query and execute to see the output ordered by the column they selected. In other words, user will only notice the change in the next query he/she will execute.
I tried to automatically execute the query upon changing the ORDER_BY clause like this:
set_block_property('dept', order_by, 'first_name desc');
go_block('EMPLOYEE');
do_key('EXECUTE_QUERY');
/* EXECUTE_QUERY -- same thing */
but what happens is that all data from the table is selected, ignoring the criteria that the user has initially set during the query mode entry.
I also searched for a solution to this problem and most of them deal with SYSTEM.LAST_QUERY and default_where. The problem is, last_query can refer to a different block from a different form, that is not valid on the currently displayed data bloc.
How can do the following in just one button press:
1- Change the ORDER_BY clause of the currently active datablock
and: 2- Execute the last query that the user has executed, using the same criteria that was set?
Any help will be highly appreciated.
You can get the last query of the block with get_block_property built-in function:
GET_BLOCK_PROPERTY('EMPLOYEE', LAST_QUERY);
Another option is to provide separate search field(s) on the form, instead of using the QBE functionality.

Resources