Skip to content
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

Support for OUTPUT in t-sql #1901

Closed
jh88 opened this issue Jul 8, 2023 · 9 comments
Closed

Support for OUTPUT in t-sql #1901

jh88 opened this issue Jul 8, 2023 · 9 comments

Comments

@jh88
Copy link

jh88 commented Jul 8, 2023

Thank you for the great work. I have been using this for transpiling SQL server (tsql) to PostgreSQL.

I would like to request support for the OUTPUT keyword in T-SQL, which is similar to the RETURNING keyword in PostgreSQL.

For instance, when executing an INSERT statement like the one below, the OUTPUT clause would return the primary key value id of the inserted row:

INSERT INTO [my_table] ([my_column]) OUTPUT inserted.id VALUES(0);

Thank you.

@tobymao
Copy link
Owner

tobymao commented Jul 8, 2023

thanks for the report

@tobymao tobymao closed this as completed in d68f844 Jul 8, 2023
@jh88
Copy link
Author

jh88 commented Jul 10, 2023

Thank you Toby for the quick response.

The aforementioned sample query, when transpiled using the new code, would be as follows:

INSERT INTO "my_table" (
  "my_column"
)
VALUES
  (0)
RETURNING inserted.id

However, it is necessary to remove inserted in the RETURNING clause.

Conversely, when returning inserted fields in T-SQL, we need to add the inserted prefix.

@tobymao
Copy link
Owner

tobymao commented Jul 10, 2023

did you test it with tsql specified?

@tobymao
Copy link
Owner

tobymao commented Jul 10, 2023

ah i see what you're saying, when going to returning, we need to remove inserted. it doesn't seem like the prefix can be added in the other direction though because it doesn't exist

@jh88
Copy link
Author

jh88 commented Jul 10, 2023

Yes, I'm transpiling between tsql and postgres.

I created a new AzureSQL class which inherits your TSQL. In the returning_sql method, as a workaround, I manually assign table to inserted.

def returning_sql(self, expression: exp.Returning) -> str:
    into = self.sql(expression, "into")
    into = self.seg(f"INTO {into}") if into else ""

    for e in expression.args['expressions']:
        e.args['table'] = 'inserted'

    return f"{self.seg('OUTPUT')} {self.expressions(expression, flat=True)}{into}"

@tobymao
Copy link
Owner

tobymao commented Jul 10, 2023

sorry, is inserted a magic keyword in tsql?

@jh88
Copy link
Author

jh88 commented Jul 10, 2023

Apologies for any misunderstandings. I am not inserting data into the table named inserted.
It is a table that is managed by SQL Server. You can find more information about it here.

The inserted table stores copies of the new or changed rows after an INSERT or UPDATE statement.

My understanding is that we should use the inserted table when working with the INSERT statement, and the deleted table for the DELETE statement.

@tobymao
Copy link
Owner

tobymao commented Jul 10, 2023

it's not so simple

UPDATE Production.WorkOrder
SET ScrapReasonID = 4
OUTPUT DELETED.ScrapReasonID,
       INSERTED.ScrapReasonID,
       INSERTED.WorkOrderID,
       INSERTED.ProductID,
       p.Name
    INTO @MyTestVar
FROM Production.WorkOrder AS wo
    INNER JOIN Production.Product AS p
    ON wo.ProductID = p.ProductID
    AND wo.ScrapReasonID= 16
    AND p.ProductID = 733;

if you're trying to convert postgres into tsql, you won't be able to know what inserted and deleted columns are

@tobymao
Copy link
Owner

tobymao commented Jul 10, 2023

i'm not going to support this for now, you can add a custom transform to do what you're looking for

expr.transform(...)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants