antlr / grammars-v4

Grammars written for ANTLR v4; expectation that the grammars are free of actions.
MIT License
10.14k stars 3.7k forks source link

TSQL: `GO` falsely identify as `column_alias`? #3275

Open svengiegerich opened 1 year ago

svengiegerich commented 1 year ago

newbie

What happened:

I'm trying to parse: SELECT 'a' GO SELECT 'b'

Expected: two batches

Actual: parsed within one batch

Being a newbie, it seems that the substring "GO" is wrongly parsed within the rule column_alias while it's protected.


The parse tree image

speshuric commented 1 year ago

It seems that SQL Server parses it as one batch. Results of execute:

GO
----
a

----
b

Here GO parsed as alias too. GO should be on new line:

A Transact-SQL statement cannot occupy the same line as a GO command. However, the line can contain comments.

form ms docs

svengiegerich commented 1 year ago

Thanks, @speshuric, for your swift response! Again maybe just me, but I seem to get the same "issue" even with a line break?

SELECT 'a' 
GO 
SELECT 'b'
image

It seems that SQL Server parses it as one batch. Results of execute:

Hmm, on my DB server with MSSQL - Microsoft SQL Server 2017 (RTM) - 14.0.1000.169 (X64) - I get the following output:

image

Is there a good way to check what is contained in one batch?

I can only think of smth like DECLARE @a INT = 4 SELECT @a GO SELECT @a where I get an issue when executing it on the server...

image

... but, again, the same batch using the grammar

image

Sorry, maybe I miss smth fundamental here...

speshuric commented 1 year ago

Let's separate the issues.

The first of all ms says "GO is not a Transact-SQL statement; it is a command recognized by the sqlcmd and osql utilities and SQL Server Management Studio Code editor." So the only way to check it correctly is to check it in sqlcmd/osql/ssms. Your screenshots are from Jetbrains tools (IDEA, DataGrip, Rider or same tools), so your statement "I get the following output" relates to these tools. JB tools are surely awesome and cool, but TSQL parser in them, hmmm, is quite far from ideal. Personally, I opened several tickets in DataGrip youtrack and some of that is not resolved now. For example about GO. I have been using DataGrip even before it rolled out to release and when it called 0xDBE :) It has come a long way, but there is still room for improvement.

The second moment to note is that indeed it seems grammar in this repo is not correct about dividing file to batches by GO-statements. But there is workaround. You can just use semicolon to help parser separate SELECTs:

select 'a';
go 
select 'b'

Parsed as: Screenshot 2023-03-19 002411 I would be glad if it helps you.

The last thing I have to note, there is no full open specification for T-SQL, so all third party implementations including this one should deal with this sadly fact.

svengiegerich commented 1 year ago

@speshuric, thanks so much! Thanks to your comment, I've learned a ton as I wasn't aware that there is an own DataGrip. I've switched to sqlcmd now.

The second moment to note is that indeed it seems grammar in this repo is not correct about dividing file to batches by GO-statements.

Yes, indeed. I've changed it now accordingly. But it would still be nice to fix it here eventually...