New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for GRANT and REVOKE statements #6812

Closed
lukaseder opened this Issue Nov 9, 2017 · 13 comments

Comments

Projects
None yet
2 participants
@lukaseder
Member

lukaseder commented Nov 9, 2017

Many databases have some way of granting (and revoking) object rights to users / roles. It would be useful to have these statements as well in our repertoire.

We'll probably need a new top level type org.jooq.User, and perhaps org.jooq.Role. It’s currently unclear how these two types should relate to each other. Once we have the types, we’ll need:

  • Ways to construct them using DSL.user() and DSL.role()
  • Perhaps, code generation support (separate issue: see #6902)
  • The actual API and its implementation
  • Parser support (#6485) and documentation in grammar

Additional improvements in separate issues:

  • Granting to and revoking from PUBLIC: #6911
  • GRANT .. [ WITH GRANT OPTION ]: #6913
  • REVOKE [ GRANT OPTION FOR ] ..: #6931

We should collect all the related features / syntaxes from different vendors – and especially the little quirks that each has to them. This subset of vendors should be a good starter:

  • DB2 LUW (We'll do this later)
  • Derby
  • H2
  • HSQLDB
  • MySQL / MariaDB
  • Oracle
  • PostgreSQL
  • SQL Server
  • SQLite (does not support grants)
@timur-sh

This comment has been minimized.

Show comment
Hide comment
@timur-sh

timur-sh Nov 21, 2017

Contributor

There is a common denominator to use GRANT statement for above databases. Except is SQLite, it doesn't support any accession control

It is separated on two possibles:
First one is GRANT PRIVILEGES, this has a common clause:
GRANT <privilege> ON <objectName> TO <grantees> [<PRIVILEGE OPTIONS>]
<privilege> = ACTION [, ...] - this is an action specific to particular database. You can find whole list below
<objectName> - OBJECT this can be table, schema, view, etc. You can find whole list below
<PRIVILEGE OPTIONS> - PRIVILEGE_OPTIONS options that may be depend on certain database. You can find them below

The second one is GRANT ROLES
GRANT roleName TO <grantees> [<ROLE_OPTIONS>]
<ROLE_OPTIONS> - ROLE_OPTIONS options that may be depend on certain database. You can find them below
<grantees> = user | role | PUBLIC

<grantees> may be change by specific database

DATABASES

DB2 LUW https://www.ibm.com/support/knowledgecenter/SSEPGG_10.1.0/com.ibm.db2.luw.sql.ref.doc/doc/r0000966.html

Derby https://db.apache.org/derby/docs/10.5/ref/rrefsqljgrant.html

  1. ACTIONS: { ALL PRIVILEGES | DELETE | INSERT | REFERENCES [column list] | SELECT [column list] | TRIGGER | UPDATE [column list] }
  2. OBJECT: [TABLE] { table-Name | view-Name }

There are some additional GRANT statements:
GRANT EXECUTE ON { FUNCTION | PROCEDURE } <routine-designator> TO <grantees>
GRANT roleName [, ... ] TO <grantees>

H2 http://www.h2database.com/html/grammar.html#grant_right

  1. ACTIONS: { SELECT | INSERT | UPDATE | DELETE | ALL }
  2. OBJECT: SCHEMA schemaName | tableName

HSQLDB http://hsqldb.org/doc/guide/accesscontrol-chapt.html

  1. ACTIONS: ALL PRIVILEGES | SELECT | SELECT <left paren> <privilege column list> <right paren> | DELETE | INSERT [ <left paren> <privilege column list> <right paren> ] | UPDATE [ <left paren> <privilege column list> <right paren> ] | REFERENCES [ <left paren> <privilege column list> <right paren> ] | USAGE | TRIGGER | EXECUTE
  2. OBJECT: [ TABLE ]<table name> | DOMAIN <domain name> | COLLATION <collation name> | CHARACTER SET <character set name> | TRANSLATION <transliteration name> | TYPE <user-defined type name> | SEQUENCE <sequence generator name> | <specific routine designator> | ROUTINE <routine name> | FUNCTION <function name> | PROCEDURE <procedure name>
  3. PRIVILEGE_OPTIONS: [ WITH GRANT OPTION ] [ GRANTED BY <grantor> ]
  4. ROLE_OPTIONS: [ WITH ADMIN OPTION ] [ GRANTED BY ]

There is additional GRANT statement:
GRANT roleName [, ... ] TO <grantees> [ ,... ] [<ROLE_OPTIONS>]
<grantor> = CURRENT_USER | CURRENT_ROLE

MariaDB https://mariadb.com/kb/en/library/grant/

MySQL https://dev.mysql.com/doc/refman/8.0/en/grant.html

  1. ACTIONS: { CREATE TEMPORARY | TABLES | CREATE USER | CREATE VIEW | DELETE | DROP | EVENT | EXECUTE | FILE | GRANT OPTION | INDEX | INDERT | LOCK TABLES| PROCESS| PROXY | REFERENCES | RELOAD | REPLICATION CLIENT | REPLICATION SLAVE | SELECT | SHOW DATABASES | SHOW VIEW | SHUTDOWN | SUPER | TRIGGER | UPDATE | USAGE }
  2. OBJECT: [{ TABLE | FUNCTION | PROCEDURE }] { * | *.* | db_name.* | db_name.tbl_name | tbl_name | db_name.routine_name }
  3. ROLE_OPTIONS: [REQUIRE {NONE | tls_option [[AND] tls_option] ...}] [WITH {GRANT OPTION | resource_option} ...]
    <grantees> = { roleName | userName}[auth_option] ...

auth_option: { IDENTIFIED BY 'auth_string' | IDENTIFIED WITH auth_plugin | IDENTIFIED WITH auth_plugin BY 'auth_string' | IDENTIFIED WITH auth_plugin AS 'hash_string' | IDENTIFIED BY PASSWORD 'hash_string' }

tls_option: { SSL | X509 | CIPHER 'cipher' | ISSUER 'issuer' | SUBJECT 'subject' }

resource_option: { | MAX_QUERIES_PER_HOUR count | MAX_UPDATES_PER_HOUR count | MAX_CONNECTIONS_PER_HOUR count | MAX_USER_CONNECTIONS count }

PostgreSQL https://www.postgresql.org/docs/10/static/sql-grant.html
PostgreSQL supports a lot of variations of the GRANT statement. Let's take as a basis the above clause. I separate this on several groups:
Group 1:

  1. ACTIONS: { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER } [, ...] | ALL [ PRIVILEGES ] }
  2. OBJECT: { [ TABLE ] table_name [, ...] | ALL TABLES IN SCHEMA schema_name [, ...] }

Group 2:

  1. ACTIONS: { { SELECT | INSERT | UPDATE | REFERENCES } ( column_name [, ...] ) [, ...] | ALL [ PRIVILEGES ] ( column_name [, ...] ) }
  2. OBJECT: [ TABLE ] table_name [, ...]

Group 3:

  1. ACTIONS: { { USAGE | SELECT | UPDATE } [, ...] | ALL [ PRIVILEGES ] }
  2. OBJECT: { SEQUENCE sequence_name [, ...] | ALL SEQUENCES IN SCHEMA schema_name [, ...] }

Group 4:

  1. ACTIONS: { { CREATE | CONNECT | TEMPORARY | TEMP } [, ...] | ALL [ PRIVILEGES ] }
  2. OBJECT: DATABASE database_name [, ...]

Group 5:

  1. ACTIONS: { USAGE | ALL [ PRIVILEGES ] }
  2. OBJECT: {DOMAIN domain_name [, ...] | FOREIGN DATA WRAPPER fdw_name [, ...] | FOREIGN DATA WRAPPER fdw_name [, ...] | FOREIGN SERVER server_name [, ...] | LANGUAGE lang_name [, ...] | TYPE type_name [, ...] }

Group 6:

  1. ACTIONS: { EXECUTE | ALL [ PRIVILEGES ] }
  2. OBJECT: { FUNCTION function_name [ ( [ [ argmode ] [ arg_name ] arg_type [, ...] ] ) ] [, ...] | ALL FUNCTIONS IN SCHEMA schema_name [, ...] }

Group 7:

  1. ACTIONS: { { SELECT | UPDATE } [, ...] | ALL [ PRIVILEGES ] }
  2. OBJECT: LARGE OBJECT loid [, ...]

Group 8:

  1. ACTIONS: { { CREATE | USAGE } [, ...] | ALL [ PRIVILEGES ] }
  2. OBJECT: SCHEMA schema_name [, ...]

Group 9:

  1. ACTIONS: { CREATE | ALL [ PRIVILEGES ] }
  2. OBJECT: TABLESPACE tablespace_name [, ...]

<grantees> = { [ GROUP ] role_name | PUBLIC | CURRENT_USER | SESSION_USER }
ROLE_OPTIONS: [ WITH GRANT OPTION ]

Oracle https://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_9013.htm
SQL Server

Contributor

timur-sh commented Nov 21, 2017

There is a common denominator to use GRANT statement for above databases. Except is SQLite, it doesn't support any accession control

It is separated on two possibles:
First one is GRANT PRIVILEGES, this has a common clause:
GRANT <privilege> ON <objectName> TO <grantees> [<PRIVILEGE OPTIONS>]
<privilege> = ACTION [, ...] - this is an action specific to particular database. You can find whole list below
<objectName> - OBJECT this can be table, schema, view, etc. You can find whole list below
<PRIVILEGE OPTIONS> - PRIVILEGE_OPTIONS options that may be depend on certain database. You can find them below

The second one is GRANT ROLES
GRANT roleName TO <grantees> [<ROLE_OPTIONS>]
<ROLE_OPTIONS> - ROLE_OPTIONS options that may be depend on certain database. You can find them below
<grantees> = user | role | PUBLIC

<grantees> may be change by specific database

DATABASES

DB2 LUW https://www.ibm.com/support/knowledgecenter/SSEPGG_10.1.0/com.ibm.db2.luw.sql.ref.doc/doc/r0000966.html

Derby https://db.apache.org/derby/docs/10.5/ref/rrefsqljgrant.html

  1. ACTIONS: { ALL PRIVILEGES | DELETE | INSERT | REFERENCES [column list] | SELECT [column list] | TRIGGER | UPDATE [column list] }
  2. OBJECT: [TABLE] { table-Name | view-Name }

There are some additional GRANT statements:
GRANT EXECUTE ON { FUNCTION | PROCEDURE } <routine-designator> TO <grantees>
GRANT roleName [, ... ] TO <grantees>

H2 http://www.h2database.com/html/grammar.html#grant_right

  1. ACTIONS: { SELECT | INSERT | UPDATE | DELETE | ALL }
  2. OBJECT: SCHEMA schemaName | tableName

HSQLDB http://hsqldb.org/doc/guide/accesscontrol-chapt.html

  1. ACTIONS: ALL PRIVILEGES | SELECT | SELECT <left paren> <privilege column list> <right paren> | DELETE | INSERT [ <left paren> <privilege column list> <right paren> ] | UPDATE [ <left paren> <privilege column list> <right paren> ] | REFERENCES [ <left paren> <privilege column list> <right paren> ] | USAGE | TRIGGER | EXECUTE
  2. OBJECT: [ TABLE ]<table name> | DOMAIN <domain name> | COLLATION <collation name> | CHARACTER SET <character set name> | TRANSLATION <transliteration name> | TYPE <user-defined type name> | SEQUENCE <sequence generator name> | <specific routine designator> | ROUTINE <routine name> | FUNCTION <function name> | PROCEDURE <procedure name>
  3. PRIVILEGE_OPTIONS: [ WITH GRANT OPTION ] [ GRANTED BY <grantor> ]
  4. ROLE_OPTIONS: [ WITH ADMIN OPTION ] [ GRANTED BY ]

There is additional GRANT statement:
GRANT roleName [, ... ] TO <grantees> [ ,... ] [<ROLE_OPTIONS>]
<grantor> = CURRENT_USER | CURRENT_ROLE

MariaDB https://mariadb.com/kb/en/library/grant/

MySQL https://dev.mysql.com/doc/refman/8.0/en/grant.html

  1. ACTIONS: { CREATE TEMPORARY | TABLES | CREATE USER | CREATE VIEW | DELETE | DROP | EVENT | EXECUTE | FILE | GRANT OPTION | INDEX | INDERT | LOCK TABLES| PROCESS| PROXY | REFERENCES | RELOAD | REPLICATION CLIENT | REPLICATION SLAVE | SELECT | SHOW DATABASES | SHOW VIEW | SHUTDOWN | SUPER | TRIGGER | UPDATE | USAGE }
  2. OBJECT: [{ TABLE | FUNCTION | PROCEDURE }] { * | *.* | db_name.* | db_name.tbl_name | tbl_name | db_name.routine_name }
  3. ROLE_OPTIONS: [REQUIRE {NONE | tls_option [[AND] tls_option] ...}] [WITH {GRANT OPTION | resource_option} ...]
    <grantees> = { roleName | userName}[auth_option] ...

auth_option: { IDENTIFIED BY 'auth_string' | IDENTIFIED WITH auth_plugin | IDENTIFIED WITH auth_plugin BY 'auth_string' | IDENTIFIED WITH auth_plugin AS 'hash_string' | IDENTIFIED BY PASSWORD 'hash_string' }

tls_option: { SSL | X509 | CIPHER 'cipher' | ISSUER 'issuer' | SUBJECT 'subject' }

resource_option: { | MAX_QUERIES_PER_HOUR count | MAX_UPDATES_PER_HOUR count | MAX_CONNECTIONS_PER_HOUR count | MAX_USER_CONNECTIONS count }

PostgreSQL https://www.postgresql.org/docs/10/static/sql-grant.html
PostgreSQL supports a lot of variations of the GRANT statement. Let's take as a basis the above clause. I separate this on several groups:
Group 1:

  1. ACTIONS: { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER } [, ...] | ALL [ PRIVILEGES ] }
  2. OBJECT: { [ TABLE ] table_name [, ...] | ALL TABLES IN SCHEMA schema_name [, ...] }

Group 2:

  1. ACTIONS: { { SELECT | INSERT | UPDATE | REFERENCES } ( column_name [, ...] ) [, ...] | ALL [ PRIVILEGES ] ( column_name [, ...] ) }
  2. OBJECT: [ TABLE ] table_name [, ...]

Group 3:

  1. ACTIONS: { { USAGE | SELECT | UPDATE } [, ...] | ALL [ PRIVILEGES ] }
  2. OBJECT: { SEQUENCE sequence_name [, ...] | ALL SEQUENCES IN SCHEMA schema_name [, ...] }

Group 4:

  1. ACTIONS: { { CREATE | CONNECT | TEMPORARY | TEMP } [, ...] | ALL [ PRIVILEGES ] }
  2. OBJECT: DATABASE database_name [, ...]

Group 5:

  1. ACTIONS: { USAGE | ALL [ PRIVILEGES ] }
  2. OBJECT: {DOMAIN domain_name [, ...] | FOREIGN DATA WRAPPER fdw_name [, ...] | FOREIGN DATA WRAPPER fdw_name [, ...] | FOREIGN SERVER server_name [, ...] | LANGUAGE lang_name [, ...] | TYPE type_name [, ...] }

Group 6:

  1. ACTIONS: { EXECUTE | ALL [ PRIVILEGES ] }
  2. OBJECT: { FUNCTION function_name [ ( [ [ argmode ] [ arg_name ] arg_type [, ...] ] ) ] [, ...] | ALL FUNCTIONS IN SCHEMA schema_name [, ...] }

Group 7:

  1. ACTIONS: { { SELECT | UPDATE } [, ...] | ALL [ PRIVILEGES ] }
  2. OBJECT: LARGE OBJECT loid [, ...]

Group 8:

  1. ACTIONS: { { CREATE | USAGE } [, ...] | ALL [ PRIVILEGES ] }
  2. OBJECT: SCHEMA schema_name [, ...]

Group 9:

  1. ACTIONS: { CREATE | ALL [ PRIVILEGES ] }
  2. OBJECT: TABLESPACE tablespace_name [, ...]

<grantees> = { [ GROUP ] role_name | PUBLIC | CURRENT_USER | SESSION_USER }
ROLE_OPTIONS: [ WITH GRANT OPTION ]

Oracle https://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_9013.htm
SQL Server

This was referenced Nov 22, 2017

@lukaseder

This comment has been minimized.

Show comment
Hide comment
@lukaseder

lukaseder Nov 22, 2017

Member

Thank you very much for this overview. That's kind of what I feared - it's a very vast territory. In any case, we don't have to (and probably shouldn't) implement all of it. Thus far, jOOQ's DDL API allows for creating objects like tables, sequences, views, etc. We should focus on actions that are possible on those objects that can be created by jOOQ. For instance, a privilege to create or access a table space or to connect to databases or to create objects is currently out of scope (which I would consider system privileges). We'll focus only on object access privileges right now. Also, granting access to roles seems out of scope right now.

