diff --git a/docs/generated/sql/functions.md b/docs/generated/sql/functions.md index 071d5890751a..3fd58113c9ab 100644 --- a/docs/generated/sql/functions.md +++ b/docs/generated/sql/functions.md @@ -637,6 +637,14 @@ has no relationship with the commit order of concurrent transactions.

Stable statement_timestamp() → timestamptz

Returns the start time of the current statement.

Stable +strftime(input: date, extract_format: string) → string

From input, extracts and formats the time as identified in extract_format using standard strftime notation (though not all formatting is supported).

+
Immutable +strftime(input: timestamp, extract_format: string) → string

From input, extracts and formats the time as identified in extract_format using standard strftime notation (though not all formatting is supported).

+
Immutable +strftime(input: timestamptz, extract_format: string) → string

From input, extracts and formats the time as identified in extract_format using standard strftime notation (though not all formatting is supported).

+
Immutable +strptime(input: string, format: string) → timestamptz

Returns input as a timestamptz using format (which uses standard strptime formatting).

+
Immutable timeofday() → string

Returns the current system time on one of the cluster nodes as a string.

Stable timezone(timezone: string, time: time) → timetz

Treat given time without time zone as located in the specified time zone.

diff --git a/pkg/sql/logictest/testdata/logic_test/pg_catalog b/pkg/sql/logictest/testdata/logic_test/pg_catalog index 9e335baf9ba0..35b295cefc8a 100644 --- a/pkg/sql/logictest/testdata/logic_test/pg_catalog +++ b/pkg/sql/logictest/testdata/logic_test/pg_catalog @@ -4640,7 +4640,7 @@ FROM pg_proc p JOIN pg_type t ON t.typinput = p.oid WHERE t.typname = '_int4' ---- -2006 array_in array_in +2010 array_in array_in ## #16285 ## int2vectors should be 0-indexed diff --git a/pkg/sql/sem/builtins/builtins.go b/pkg/sql/sem/builtins/builtins.go index 119092a20346..03e6781a432d 100644 --- a/pkg/sql/sem/builtins/builtins.go +++ b/pkg/sql/sem/builtins/builtins.go @@ -2403,84 +2403,11 @@ var regularBuiltins = map[string]builtinDefinition{ // Timestamp/Date functions. - "experimental_strftime": makeBuiltin( - tree.FunctionProperties{ - Category: builtinconstants.CategoryDateAndTime, - }, - tree.Overload{ - Types: tree.ArgTypes{{"input", types.Timestamp}, {"extract_format", types.String}}, - ReturnType: tree.FixedReturnType(types.String), - Fn: func(_ *eval.Context, args tree.Datums) (tree.Datum, error) { - fromTime := args[0].(*tree.DTimestamp).Time - format := string(tree.MustBeDString(args[1])) - t, err := strtime.Strftime(fromTime, format) - if err != nil { - return nil, err - } - return tree.NewDString(t), nil - }, - Info: "From `input`, extracts and formats the time as identified in `extract_format` " + - "using standard `strftime` notation (though not all formatting is supported).", - Volatility: volatility.Immutable, - }, - tree.Overload{ - Types: tree.ArgTypes{{"input", types.Date}, {"extract_format", types.String}}, - ReturnType: tree.FixedReturnType(types.String), - Fn: func(_ *eval.Context, args tree.Datums) (tree.Datum, error) { - fromTime, err := args[0].(*tree.DDate).ToTime() - if err != nil { - return nil, err - } - format := string(tree.MustBeDString(args[1])) - t, err := strtime.Strftime(fromTime, format) - if err != nil { - return nil, err - } - return tree.NewDString(t), nil - }, - Info: "From `input`, extracts and formats the time as identified in `extract_format` " + - "using standard `strftime` notation (though not all formatting is supported).", - Volatility: volatility.Immutable, - }, - tree.Overload{ - Types: tree.ArgTypes{{"input", types.TimestampTZ}, {"extract_format", types.String}}, - ReturnType: tree.FixedReturnType(types.String), - Fn: func(_ *eval.Context, args tree.Datums) (tree.Datum, error) { - fromTime := args[0].(*tree.DTimestampTZ).Time - format := string(tree.MustBeDString(args[1])) - t, err := strtime.Strftime(fromTime, format) - if err != nil { - return nil, err - } - return tree.NewDString(t), nil - }, - Info: "From `input`, extracts and formats the time as identified in `extract_format` " + - "using standard `strftime` notation (though not all formatting is supported).", - Volatility: volatility.Immutable, - }, - ), + "strftime": strftimeImpl(), + "experimental_strftime": strftimeImpl(), - "experimental_strptime": makeBuiltin( - tree.FunctionProperties{ - Category: builtinconstants.CategoryDateAndTime, - }, - tree.Overload{ - Types: tree.ArgTypes{{"input", types.String}, {"format", types.String}}, - ReturnType: tree.FixedReturnType(types.TimestampTZ), - Fn: func(_ *eval.Context, args tree.Datums) (tree.Datum, error) { - toParse := string(tree.MustBeDString(args[0])) - format := string(tree.MustBeDString(args[1])) - t, err := strtime.Strptime(toParse, format) - if err != nil { - return nil, err - } - return tree.MakeDTimestampTZ(t.UTC(), time.Microsecond) - }, - Info: "Returns `input` as a timestamptz using `format` (which uses standard " + - "`strptime` formatting).", - Volatility: volatility.Immutable, - }, - ), + "strptime": strptimeImpl(), + "experimental_strptime": strptimeImpl(), "to_char": makeBuiltin( defProps(), @@ -7568,6 +7495,89 @@ func generateRandomUUID4Impl() builtinDefinition { ) } +func strftimeImpl() builtinDefinition { + return makeBuiltin( + tree.FunctionProperties{ + Category: builtinconstants.CategoryDateAndTime, + }, + tree.Overload{ + Types: tree.ArgTypes{{"input", types.Timestamp}, {"extract_format", types.String}}, + ReturnType: tree.FixedReturnType(types.String), + Fn: func(_ *eval.Context, args tree.Datums) (tree.Datum, error) { + fromTime := args[0].(*tree.DTimestamp).Time + format := string(tree.MustBeDString(args[1])) + t, err := strtime.Strftime(fromTime, format) + if err != nil { + return nil, err + } + return tree.NewDString(t), nil + }, + Info: "From `input`, extracts and formats the time as identified in `extract_format` " + + "using standard `strftime` notation (though not all formatting is supported).", + Volatility: volatility.Immutable, + }, + tree.Overload{ + Types: tree.ArgTypes{{"input", types.Date}, {"extract_format", types.String}}, + ReturnType: tree.FixedReturnType(types.String), + Fn: func(_ *eval.Context, args tree.Datums) (tree.Datum, error) { + fromTime, err := args[0].(*tree.DDate).ToTime() + if err != nil { + return nil, err + } + format := string(tree.MustBeDString(args[1])) + t, err := strtime.Strftime(fromTime, format) + if err != nil { + return nil, err + } + return tree.NewDString(t), nil + }, + Info: "From `input`, extracts and formats the time as identified in `extract_format` " + + "using standard `strftime` notation (though not all formatting is supported).", + Volatility: volatility.Immutable, + }, + tree.Overload{ + Types: tree.ArgTypes{{"input", types.TimestampTZ}, {"extract_format", types.String}}, + ReturnType: tree.FixedReturnType(types.String), + Fn: func(_ *eval.Context, args tree.Datums) (tree.Datum, error) { + fromTime := args[0].(*tree.DTimestampTZ).Time + format := string(tree.MustBeDString(args[1])) + t, err := strtime.Strftime(fromTime, format) + if err != nil { + return nil, err + } + return tree.NewDString(t), nil + }, + Info: "From `input`, extracts and formats the time as identified in `extract_format` " + + "using standard `strftime` notation (though not all formatting is supported).", + Volatility: volatility.Immutable, + }, + ) +} + +func strptimeImpl() builtinDefinition { + return makeBuiltin( + tree.FunctionProperties{ + Category: builtinconstants.CategoryDateAndTime, + }, + tree.Overload{ + Types: tree.ArgTypes{{"input", types.String}, {"format", types.String}}, + ReturnType: tree.FixedReturnType(types.TimestampTZ), + Fn: func(_ *eval.Context, args tree.Datums) (tree.Datum, error) { + toParse := string(tree.MustBeDString(args[0])) + format := string(tree.MustBeDString(args[1])) + t, err := strtime.Strptime(toParse, format) + if err != nil { + return nil, err + } + return tree.MakeDTimestampTZ(t.UTC(), time.Microsecond) + }, + Info: "Returns `input` as a timestamptz using `format` (which uses standard " + + "`strptime` formatting).", + Volatility: volatility.Immutable, + }, + ) +} + func uuidV4Impl() builtinDefinition { return makeBuiltin( tree.FunctionProperties{