Fix query interval definitions for date add/sub
This commit is contained in:
@@ -236,7 +236,10 @@ func (n interval) ToAST() (out *ASTNode) {
|
||||
return &ASTNode{
|
||||
Ref: "interval",
|
||||
Args: ASTNodeSet{
|
||||
{Symbol: n.unit},
|
||||
// @todo consider introducing a new concept on the ASTNode to cover
|
||||
// system defined symbols/keywords. This is a temporary solutions
|
||||
// to fix reporting interval definitions; it should eventually be reworked
|
||||
{Value: MakeValueOf("String", n.unit)},
|
||||
{Value: MakeValueOf("Number", n.value)},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
|
||||
"github.com/cortezaproject/corteza-server/pkg/errors"
|
||||
|
||||
"github.com/cortezaproject/corteza-server/pkg/dal"
|
||||
|
||||
@@ -63,17 +63,41 @@ var (
|
||||
},
|
||||
},
|
||||
|
||||
"interval": {
|
||||
Handler: func(args ...exp.Expression) exp.Expression {
|
||||
// The problem here is that PGSQL, to my findings, doesn't have functions to add/sub dates
|
||||
// like MySQL for example.
|
||||
//
|
||||
// We need to construct an expression in the lines of `INTERVAL 'N UNIT'` which
|
||||
// then becomes, for example, d + INTERVAL 'N UNIT'.
|
||||
//
|
||||
// The problem #2 is that we can't just use value placeholders in string literals
|
||||
// nor is there a 2 arg function to make an interval. There is a make_interval function
|
||||
// but that one won't do.
|
||||
//
|
||||
// So...
|
||||
// (? || 'S') makes the interval label a plural because MySQL uses singular and that
|
||||
// is what QL supports. PgSQL uses plural, such as years, months, and days.
|
||||
//
|
||||
// The rest of the expression is just to construct the string which can then be casted to INTERVAL
|
||||
// which can then be used in date math, which is done with regular math operators.
|
||||
return exp.NewLiteralExpression("(?::INTEGER || ' ' || (? || 'S'))::INTERVAL", args[1], args[0])
|
||||
},
|
||||
},
|
||||
|
||||
"date_add": {
|
||||
Handler: func(args ...exp.Expression) exp.Expression {
|
||||
return exp.NewLiteralExpression("(? + ?)", args[0], args[1])
|
||||
},
|
||||
},
|
||||
|
||||
"date_sub": {
|
||||
Handler: func(args ...exp.Expression) exp.Expression {
|
||||
return exp.NewLiteralExpression("(? - ?)", args[0], args[1])
|
||||
},
|
||||
},
|
||||
|
||||
// functions currently unsupported in PostgreSQL store backend
|
||||
//"DATE_ADD": {
|
||||
// Handler: func(args ...exp.Expression) exp.Expression {
|
||||
// return exp.NewLiteralExpression("")
|
||||
// },
|
||||
//},
|
||||
//"DATE_SUB": {
|
||||
// Handler: func(args ...exp.Expression) exp.Expression {
|
||||
// return exp.NewLiteralExpression("")
|
||||
// },
|
||||
//},
|
||||
//"STD": {
|
||||
// Handler: func(args ...exp.Expression) exp.Expression {
|
||||
// return exp.NewLiteralExpression("")
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/cortezaproject/corteza-server/pkg/ql"
|
||||
"github.com/doug-martin/goqu/v9"
|
||||
"github.com/doug-martin/goqu/v9/exp"
|
||||
)
|
||||
|
||||
@@ -117,6 +118,38 @@ var (
|
||||
},
|
||||
},
|
||||
|
||||
"interval": {
|
||||
Handler: func(args ...exp.Expression) exp.Expression {
|
||||
|
||||
// The problem here is similar to the one with PgSQL... but more complicated...
|
||||
// The interval duration identifiers are keywords and can't be bound via value placeholders.
|
||||
// This forces us to interpolate the thing when building the literal expression below.
|
||||
//
|
||||
// Since goqu doesn't let me get the raw value of the expression... I was forced
|
||||
// to do this calamity
|
||||
_, aa, err := goqu.Select(args[0]).ToSQL()
|
||||
if err != nil {
|
||||
// This error should never occur
|
||||
panic(err)
|
||||
}
|
||||
intv := aa[0].(string)
|
||||
|
||||
return exp.NewLiteralExpression(fmt.Sprintf("INTERVAL ? %s", intv), args[1])
|
||||
},
|
||||
},
|
||||
|
||||
"date_add": {
|
||||
Handler: func(args ...exp.Expression) exp.Expression {
|
||||
return exp.NewSQLFunctionExpression("DATE_ADD", args[0], args[1])
|
||||
},
|
||||
},
|
||||
|
||||
"date_sub": {
|
||||
Handler: func(args ...exp.Expression) exp.Expression {
|
||||
return exp.NewSQLFunctionExpression("DATE_SUB", args[0], args[1])
|
||||
},
|
||||
},
|
||||
|
||||
// @todo better negation?
|
||||
"like": {
|
||||
Handler: func(args ...exp.Expression) exp.Expression {
|
||||
|
||||
Reference in New Issue
Block a user