Skip to content

Commit 4cf4af7

Browse files
committed
chore(embedded/sql): add support for SELECT FROM VALUES syntax
Signed-off-by: Stefano Scafiti <[email protected]>
1 parent 0ce2146 commit 4cf4af7

File tree

4 files changed

+386
-268
lines changed

4 files changed

+386
-268
lines changed

embedded/sql/engine_test.go

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3073,6 +3073,86 @@ func TestQuery(t *testing.T) {
30733073
err = r.Close()
30743074
require.NoError(t, err)
30753075
})
3076+
3077+
t.Run("query from values", func(t *testing.T) {
3078+
_, err := engine.queryAll(
3079+
context.Background(),
3080+
nil,
3081+
`
3082+
SELECT * FROM (
3083+
VALUES
3084+
(1, 'foo'),
3085+
(2, true)
3086+
)
3087+
`,
3088+
nil,
3089+
)
3090+
require.ErrorContains(t, err, "cannot match types VARCHAR and BOOLEAN")
3091+
3092+
_, err = engine.queryAll(
3093+
context.Background(),
3094+
nil,
3095+
`
3096+
SELECT * FROM (
3097+
VALUES
3098+
(@a),
3099+
(@b)
3100+
)
3101+
`,
3102+
map[string]interface{}{"a": 1, "b": "test"},
3103+
)
3104+
require.ErrorContains(t, err, "cannot match types INTEGER and VARCHAR")
3105+
3106+
rows, err := engine.queryAll(
3107+
context.Background(),
3108+
nil,
3109+
`
3110+
SELECT * FROM (
3111+
VALUES
3112+
(1, 'foo', true, 1.22, '2024-11-29'::TIMESTAMP),
3113+
(2, 'bar', false, 1.25, '1996-09-11'::TIMESTAMP),
3114+
(3, 'baz', true, 2.50, '2000-01-01'::TIMESTAMP),
3115+
(4, 'qux', false, 3.75, '2010-05-15'::TIMESTAMP),
3116+
(5, 'quux', true, 0.99, '2022-12-31'::TIMESTAMP)
3117+
)
3118+
`,
3119+
nil,
3120+
)
3121+
require.NoError(t, err)
3122+
require.Len(t, rows, 5)
3123+
3124+
expectedRows := []*Row{
3125+
{
3126+
ValuesByPosition: []TypedValue{
3127+
&Integer{1}, &Varchar{"foo"}, &Bool{true}, &Float64{1.22}, &Timestamp{time.Date(2024, 11, 29, 0, 0, 0, 0, time.UTC)},
3128+
},
3129+
},
3130+
{
3131+
ValuesByPosition: []TypedValue{
3132+
&Integer{2}, &Varchar{"bar"}, &Bool{false}, &Float64{1.25}, &Timestamp{time.Date(1996, 9, 11, 0, 0, 0, 0, time.UTC)},
3133+
},
3134+
},
3135+
{
3136+
ValuesByPosition: []TypedValue{
3137+
&Integer{3}, &Varchar{"baz"}, &Bool{true}, &Float64{2.50}, &Timestamp{time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)},
3138+
},
3139+
},
3140+
{
3141+
ValuesByPosition: []TypedValue{
3142+
&Integer{4}, &Varchar{"qux"}, &Bool{false}, &Float64{3.75}, &Timestamp{time.Date(2010, 5, 15, 0, 0, 0, 0, time.UTC)},
3143+
},
3144+
},
3145+
{
3146+
ValuesByPosition: []TypedValue{
3147+
&Integer{5}, &Varchar{"quux"}, &Bool{true}, &Float64{0.99}, &Timestamp{time.Date(2022, 12, 31, 0, 0, 0, 0, time.UTC)},
3148+
},
3149+
},
3150+
}
3151+
3152+
for i, row := range rows {
3153+
require.Equal(t, expectedRows[i].ValuesByPosition, row.ValuesByPosition)
3154+
}
3155+
})
30763156
}
30773157

30783158
func TestJSON(t *testing.T) {

embedded/sql/sql_grammar.y

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,11 @@ ds:
804804
$1.as = $3
805805
$$ = $1
806806
}
807+
|
808+
'(' VALUES rows ')'
809+
{
810+
$$ = &valuesDataSource{inferTypes: true, rows: $3}
811+
}
807812
|
808813
'(' dqlstmt ')' opt_as
809814
{

0 commit comments

Comments
 (0)