Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/howto/analyze.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ provided. The schema is always read from the `--schema` file.
## Flags

- `--dialect`, `-d` - The SQL dialect to use. One of `postgresql`, `mysql`,
`sqlite`, `clickhouse`, or `googlesql`. Required.
`sqlite`, `clickhouse`, `googlesql`, or `mssql`. Required.
- `--schema`, `-s` - Path to the schema (DDL) file. Required.
- `--ast` - Include each statement's AST in the output. Defaults to `false`.

Expand Down
2 changes: 1 addition & 1 deletion docs/howto/parse.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ provided.
## Flags

- `--dialect`, `-d` - The SQL dialect to use. One of `postgresql`, `mysql`,
`sqlite`, `clickhouse`, or `googlesql`. Required.
`sqlite`, `clickhouse`, `googlesql`, or `mssql`. Required.

## Examples

Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ require (
github.com/sqlc-dev/marino v0.1.0
github.com/sqlc-dev/meyer v0.1.1
github.com/sqlc-dev/oliphant v0.1.0
github.com/sqlc-dev/teesql v1.1.0
github.com/sqlc-dev/zetajones v0.1.0
github.com/tetratelabs/wazero v1.12.0
github.com/xeipuuv/gojsonschema v1.2.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ github.com/sqlc-dev/meyer v0.1.1 h1:BAeZcfgLyTnk9f90DyGEKXPrHxtgvVD/DTM6awq2kUY=
github.com/sqlc-dev/meyer v0.1.1/go.mod h1:pS4USCRf/SLjWtaMcnTo4YrEEFKBj8CyyqlxcVUJQH8=
github.com/sqlc-dev/oliphant v0.1.0 h1:RAsO6BMitIzB2+swx/qzUR5nf6w4cQ1abgHIu+Fgppo=
github.com/sqlc-dev/oliphant v0.1.0/go.mod h1:fRM/t4FutRddTIq2YCuS4O9o+2rRwSwELRvLMqtPloo=
github.com/sqlc-dev/teesql v1.1.0 h1:3sVYQ9FGxQVcqrqQOQ27bk0aF4c4yN1H1zLL79uaSxQ=
github.com/sqlc-dev/teesql v1.1.0/go.mod h1:WwOp9UtnxG17+eNFT5KXu/AGBQ8ucdGc8wIOpnj4XCI=
github.com/sqlc-dev/zetajones v0.1.0 h1:VeG0atx6lNABr9V2bSI5vL9DvOKTHX0XjMqWUE/rv40=
github.com/sqlc-dev/zetajones v0.1.0/go.mod h1:dU1DxwqC6Cahbpnw16KpH1J2waWRDMdwyDSvovMZR4I=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
Expand Down
11 changes: 8 additions & 3 deletions internal/cmd/analyze.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ Examples:
# Analyze a GoogleSQL (BigQuery, Spanner) query
sqlc analyze --dialect googlesql --schema schema.sql query.sql

# Analyze a SQL Server (T-SQL) query
sqlc analyze --dialect mssql --schema schema.sql query.sql

# Analyze a query piped via stdin
echo "-- name: GetAuthor :one
SELECT * FROM authors WHERE id = $1;" | sqlc analyze --dialect postgresql --schema schema.sql
Expand All @@ -56,7 +59,7 @@ Examples:
return err
}
if dialect == "" {
return fmt.Errorf("--dialect flag is required (postgresql, mysql, sqlite, clickhouse, or googlesql)")
return fmt.Errorf("--dialect flag is required (postgresql, mysql, sqlite, clickhouse, googlesql, or mssql)")
}

schemaPath, err := cmd.Flags().GetString("schema")
Expand Down Expand Up @@ -117,8 +120,10 @@ Examples:
engine = config.EngineClickHouse
case "googlesql":
engine = config.EngineGoogleSQL
case "mssql", "sqlserver":
engine = config.EngineMSSQL
default:
return fmt.Errorf("unsupported dialect: %s (use postgresql, mysql, sqlite, clickhouse, or googlesql)", dialect)
return fmt.Errorf("unsupported dialect: %s (use postgresql, mysql, sqlite, clickhouse, googlesql, or mssql)", dialect)
}

sql := config.SQL{
Expand Down Expand Up @@ -160,7 +165,7 @@ Examples:
return nil
},
}
cmd.Flags().StringP("dialect", "d", "", "SQL dialect to use (postgresql, mysql, sqlite, clickhouse, or googlesql)")
cmd.Flags().StringP("dialect", "d", "", "SQL dialect to use (postgresql, mysql, sqlite, clickhouse, googlesql, or mssql)")
cmd.Flags().StringP("schema", "s", "", "path to the schema file")
cmd.Flags().BoolP("ast", "", false, "include the statement AST in the output")
return cmd
Expand Down
14 changes: 10 additions & 4 deletions internal/cmd/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/sqlc-dev/sqlc/internal/engine/clickhouse"
"github.com/sqlc-dev/sqlc/internal/engine/dolphin"
"github.com/sqlc-dev/sqlc/internal/engine/googlesql"
"github.com/sqlc-dev/sqlc/internal/engine/mssql"
"github.com/sqlc-dev/sqlc/internal/engine/postgresql"
"github.com/sqlc-dev/sqlc/internal/engine/sqlite"
"github.com/sqlc-dev/sqlc/internal/metadata"
Expand Down Expand Up @@ -59,15 +60,18 @@ Examples:
sqlc parse --dialect clickhouse queries.sql

# Parse GoogleSQL (BigQuery, Spanner)
sqlc parse --dialect googlesql queries.sql`,
sqlc parse --dialect googlesql queries.sql

# Parse SQL Server (T-SQL) SQL
sqlc parse --dialect mssql queries.sql`,
Args: cobra.MaximumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
dialect, err := cmd.Flags().GetString("dialect")
if err != nil {
return err
}
if dialect == "" {
return fmt.Errorf("--dialect flag is required (postgresql, mysql, sqlite, clickhouse, or googlesql)")
return fmt.Errorf("--dialect flag is required (postgresql, mysql, sqlite, clickhouse, googlesql, or mssql)")
}

// Determine input source
Expand Down Expand Up @@ -104,8 +108,10 @@ Examples:
parser = clickhouse.NewParser()
case "googlesql":
parser = googlesql.NewParser()
case "mssql", "sqlserver":
parser = mssql.NewParser()
default:
return fmt.Errorf("unsupported dialect: %s (use postgresql, mysql, sqlite, clickhouse, or googlesql)", dialect)
return fmt.Errorf("unsupported dialect: %s (use postgresql, mysql, sqlite, clickhouse, googlesql, or mssql)", dialect)
}

// Read the full source so each statement's name and command can be
Expand Down Expand Up @@ -149,6 +155,6 @@ Examples:
return nil
},
}
cmd.Flags().StringP("dialect", "d", "", "SQL dialect to use (postgresql, mysql, sqlite, clickhouse, or googlesql)")
cmd.Flags().StringP("dialect", "d", "", "SQL dialect to use (postgresql, mysql, sqlite, clickhouse, googlesql, or mssql)")
return cmd
}
10 changes: 8 additions & 2 deletions internal/compiler/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/sqlc-dev/sqlc/internal/engine/clickhouse"
"github.com/sqlc-dev/sqlc/internal/engine/dolphin"
"github.com/sqlc-dev/sqlc/internal/engine/googlesql"
"github.com/sqlc-dev/sqlc/internal/engine/mssql"
"github.com/sqlc-dev/sqlc/internal/engine/postgresql"
pganalyze "github.com/sqlc-dev/sqlc/internal/engine/postgresql/analyzer"
"github.com/sqlc-dev/sqlc/internal/engine/sqlite"
Expand Down Expand Up @@ -57,9 +58,10 @@ func NewCompiler(conf config.SQL, combo config.CombinedSettings, parserOpts opts
o(c)
}

// ClickHouse and GoogleSQL have no legacy analysis path to fall back to.
// ClickHouse, GoogleSQL and SQL Server have no legacy analysis path to
// fall back to.
switch conf.Engine {
case config.EngineClickHouse, config.EngineGoogleSQL:
case config.EngineClickHouse, config.EngineGoogleSQL, config.EngineMSSQL:
c.coreAnalysis = true
}
if c.coreAnalysis {
Expand Down Expand Up @@ -138,6 +140,10 @@ func (c *Compiler) initCore() error {
c.parser = googlesql.NewParser()
c.selector = newDefaultSelector()
dialect = googlesql.Dialect()
case config.EngineMSSQL:
c.parser = mssql.NewParser()
c.selector = newDefaultSelector()
dialect = mssql.Dialect()
default:
return fmt.Errorf("unknown engine: %s", c.conf.Engine)
}
Expand Down
1 change: 1 addition & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ const (
EngineSQLite Engine = "sqlite"
EngineClickHouse Engine = "clickhouse"
EngineGoogleSQL Engine = "googlesql"
EngineMSSQL Engine = "mssql"
)

type Config struct {
Expand Down
5 changes: 5 additions & 0 deletions internal/endtoend/testdata/analyze_basic/mssql/exec.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"command": "analyze",
"args": ["--dialect", "mssql", "--schema", "schema.sql", "query.sql"],
"contexts": ["base"]
}
2 changes: 2 additions & 0 deletions internal/endtoend/testdata/analyze_basic/mssql/query.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- name: ListAuthors :many
SELECT id, name, bio, royalties, created FROM authors;
7 changes: 7 additions & 0 deletions internal/endtoend/testdata/analyze_basic/mssql/schema.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
CREATE TABLE authors (
id BIGINT IDENTITY(1,1) PRIMARY KEY,
name NVARCHAR(100) NOT NULL,
bio NVARCHAR(MAX),
royalties DECIMAL(10,2) NOT NULL,
created DATETIME2 NOT NULL
);
44 changes: 44 additions & 0 deletions internal/endtoend/testdata/analyze_basic/mssql/stdout.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
[
{
"name": "ListAuthors",
"cmd": ":many",
"columns": [
{
"name": "id",
"data_type": "bigint",
"not_null": true,
"is_array": false,
"table": "authors"
},
{
"name": "name",
"data_type": "nvarchar",
"not_null": true,
"is_array": false,
"table": "authors"
},
{
"name": "bio",
"data_type": "nvarchar",
"not_null": false,
"is_array": false,
"table": "authors"
},
{
"name": "royalties",
"data_type": "decimal",
"not_null": true,
"is_array": false,
"table": "authors"
},
{
"name": "created",
"data_type": "datetime2",
"not_null": true,
"is_array": false,
"table": "authors"
}
],
"params": []
}
]
5 changes: 5 additions & 0 deletions internal/endtoend/testdata/analyze_dml/mssql/exec.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"command": "analyze",
"args": ["--dialect", "mssql", "--schema", "schema.sql", "query.sql"],
"contexts": ["base"]
}
11 changes: 11 additions & 0 deletions internal/endtoend/testdata/analyze_dml/mssql/query.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
-- name: CreateAuthor :one
INSERT INTO authors (name, bio) OUTPUT INSERTED.id VALUES (@name, @bio);

-- name: UpdateAuthorAlias :exec
UPDATE a SET name = @name FROM authors a WHERE a.id = @id;

-- name: UpdateBookPrices :exec
UPDATE b SET price = @price FROM books b JOIN authors a ON b.author_id = a.id WHERE a.name = @author;

-- name: DeleteBooksByAuthor :exec
DELETE b FROM books b INNER JOIN authors a ON b.author_id = a.id WHERE a.name = @name;
12 changes: 12 additions & 0 deletions internal/endtoend/testdata/analyze_dml/mssql/schema.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
CREATE TABLE authors (
id BIGINT IDENTITY(1,1) PRIMARY KEY,
name NVARCHAR(100) NOT NULL,
bio NVARCHAR(MAX)
);

CREATE TABLE books (
id BIGINT IDENTITY(1,1) PRIMARY KEY,
author_id BIGINT NOT NULL,
title NVARCHAR(200) NOT NULL,
price DECIMAL(10,2)
);
108 changes: 108 additions & 0 deletions internal/endtoend/testdata/analyze_dml/mssql/stdout.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
[
{
"name": "CreateAuthor",
"cmd": ":one",
"columns": [
{
"name": "id",
"data_type": "bigint",
"not_null": true,
"is_array": false,
"table": "authors"
}
],
"params": [
{
"number": 1,
"column": {
"name": "name",
"data_type": "nvarchar",
"not_null": true,
"is_array": false,
"table": "authors"
}
},
{
"number": 2,
"column": {
"name": "bio",
"data_type": "nvarchar",
"not_null": false,
"is_array": false,
"table": "authors"
}
}
]
},
{
"name": "UpdateAuthorAlias",
"cmd": ":exec",
"columns": [],
"params": [
{
"number": 1,
"column": {
"name": "name",
"data_type": "nvarchar",
"not_null": true,
"is_array": false,
"table": "authors"
}
},
{
"number": 2,
"column": {
"name": "id",
"data_type": "bigint",
"not_null": true,
"is_array": false,
"table": "authors"
}
}
]
},
{
"name": "UpdateBookPrices",
"cmd": ":exec",
"columns": [],
"params": [
{
"number": 1,
"column": {
"name": "price",
"data_type": "decimal",
"not_null": false,
"is_array": false,
"table": "books"
}
},
{
"number": 2,
"column": {
"name": "name",
"data_type": "nvarchar",
"not_null": true,
"is_array": false,
"table": "authors"
}
}
]
},
{
"name": "DeleteBooksByAuthor",
"cmd": ":exec",
"columns": [],
"params": [
{
"number": 1,
"column": {
"name": "name",
"data_type": "nvarchar",
"not_null": true,
"is_array": false,
"table": "authors"
}
}
]
}
]
5 changes: 5 additions & 0 deletions internal/endtoend/testdata/analyze_params/mssql/exec.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"command": "analyze",
"args": ["--dialect", "mssql", "--schema", "schema.sql", "query.sql"],
"contexts": ["base"]
}
5 changes: 5 additions & 0 deletions internal/endtoend/testdata/analyze_params/mssql/query.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-- name: GetAuthor :one
SELECT id, name, bio FROM authors WHERE id = @id;

-- name: FilterAuthors :many
SELECT id, name FROM authors WHERE name = @name AND royalties > @royalties;
7 changes: 7 additions & 0 deletions internal/endtoend/testdata/analyze_params/mssql/schema.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
CREATE TABLE authors (
id BIGINT IDENTITY(1,1) PRIMARY KEY,
name NVARCHAR(100) NOT NULL,
bio NVARCHAR(MAX),
royalties DECIMAL(10,2) NOT NULL,
created DATETIME2 NOT NULL
);
Loading
Loading