Add missing sqlite conditional functions.

This commit is contained in:
go-jet 2022-08-17 13:03:03 +02:00
parent bdbbc4d58d
commit f93636eab0
4 changed files with 251 additions and 1 deletions

View file

@ -342,7 +342,13 @@ func UNIX_TIMESTAMP(str StringExpression) TimestampExpression {
return jet.NewTimestampFunc("UNIX_TIMESTAMP", str)
}
//----------- Comparison operators ---------------//
// --------------- Conditional Expressions Functions -------------//
// COALESCE function returns the first of its arguments that is not null.
var COALESCE = jet.COALESCE
// NULLIF function returns a null value if value1 equals value2; otherwise it returns value1.
var NULLIF = jet.NULLIF
// EXISTS checks for existence of the rows in subQuery
var EXISTS = jet.EXISTS

View file

@ -1103,3 +1103,89 @@ func TestScanIntoCustomBaseTypes(t *testing.T) {
require.Equal(t, testutils.ToJSON(films), testutils.ToJSON(myFilms))
}
func TestConditionalFunctions(t *testing.T) {
stmt := SELECT(
EXISTS(
Film.SELECT(Film.FilmID).WHERE(Film.RentalDuration.GT(Int(100))),
).AS("exists"),
CASE(Film.Length.GT(Int(120))).
WHEN(Bool(true)).THEN(String("long film")).
ELSE(String("short film")).AS("case"),
COALESCE(Film.Description, String("none")).AS("coalesce"),
NULLIF(Film.ReleaseYear, Int(200)).AS("null_if"),
GREATEST(Film.RentalDuration, Int(4), Int(5)).AS("greatest"),
LEAST(Film.RentalDuration, Int(7), Int(6)).AS("least"),
).FROM(
Film,
).WHERE(
Film.FilmID.LT(Int(5)),
).ORDER_BY(
Film.FilmID,
)
testutils.AssertDebugStatementSql(t, stmt, `
SELECT (EXISTS (
SELECT film.film_id AS "film.film_id"
FROM dvds.film
WHERE film.rental_duration > 100
)) AS "exists",
(CASE (film.length > 120) WHEN TRUE THEN 'long film' ELSE 'short film' END) AS "case",
COALESCE(film.description, 'none') AS "coalesce",
NULLIF(film.release_year, 200) AS "null_if",
GREATEST(film.rental_duration, 4, 5) AS "greatest",
LEAST(film.rental_duration, 7, 6) AS "least"
FROM dvds.film
WHERE film.film_id < 5
ORDER BY film.film_id;
`)
var res []struct {
Exists string
Case string
Coalesce string
NullIf string
Greatest string
Least string
}
err := stmt.Query(db, &res)
require.NoError(t, err)
testutils.AssertJSON(t, res, `
[
{
"Exists": "0",
"Case": "short film",
"Coalesce": "A Epic Drama of a Feminist And a Mad Scientist who must Battle a Teacher in The Canadian Rockies",
"NullIf": "2006",
"Greatest": "6",
"Least": "6"
},
{
"Exists": "0",
"Case": "short film",
"Coalesce": "A Astounding Epistle of a Database Administrator And a Explorer who must Find a Car in Ancient China",
"NullIf": "2006",
"Greatest": "5",
"Least": "3"
},
{
"Exists": "0",
"Case": "short film",
"Coalesce": "A Astounding Reflection of a Lumberjack And a Car who must Sink a Lumberjack in A Baloon Factory",
"NullIf": "2006",
"Greatest": "7",
"Least": "6"
},
{
"Exists": "0",
"Case": "short film",
"Coalesce": "A Fanciful Documentary of a Frisbee And a Lumberjack who must Chase a Monkey in A Shark Tank",
"NullIf": "2006",
"Greatest": "5",
"Least": "5"
}
]
`)
}

View file

