Hi Dan,
Here are answers to your questions
Question 1)
<quote>
This paragraph talks about a stack of default schemas and current schemas, but there are no more details of how this will be implemented. Also, I don't remember anything in the functional spec about how current or default schema was changing, but I can't get to Jira to check & I don't have a local copy of the functional spec from DEBRY-464. Just want to understand what functionality you are proposing to be implemented.
</quote>
This paragraph talks about a stack of default schemas and current schemas, but there are no more details of how this will be implemented. Also, I don't remember anything in the functional spec about how current or default schema was changing, but I can't get to Jira to check & I don't have a local copy of the functional spec from DEBRY-464. Just want to understand what functionality you are proposing to be implemented.
</quote>
Let me take an example to explain what I am trying to achieve here. Have a insert trigger on a table and have the trigger invokes a function. The invoked function will change the schema to a different schema. What should be the current schema at the end of insert statement?
Following is the java code for sql function change_schema
org.apache.derbyTesting.functionTests.util.ProcedureTest.changeSchema
public static int changeSchema(String schemaName) throws SQLException {
Connection conn = DriverManager.getConnection("jdbc:default:connection");
Statement s = conn.createStatement();
s.executeUpdate ("set schema " + schemaName);
s.close();
conn.close();
return 1;
}
Connection conn = DriverManager.getConnection("jdbc:default:connection");
Statement s = conn.createStatement();
s.executeUpdate ("set schema " + schemaName);
s.close();
conn.close();
return 1;
}
ij session
connect 'jdbc:derby:c:/dellater/db1sqlStandardNewCol;create=true' user 'mamta1';
create table mamta1t1 (c11 int);
CREATE FUNCTION Change_schema(P1 VARCHAR(128)) RETURNS INT READS SQL DATA
EXTERNAL NAME 'org.apache.derbyTesting.functionTests.util.ProcedureTest.changeSchema '
LANGUAGE JAVA PARAMETER STYLE JAVA;
create trigger tr1t1 after insert on mamta1t1 for each row mode db2sql values change_schema('mamta1');
grant insert on mamta1t1 to mamta2;
create table mamta1t1 (c11 int);
CREATE FUNCTION Change_schema(P1 VARCHAR(128)) RETURNS INT READS SQL DATA
EXTERNAL NAME 'org.apache.derbyTesting.functionTests.util.ProcedureTest.changeSchema '
LANGUAGE JAVA PARAMETER STYLE JAVA;
create trigger tr1t1 after insert on mamta1t1 for each row mode db2sql values change_schema('mamta1');
grant insert on mamta1t1 to mamta2;
connect 'jdbc:derby:c:/dellater/db1sqlStandardNewCol;create=true' user 'mamta2';
values current schema; -- this will be mamta2 at this point
values current schema; -- this will be mamta2 at this point
insert into mamta1.mamta1t1 values(1); -- function invoked by the trigger is setting the schema to mamta1
values current schema; -- schema should be mamta2 again
In order to ensure that current schema is mamta2 after the insert, any changes made to switch schema inside the function should apply to StatementContext associated with the function and not to the StatementContext associated with the insert statement. And that is why I was proposing that in addition to the authorizer stack in StatementContext, we should also have a stack for default schema descriptors in StatementContext for those authorizers.
Question 2)
<quote>
The etc. is a little worrying in a design spec, which methods are you
changing the behaviour of, is LCC.getAuthorizationId one of them?
</quote>
changing the behaviour of, is LCC.getAuthorizationId one of them?
</quote>
LCC has various methods which at this point uses the session authorizer and it's schema. This was fine with legacy database. But with sqlStandard database, these methods should get the current authorizer from the top active StatementContext and use that authorizer and it's schema in the various methods. In the absence of an active StatementContext, LCC should use session authorizer. The reason behind this change is same as the answer to Question 1.
The LCC methods affected will be
public PreparedStatement prepareInternalStatement(String sqlText)
public String getAuthorizationId()
public SchemaDescriptor getDefaultSchema()
public String getCurrentSchemaName()
public void setDefaultSchema(SchemaDescriptor sd)
public void setReadOnly(boolean on) throws StandardException
public boolean isReadOnly()
public String getAuthorizationId()
public SchemaDescriptor getDefaultSchema()
public String getCurrentSchemaName()
public void setDefaultSchema(SchemaDescriptor sd)
public void setReadOnly(boolean on) throws StandardException
public boolean isReadOnly()
public Authorizer getAuthorizer()
</quote>
Question/Comment 3)
<quote>
Might I suggest some method name changes, for readability and
clarity of meaning?
addAuthorizerToTopOfStack -> pushAuthorizer
removeAuthorizerFromTopOfStack
clarity of meaning?
addAuthorizerToTopOfStack -> pushAuthorizer
removeAuthorizerFromTopOfStack
</quote>
Thanks for your suggestions. I will incorporate those
Question/Comment 4)
<quote>
Also, I think for the term "invoker", you really mean "session" in some
cases. E.g. it's not the invoker user identifier or Authorizer, it's the
session's user identifier or Authorizer.
cases. E.g. it's not the invoker user identifier or Authorizer, it's the
session's user identifier or Authorizer.
So, to make sure I understand it correctly, the user who makes the database connection is the session user and LCC will keep the authorizer for the session user. Going to back to my example earlier
connect 'jdbc:derby:c:/dellater/db1sqlStandardNewCol;create=true' user 'mamta2';
-- we have session authorizer mamta2 at this point
values current schema;
values current schema;
-- we still have session authorizer mamta2 at this point
-- But since trigger (fired by insert below) gets executed with definer authorizer, inside the function change_schema, the authorizer used will be invoker
-- But since trigger (fired by insert below) gets executed with definer authorizer, inside the function change_schema, the authorizer used will be invoker
-- authorizer for mamta1
insert into mamta1.mamta1t1 values(1); -- trigger is setting the schema to mamta1
-- we are back to session authorizer mamta2
values current schema;
Question/Comment 5)
<quote>
When can this happen? I don't think this code and the associated new
methods (getInvokeAuthorizer and addAuthorizerToTopOfStack(Authorizer)
are required.
</quote>
methods (getInvokeAuthorizer and addAuthorizerToTopOfStack(Authorizer)
are required.
</quote>
After thinking further about this, I think you are right. Can't pinpoint the technical reason at this time for a need to push the session authorizer.
I hope this addresses your comments. If yes and nonone else has any comments, then I can start looking at implementing this.
Mamta
On 3/15/06, Daniel John Debrunner <[EMAIL PROTECTED]> wrote:
Mamta Satoor wrote:
> Here is the proposal for invoker/definer model based on StatementContext.
Thanks for the changes, this looks like the correct direction.
>
> I am proposing that we continue to keep the "invoker" authorizer
> information in GenericeLanguageConnectionContext. In addition to that,
> we will keep a stack of authorizers and corresponding default schema
> descriptors in a StatementContext. When authorizer information (like
> getAuthorizationId, getDefaultSchema, getCurrentSchemaName etc) will be
> requested from LanguageConnectionContext, it will check if it has an
> active StatementContext. If it does have an active
> StatementContext, then the authorization information requested will be
> obtained from authorizer at the top of StatementContext's authorizer
> stack. But if there is no active StatementContext, then authorization
> information requested will come from LanguageConnectionContext's invoker
> authorizer.
This paragraph talks about a stack of default schemas and current
schemas, but there are no more details of how this will be implemented.
Also, I don't remember anything in the functional spec about how current
or default schema was changing, but I can't get to Jira to check & I
don't have a local copy of the functional spec from DEBRY-464. Just want
to understand what functionality you are proposing to be implemented.
> When authorizer information (like
> getAuthorizationId, getDefaultSchema, getCurrentSchemaName etc)
The etc. is a little worrying in a design spec, which methods are you
changing the behaviour of, is LCC.getAuthorizationId one of them?
Might I suggest some method name changes, for readability and
clarity of meaning?
addAuthorizerToTopOfStack -> pushAuthorizer
removeAuthorizerFromTopOfStack -> popAuthorizer
Also, I think for the term "invoker", you really mean "session" in some
cases. E.g . it's not the invoker user identifier or Authorizer, it's the
session's user identifier or Authorizer.
> If an object needs to switch to invoker's authorization, code should be
> generated to get the invoker authorizer from
> GenericLanguageConnectionContext and put that authorizer to the top of
> authorizer stack by generating code addAuthorizerToTopOfStack(Authorizer
> invokerAuthorizer). To get the invoker authorizer, I am planning on
> adding method getInvokerAuthorizer to GenericLanguageConnectionContext.
When can this happen? I don't think this code and the associated new
methods (getInvokeAuthorizer and addAuthorizerToTopOfStack(Authorizer)
are required.
Thanks,
Dan.
