From 046855cb30842df0b833851d17131925cce77240 Mon Sep 17 00:00:00 2001 From: Denis Arh Date: Fri, 18 Mar 2022 20:38:34 +0100 Subject: [PATCH] Fix date/time functions in record queries --- store/postgres/sql_functions.go | 6 ++++++ store/rdbms/compose_records.go | 2 ++ store/sqlite3/sql_functions.go | 2 ++ store/tests/compose_records_test.go | 3 +++ 4 files changed, 13 insertions(+) diff --git a/store/postgres/sql_functions.go b/store/postgres/sql_functions.go index 122794a3a..afb02d542 100644 --- a/store/postgres/sql_functions.go +++ b/store/postgres/sql_functions.go @@ -7,6 +7,7 @@ import ( "github.com/cortezaproject/corteza-server/pkg/ql" "github.com/cortezaproject/corteza-server/pkg/qlng" "github.com/cortezaproject/corteza-server/store/rdbms" + "github.com/davecgh/go-spew/spew" ) var ( @@ -38,13 +39,18 @@ func sqlASTFormatter(n *qlng.ASTNode) rdbms.HandlerSig { } func sqlFunctionHandler(f ql.Function) (ql.ASTNode, error) { + spew.Dump(f) switch strings.ToUpper(f.Name) { case "QUARTER", "YEAR": return ql.MakeFormattedNode(fmt.Sprintf("EXTRACT(%s FROM %%s::date)", f.Name), f.Arguments...), nil case "DATE_FORMAT": return ql.MakeReplacedFormattedNode("TO_CHAR(%s, %s)", translateDateFormatParams, f.Arguments...), nil + case "TIMESTAMP": + return ql.MakeFormattedNode("TIMESTAMPTZ(%s::TIMESTAMPTZ)", f.Arguments...), nil case "DATE": return ql.MakeFormattedNode("%s::DATE", f.Arguments...), nil + case "TIME": + return ql.MakeFormattedNode("DATE_TRUNC('second', %s::TIME)::TIME", f.Arguments...), nil case "DATE_ADD", "DATE_SUB", "STD": return nil, fmt.Errorf("%q function is currently unsupported in PostgreSQL store backend", f.Name) } diff --git a/store/rdbms/compose_records.go b/store/rdbms/compose_records.go index 727101f4b..3068d892a 100644 --- a/store/rdbms/compose_records.go +++ b/store/rdbms/compose_records.go @@ -540,6 +540,7 @@ func (s Store) convertComposeRecordFilter(m *types.Module, f types.RecordFilter) // Resolve all identifiers found in the query // into their table/column counterparts fp.OnIdent = identResolver + fp.OnFunction = s.SqlFunctionHandler if fn, err = fp.ParseExpression(f.Query); err != nil { return @@ -559,6 +560,7 @@ func (s Store) convertComposeRecordFilter(m *types.Module, f types.RecordFilter) // Resolve all identifiers found in sort // into their table/column counterparts sp.OnIdent = identResolver + sp.OnFunction = s.SqlFunctionHandler if _, err = sp.ParseColumns(f.Sort.String()); err != nil { return diff --git a/store/sqlite3/sql_functions.go b/store/sqlite3/sql_functions.go index f3d799021..3be24662a 100644 --- a/store/sqlite3/sql_functions.go +++ b/store/sqlite3/sql_functions.go @@ -117,6 +117,8 @@ func sqlFunctionHandler(f ql.Function) (ql.ASTNode, error) { return ql.MakeFormattedNode("STRFTIME('%%Y', %s)", f.Arguments...), nil case "NOW": return ql.MakeFormattedNode("DATE('now')", f.Arguments...), nil + case "TIMESTAMP", "DATETIME": + return ql.MakeFormattedNode("DATETIME(%s)", f.Arguments...), nil case "DATE_FORMAT": if len(f.Arguments) != 2 { return nil, fmt.Errorf("expecting exactly two arguments for DATE_FORMAT function") diff --git a/store/tests/compose_records_test.go b/store/tests/compose_records_test.go index 4e3378dbc..ea84f95c3 100644 --- a/store/tests/compose_records_test.go +++ b/store/tests/compose_records_test.go @@ -1665,8 +1665,11 @@ func testComposeRecords(t *testing.T, s store.ComposeRecords) { result string }{ {"datetime1 = '2020-10-02T00:00:02'", "1002"}, + {"TIMESTAMP(datetime1) = TIMESTAMP('2020-10-02T00:00:02')", "1002"}, {"date1 = '2020-10-02'", "2002"}, + {"DATE(date1) = DATE('2020-10-02')", "2002"}, {"time1 = '02:00:00'", "3002"}, + {"TIME(time1) = TIME('02:00:00')", "3002"}, {"datetime1 <= '2020-10-02T00:00:02'", "1001;1002"}, {"date1 <= '2020-10-02'", "2001;2002"}, {"time1 <= '02:00:00'", "3001;3002"},