@ -2723,6 +2723,92 @@ func TestScanUsingConn(t *testing.T) {
})
}
func TestConditionalFunctions(t *testing.T) {
stmt := SELECT(
EXISTS(
Film.SELECT(Film.FilmID).WHERE(Film.RentalDuration.GT(Int(100))),
).AS("exists"),
CASE(Film.Length.GT(Int(120))).
WHEN(Bool(true)).THEN(String("long film")).
ELSE(String("short film")).AS("case"),
COALESCE(Film.Description, String("none")).AS("coalesce"),
NULLIF(Film.ReleaseYear, Int(200)).AS("null_if"),
GREATEST(Film.RentalDuration, Int(4), Int(5)).AS("greatest"),
LEAST(Film.RentalDuration, Int(7), Int(6)).AS("least"),
).FROM(
Film,
).WHERE(
Film.FilmID.LT(Int(5)),
).ORDER_BY(
Film.FilmID,
)
testutils.AssertDebugStatementSql(t, stmt, `
SELECT (EXISTS (
SELECT film.film_id AS "film.film_id"
FROM dvds.film
WHERE film.rental_duration > 100
)) AS "exists",
(CASE (film.length > 120) WHEN TRUE::boolean THEN 'long film'::text ELSE 'short film'::text END) AS "case",
COALESCE(film.description, 'none'::text) AS "coalesce",
NULLIF(film.release_year, 200) AS "null_if",
GREATEST(film.rental_duration, 4, 5) AS "greatest",
LEAST(film.rental_duration, 7, 6) AS "least"
FROM dvds.film
WHERE film.film_id < 5
ORDER BY film.film_id;
`)
var res []struct {
Exists bool
Case string
Coalesce string
NullIf string
Greatest string
Least string
}
err := stmt.Query(db, &res)
require.NoError(t, err)
testutils.AssertJSON(t, res, `
[
{
"Exists": false,
"Case": "short film",
"Coalesce": "A Epic Drama of a Feminist And a Mad Scientist who must Battle a Teacher in The Canadian Rockies",
"NullIf": "2006",
"Greatest": "6",
"Least": "6"
},
{
"Exists": false,
"Case": "short film",
"Coalesce": "A Astounding Epistle of a Database Administrator And a Explorer who must Find a Car in Ancient China",
"NullIf": "2006",
"Greatest": "5",
"Least": "3"
},
{
"Exists": false,
"Case": "short film",
"Coalesce": "A Astounding Reflection of a Lumberjack And a Car who must Sink a Lumberjack in A Baloon Factory",
"NullIf": "2006",
"Greatest": "7",
"Least": "6"
},
{
"Exists": false,
"Case": "short film",
"Coalesce": "A Fanciful Documentary of a Frisbee And a Lumberjack who must Chase a Monkey in A Shark Tank",
"NullIf": "2006",
"Greatest": "5",
"Least": "5"
}
]
`)
}
var customer0 = model.Customer{
CustomerID: 1,
StoreID: 1,

View file

@ -810,3 +810,75 @@ func TestScanNumericToNumber(t *testing.T) {
require.Equal(t, number.Float32, float32(1.234568e+09))
require.Equal(t, number.Float64, float64(1.234567890111e+09))
}
func TestConditionalFunctions(t *testing.T) {
stmt := SELECT(
EXISTS(
Film.SELECT(Film.FilmID).WHERE(Film.RentalDuration.GT(Int(5))),
).AS("exists"),
CASE(Film.Length.GT(Int(120))).
WHEN(Bool(true)).THEN(String("long film")).
ELSE(String("short film")).AS("case"),
COALESCE(Film.Description, String("none")).AS("coalesce"),
NULLIF(Film.ReleaseYear, Int(200)).AS("null_if"),
).FROM(
Film,
).WHERE(
Film.FilmID.LT(Int(5)),
).ORDER_BY(
Film.FilmID,
)
testutils.AssertDebugStatementSql(t, stmt, `
SELECT (EXISTS (
SELECT film.film_id AS "film.film_id"
FROM film
WHERE film.rental_duration > 5
)) AS "exists",
(CASE (film.length > 120) WHEN TRUE THEN 'long film' ELSE 'short film' END) AS "case",
COALESCE(film.description, 'none') AS "coalesce",
NULLIF(film.release_year, 200) AS "null_if"
FROM film
WHERE film.film_id < 5
ORDER BY film.film_id;
`)
var res []struct {
Exists bool
Case string
Coalesce string
NullIf string
}
err := stmt.Query(db, &res)
require.NoError(t, err)
testutils.AssertJSON(t, res, `
[
{
"Exists": true,
"Case": "short film",
"Coalesce": "A Epic Drama of a Feminist And a Mad Scientist who must Battle a Teacher in The Canadian Rockies",
"NullIf": "2006"
},
{
"Exists": true,
"Case": "short film",
"Coalesce": "A Astounding Epistle of a Database Administrator And a Explorer who must Find a Car in Ancient China",
"NullIf": "2006"
},
{
"Exists": true,
"Case": "short film",
"Coalesce": "A Astounding Reflection of a Lumberjack And a Car who must Sink a Lumberjack in A Baloon Factory",
"NullIf": "2006"
},
{
"Exists": true,
"Case": "short film",
"Coalesce": "A Fanciful Documentary of a Frisbee And a Lumberjack who must Chase a Monkey in A Shark Tank",
"NullIf": "2006"
}
]
`)
}