So, how about the following subset:

grantStatement ::=
  GRANT { SELECT | INSERT | UPDATE | DELETE } ON <table> TO { <user> | <role> }

revokeStatement ::=
  REVOKE { SELECT | INSERT | UPDATE | DELETE } ON <table> FROM { <user> | <role> } 

The <table> reference is already available from the jOOQ API through org.jooq.Table. The <user> and <role> references will need to be created as new types: org.jooq.User and org.jooq.Role. I'm creating separate tasks for those types (let's focus on User first (#6838), and maybe do Role (#6839) later).

The DSL API should have convenience methods for the above four actions. Later on, when we decide that other types of actions should be supported as well, we can still introduce a new type org.jooq.Privilege or org.jooq.Action. So, I'm suggesting the following syntax that will be available from DSL and from DSLContext:

// Examples
grantSelectOn(table).to(user).execute();
revokeInsertOn(table).from(user).execute();

We can then add additional tasks as we go for things like WITH GRANT OPTION.

So, immediate steps:

  1. Implement org.jooq.User (through #6838)
  2. Implement the above simple API
  3. Update the parser (through #6485)
Member

lukaseder commented Nov 22, 2017

Thank you very much for this overview. That's kind of what I feared - it's a very vast territory. In any case, we don't have to (and probably shouldn't) implement all of it. Thus far, jOOQ's DDL API allows for creating objects like tables, sequences, views, etc. We should focus on actions that are possible on those objects that can be created by jOOQ. For instance, a privilege to create or access a table space or to connect to databases or to create objects is currently out of scope (which I would consider system privileges). We'll focus only on object access privileges right now. Also, granting access to roles seems out of scope right now.

So, how about the following subset:

grantStatement ::=
  GRANT { SELECT | INSERT | UPDATE | DELETE } ON <table> TO { <user> | <role> }

revokeStatement ::=
  REVOKE { SELECT | INSERT | UPDATE | DELETE } ON <table> FROM { <user> | <role> } 

The <table> reference is already available from the jOOQ API through org.jooq.Table. The <user> and <role> references will need to be created as new types: org.jooq.User and org.jooq.Role. I'm creating separate tasks for those types (let's focus on User first (#6838), and maybe do Role (#6839) later).

The DSL API should have convenience methods for the above four actions. Later on, when we decide that other types of actions should be supported as well, we can still introduce a new type org.jooq.Privilege or org.jooq.Action. So, I'm suggesting the following syntax that will be available from DSL and from DSLContext:

// Examples
grantSelectOn(table).to(user).execute();
revokeInsertOn(table).from(user).execute();

We can then add additional tasks as we go for things like WITH GRANT OPTION.

So, immediate steps:

  1. Implement org.jooq.User (through #6838)
  2. Implement the above simple API
  3. Update the parser (through #6485)
@timur-sh

This comment has been minimized.

Show comment
Hide comment
@timur-sh

timur-sh Nov 22, 2017

Contributor

Thank you for reply! I agree with you. But, I would extend the clause by SEQUENCE and REFERENCES statements either will add them future (within next tasks).

grantStatement ::=
  GRANT { SELECT | INSERT | UPDATE | DELETE | SEQUENCE | REFERENCES } ON <table> TO { <user> | <role> }

revokeStatement ::=
  REVOKE { SELECT | INSERT | UPDATE | DELETE | SEQUENCE | REFERENCES } ON <table> FROM { <user> | <role> } 
Contributor

timur-sh commented Nov 22, 2017

Thank you for reply! I agree with you. But, I would extend the clause by SEQUENCE and REFERENCES statements either will add them future (within next tasks).

grantStatement ::=
  GRANT { SELECT | INSERT | UPDATE | DELETE | SEQUENCE | REFERENCES } ON <table> TO { <user> | <role> }

revokeStatement ::=
  REVOKE { SELECT | INSERT | UPDATE | DELETE | SEQUENCE | REFERENCES } ON <table> FROM { <user> | <role> } 
@lukaseder

This comment has been minimized.

Show comment
Hide comment
@lukaseder

lukaseder Nov 22, 2017

Member

Let's add convenience API for the 4 actions mentioned, and then look into a org.jooq.Action (or so) type to model the more rare / complex cases to prevent the API from exploding. For instance, REFERENCES takes arguments in some databases. It could look like this:

grant(references(T.COL1, T.COL2)).on(T).to(user).execute();
Member

lukaseder commented Nov 22, 2017

Let's add convenience API for the 4 actions mentioned, and then look into a org.jooq.Action (or so) type to model the more rare / complex cases to prevent the API from exploding. For instance, REFERENCES takes arguments in some databases. It could look like this:

grant(references(T.COL1, T.COL2)).on(T).to(user).execute();
@timur-sh

This comment has been minimized.

Show comment
Hide comment
@timur-sh

timur-sh Nov 23, 2017

Contributor

What must be next step eitherPerhaps, code generation support or The actual API and its implementation

Could you create appropriate task?

Contributor

timur-sh commented Nov 23, 2017

What must be next step eitherPerhaps, code generation support or The actual API and its implementation

Could you create appropriate task?

@lukaseder

This comment has been minimized.

Show comment
Hide comment
@lukaseder

lukaseder Nov 23, 2017

Member

This task talks about the statement and API implementation. Code generation support will be in another task.

Member

lukaseder commented Nov 23, 2017

This task talks about the statement and API implementation. Code generation support will be in another task.

@timur-sh

This comment has been minimized.

Show comment
Hide comment
@timur-sh

timur-sh Nov 24, 2017

Contributor

I plant to start to work on implementation the mentioned API, I suggest one of kind of implementation to be looked like:

grant(EnumPrivilege privilege).on(Table).to(user | role).execute();
grant(EnumPrivilege... privileges).on(Table).to(user | role).execute();


revoke(EnumPrivilege privilege).on(Table).from(user | role).execute();
revoke(EnumPrivilege... privileges).from(Table).from(user | role).execute();

My suggestion also is, we should add another one Interface, that will be used in the from() method.

Contributor

timur-sh commented Nov 24, 2017

I plant to start to work on implementation the mentioned API, I suggest one of kind of implementation to be looked like:

grant(EnumPrivilege privilege).on(Table).to(user | role).execute();
grant(EnumPrivilege... privileges).on(Table).to(user | role).execute();


revoke(EnumPrivilege privilege).on(Table).from(user | role).execute();
revoke(EnumPrivilege... privileges).from(Table).from(user | role).execute();

My suggestion also is, we should add another one Interface, that will be used in the from() method.

@lukaseder

This comment has been minimized.

Show comment
Hide comment
@lukaseder

lukaseder Nov 24, 2017

Member

I'd really prefer the privilege not to be an enum. We don't know what sorts of privileges we'll have in the future, and how they're composed. However, you're right. there should be an overload allowing for passing several privileges. There's usually also an overload for Collection<? extends Privilege>, for convenience.

I prefer not to add another interface for the from() method. The number of interfaces would explode if we did things this way. The fact that we really have a union type user | role (if Java supported them) is best emulated through overloads, again.

Member

lukaseder commented Nov 24, 2017

I'd really prefer the privilege not to be an enum. We don't know what sorts of privileges we'll have in the future, and how they're composed. However, you're right. there should be an overload allowing for passing several privileges. There's usually also an overload for Collection<? extends Privilege>, for convenience.

I prefer not to add another interface for the from() method. The number of interfaces would explode if we did things this way. The fact that we really have a union type user | role (if Java supported them) is best emulated through overloads, again.

timur-sh added a commit to timur-sh/jOOQ that referenced this issue Nov 28, 2017

timur-sh added a commit to timur-sh/jOOQ that referenced this issue Nov 29, 2017

[jOOQ#6812] Added GRANT statement and its implementation.
[jOOQ#6812] Revoke statement was added and its implementation.

[jOOQ#6839] Enhancement and refactoring

lukaseder added a commit that referenced this issue Nov 30, 2017

Merge pull request #6878 from timur-sh/6812
[#6812] Added GRANT statement and its implementation.
@lukaseder

This comment has been minimized.

Show comment
Hide comment
@lukaseder

lukaseder Nov 30, 2017

Member

The implementation from PR #6878 has been successfully integration tested for Oracle thus far. Further work is gonig to be implemented soon

Member

lukaseder commented Nov 30, 2017

The implementation from PR #6878 has been successfully integration tested for Oracle thus far. Further work is gonig to be implemented soon

@lukaseder

This comment has been minimized.

Show comment
Hide comment
@lukaseder

lukaseder Dec 7, 2017

Member

I added parser support for these statements

Member

lukaseder commented Dec 7, 2017

I added parser support for these statements

@lukaseder

This comment has been minimized.

Show comment
Hide comment
@lukaseder

lukaseder Dec 19, 2017

Member

Alright. Only DB2 and MySQL / MariaDB missing in the integration tests for now. I'll do those a bit later. Their users are a bit of a pain to set up.

Member

lukaseder commented Dec 19, 2017

Alright. Only DB2 and MySQL / MariaDB missing in the integration tests for now. I'll do those a bit later. Their users are a bit of a pain to set up.

@lukaseder lukaseder added the R: Fixed label Dec 22, 2017

@lukaseder lukaseder closed this Dec 22, 2017

@lukaseder

This comment has been minimized.

Show comment
Hide comment
@lukaseder

lukaseder Dec 22, 2017

Member

MySQL is done. DB2 will be done in a later release / upon customer request. Thanks again for all your help implementing this feature, @timur-sh !

Member

lukaseder commented Dec 22, 2017

MySQL is done. DB2 will be done in a later release / upon customer request. Thanks again for all your help implementing this feature, @timur-sh !

@timur-sh

This comment has been minimized.

Show comment
Hide comment
@timur-sh

timur-sh Dec 22, 2017

Contributor

You're welcome! :)

Contributor

timur-sh commented Dec 22, 2017

You're welcome! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment