Skip to content
Open
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"command": "analyze",
"args": ["--dialect", "duckdb", "--schema", "schema.sql", "query.sql"],
"contexts": ["base"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- name: ListItems :many
SELECT id, name FROM items;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
INSTALL spatial;
LOAD spatial;
SET threads = 2;

CREATE TABLE items (id INTEGER NOT NULL, name VARCHAR NOT NULL);
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[
{
"name": "ListItems",
"cmd": ":many",
"columns": [
{
"name": "id",
"type": {
"name": "integer"
},
"table": "items"
},
{
"name": "name",
"type": {
"name": "varchar"
},
"table": "items"
}
],
"params": []
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"command": "analyze",
"args": ["--dialect", "duckdb", "--schema", "schema.sql", "query.sql"],
"contexts": ["base"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-- name: ListItems :many
SELECT id, name FROM items;

-- name: ExportItems :exec
COPY (SELECT id, name FROM items) TO 'items.parquet' (FORMAT PARQUET);
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
CREATE TABLE items (id INTEGER NOT NULL, name VARCHAR NOT NULL);
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Error: error parsing queries: query.sql:5:1: query ExportItems: statement is not supported by the duckdb engine
32 changes: 31 additions & 1 deletion internal/engine/duckdb/parse.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package duckdb

import (
"bytes"
"context"
"errors"
"fmt"
"io"
"strings"

"github.com/sqlc-dev/darkwing/parser"

"github.com/sqlc-dev/sqlc/internal/metadata"
"github.com/sqlc-dev/sqlc/internal/source"
"github.com/sqlc-dev/sqlc/internal/sql/ast"
"github.com/sqlc-dev/sqlc/internal/sql/sqlerr"
Expand All @@ -23,7 +27,11 @@ type Parser struct{}
// starts where the previous one ended — so a statement's span covers the
// comments before it, which is where the sqlc query annotation lives.
func (p *Parser) Parse(r io.Reader) ([]ast.Statement, error) {
stmts, err := parser.Parse(context.Background(), r)
src, err := io.ReadAll(r)
if err != nil {
return nil, err
}
stmts, err := parser.Parse(context.Background(), bytes.NewReader(src))
if err != nil {
var perr *parser.Error
if errors.As(err, &perr) {
Expand All @@ -45,6 +53,21 @@ func (p *Parser) Parse(r io.Reader) ([]ast.Statement, error) {
converter := &cc{}
node := converter.convert(stmt)
if _, ok := node.(*ast.TODO); ok {
// A statement with no query annotation (INSTALL, LOAD, SET in a
// schema file) is skipped. A statement with one is a query that
// the user expects sqlc to generate: dropping it would hide the
// missing method, so report it.
span := string(src[stmt.Pos():stmt.End()])
name, _, merr := metadata.ParseQueryNameAndType(span, metadata.CommentSyntax(p.CommentSyntax()))
if merr != nil {
return nil, &sqlerr.Error{Message: merr.Error(), Location: stmt.Pos() + leadingSpace(span)}
}
if name != "" {
return nil, &sqlerr.Error{
Message: fmt.Sprintf("query %s: statement is not supported by the duckdb engine", name),
Location: stmt.Pos() + leadingSpace(span),
}
}
continue
}
out = append(out, ast.Statement{
Expand All @@ -58,6 +81,13 @@ func (p *Parser) Parse(r io.Reader) ([]ast.Statement, error) {
return out, nil
}

// leadingSpace returns the length of the whitespace before the first
// character of s, so an error points at the annotation and not at the blank
// lines that follow the previous statement.
func leadingSpace(s string) int {
return len(s) - len(strings.TrimLeft(s, " \t\r\n"))
}

// https://duckdb.org/docs/stable/sql/introduction#comments
func (p *Parser) CommentSyntax() source.CommentSyntax {
return source.CommentSyntax{
Expand Down
Loading