Add table function to execute stored procedure in SQLServer#15982
Add table function to execute stored procedure in SQLServer#15982Praveen2112 wants to merge 4 commits intotrinodb:masterfrom
Conversation
e17613b to
eec9f7d
Compare
There was a problem hiding this comment.
Let's have a BaseJdbcConnectorTableHandle marker interface and let JdbcProcedureHandle, JdbcTableHandle both extend it; use here
There was a problem hiding this comment.
It should be as an abstract class right ?
plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/JdbcRecordSet.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Why not for procedure handle?
Have same check for them too
There was a problem hiding this comment.
In case of Will implement it.ProcedureHandle we won't face the no columns kind of a situation - plus the columns are populated when we are creating the table handle. Add the ProcedureHandle doesn't support project pushdown there is a good chance the column we pass on RecordSetProvider might be a subset of overall columns present in ProcedureHandle.
There was a problem hiding this comment.
not sure if we use records for between-nodes serialization (I think we are starting to)
then ProcedureFunctionHandle above can be a record too
also, i don't think we need @JsonProperty and @JsonCreator for records (airlift/airlift#993), do we?
There was a problem hiding this comment.
ProcedureFunctionHandle - wanted be in-sync with other TableHandle implementation. I don't have any strong opinions on it. Will move it to a record.
There was a problem hiding this comment.
You don't need this. The code will never get invoked with JdbcProcedureHandle, and if it would, it would fail explicitly anyway
There was a problem hiding this comment.
Can we replicate it for all alter options ?
584e83c to
47bdf91
Compare
|
@findepi AC. |
47bdf91 to
db1d540
Compare
plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/BaseJdbcClient.java
Outdated
Show resolved
Hide resolved
plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/BaseJdbcClient.java
Outdated
Show resolved
Hide resolved
plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/CachingJdbcClient.java
Outdated
Show resolved
Hide resolved
plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/JdbcTableHandle.java
Outdated
Show resolved
Hide resolved
As for me it's really new topic, can you please point me to some entry point, to understand what we have now (I mean existing query table function) and why we can't use it for this connectors |
|
@vlad-lyutenko this all boils down to two things
|
|
Given that this is a very powerful user facing feature that potentially has huge security and functionality implications I request the following:
|
|
Also for reference following is a link to the section in the MySQL connector docs where a new subsection for the new table function is needed. https://trino.io/docs/current/connector/mysql.html#table-functions And related question... will this table function have a similar restriction where it is required that the stored procedure returns a result set? If so .. that could be limiting functionality. And if not ... the security implications are even bigger since arbitrary stored procedures can be called. Last.. I assume that the user accessing the database from the catalog configuration has to have the right to run the stored procedure .. can you detail what is actually specifically needed in MySQL and SQL Server terminology? |
db1d540 to
9bf4ed0
Compare
Yes we have a same restriction where the stored procedure has to return a
Similar to tables - if the user specified in the catalog configuration has access to run the stored procedures then we would support it. |
|
@kokosing AC |
There was a problem hiding this comment.
I think it would be more user-friendly if the argument was renamed to procedure and the user would only pass the procedure call, that is "procedure_name()" without the CALL keyword.
There was a problem hiding this comment.
Depending on vendor you are using CALL or EXEC. So maybe we could rename name of function to call to exec depending on vendor (connector) and only pass the name of procedure. This could work only if we are not expecting to pass parameters any parameters to procedures.
There was a problem hiding this comment.
In case of arguments we could either pass them as an Array<String> and handle them accordingly.
plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/BaseJdbcClient.java
Outdated
Show resolved
Hide resolved
|
Need any help with the docs here @Praveen2112 ? Should I send a separate parallel PR? |
9bf4ed0 to
10dc303
Compare
6d8b5c4 to
f464ee5
Compare
be36f5f to
daec542
Compare
kokosing
left a comment
There was a problem hiding this comment.
skimmed. I am fine with the approach
There was a problem hiding this comment.
what if procedure expects an integer?
There was a problem hiding this comment.
For now we pass the arguments as string - we pass it without quotes for integer and with additional quotes for string (if requested by the underlying datasource).
There was a problem hiding this comment.
But for SQLServer, it doesn't expect additional quotes. So do we need to document it ?
There was a problem hiding this comment.
It’d be better to pass the arguments as a ROW, so each one has the proper type. You get type safety and avoid conversions that might not be possible to do easily or reliably.
There was a problem hiding this comment.
Can you provide pointer on where/how it is established during the analysis step - Should we use a different Argument specification for this.
There was a problem hiding this comment.
The type of scalar argument is established at TF declaration.
There was a problem hiding this comment.
Even if we could pass arbitrary scalars, it seems right to use an array of varchar in this case. It shifts the responsibility of formatting them the right way to the user. That's in the spirit of query pass-through. This way it is harder for the user to pass parameters, or non-literal expressions, but I don't know if a real use-case would need those capabilities.
Like @kokosing noticed, we must watch out for possible abuse (injection).
There was a problem hiding this comment.
Table argument is the only argument type of table functions that is polymorphic . Technically, we could make use of it, and pass a scalar subquery containing parameters. But then we'd have to refactor the PTF to use the operator-based execution.
There was a problem hiding this comment.
it looks like one could inject some SQL by using inputs.
There was a problem hiding this comment.
Thanks for pointing it out. Have added additional checks.
daec542 to
d383be0
Compare
hashhar
left a comment
There was a problem hiding this comment.
Approach looks good, some early comments.
plugin/trino-sqlserver/src/main/java/io/trino/plugin/sqlserver/SqlServerClient.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
https://learn.microsoft.com/en-us/sql/t-sql/queries/output-clause-transact-sql?view=sql-server-ver16 exists so can we test with it as well?
There was a problem hiding this comment.
Have added test with OUTPUT clause.
plugin/trino-sqlserver/src/test/java/io/trino/plugin/sqlserver/BaseSqlServerConnectorTest.java
Outdated
Show resolved
Hide resolved
plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/CachingJdbcClient.java
Outdated
Show resolved
Hide resolved
d383be0 to
3792ce9
Compare
|
@hashhar , @skrzypo987 AC |
3301e93 to
91ee0b7
Compare
|
Rebased the PR to resolve conflicts. |
91ee0b7 to
5fa16b1
Compare
hashhar
left a comment
There was a problem hiding this comment.
LGTM with the recent changes.
mosabua
left a comment
There was a problem hiding this comment.
Docs look good. Did not look at the code..
plugin/trino-base-jdbc/src/test/java/io/trino/plugin/jdbc/TestProcedure.java
Outdated
Show resolved
Hide resolved
5fa16b1 to
8515486
Compare
plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/BaseJdbcClient.java
Outdated
Show resolved
Hide resolved
8515486 to
47e7213
Compare
There was a problem hiding this comment.
If we can process arguments via preparedCall.setParameter we wouldn't need this.
if we cannot process arguments via preparedCall.setParameter we shouldn't pretend we can.
If the user provides parameter values as string literals to be concatenated with the procedure call, why can't they provide the whole procedure call (including the parameters)? Just like we do with SQL pushdown?
There was a problem hiding this comment.
If we can process arguments via preparedCall.setParameter we wouldn't need this.
It could be possible - like if we could get the procedure column information and map them accordingly. I would like implement them in an incremental way as executing stored procedure is kind of an experimental feature. WDYT ?
why can't they provide the whole procedure call (including the parameters)? Just like we do with SQL pushdown?
The initial approach we have is like SQL Pushdown - where we don't do any processing but consume a String as an input. For some datasources like SQLServer it would be helpful if we could get the schema and procedure name - so we could apply some checks to ensure the SP doesn't any DDL or DML operations. So it more of an extended version of SQLPushdown - where we take some of them in parts and concat all the pieces.
These methods can be reused for Procedures PTF - Extract building columns from ResultSetMetaData as a separate method. - Extract creating connection based on session
47e7213 to
88d57a0
Compare
|
Rebased due to conflicts. |
|
Overridden by #16696 |
Description
A dedicated table function which allows us to run stored procedures in SQLServer. We can't use existing query table function - as it wraps with inside a query like
SELECT * FROM (EXEC my_procedure) o- so we are handing them via a different function. All the pushdown are disabled forJdbcProcedureHandleresolved by thisProcedure.Slightly different implementation from #15813
Limitation
ResultSetonly for the first statement. (Test to be added)Example
Release notes
( ) This is not user-visible or docs only and no release notes are required.
(x) Release notes are required, please propose a release note for me.
( ) Release notes are required, with the following suggested text: