Documentation
¶
Overview ¶
Package functions holds SQL-value operations that don't need connection/session state: checked integer arithmetic, numeric + bitwise operators with SQL semantics, type-coercion helpers used by scalar-function arguments, and (in future PRs) the scalar function dispatcher + protoreflect <-> driver.Value marshaling.
Mirrors Java's fdb-relational-core/recordlayer/query/functions/ package plus the arithmetic helpers in ArithmeticValue. PhysicalOperator. All functions here are pure — no *Session, no *EmbeddedConnection — so the naive planner, Cascades planner, and any future frontend can call them uniformly.
This is the first move of RFC-021 Phase 1c1. Future commits add castValue, convertToProtoValue, protoValueToDriver and the scalar function core.
Index ¶
- Constants
- func AddInt64Checked(a, b int64) (int64, bool)
- func ApplyBitOp(left, right any, op string) (any, error)
- func ApplyMathOp(left, right any, op string) (any, error)
- func CastValue(v any, typeName string) (any, error)
- func CompareValues(a, b driver.Value) int
- func ConvertToProtoValue(fd protoreflect.FieldDescriptor, val any) (protoreflect.Value, error)
- func FormatDate(t time.Time) string
- func FormatTimestamp(t time.Time) string
- func FullIdToName(fid antlrgen.IFullIdContext) string
- func IsTruthy(v any) bool
- func LikeMatch(pattern, s string, escape rune) bool
- func LiteralMatchesPKKind(val any, kind protoreflect.Kind) bool
- func MulInt64Checked(a, b int64) (int64, bool)
- func ParseTimestamp(s string) (time.Time, bool)
- func ProtoValueToDriver(fd protoreflect.FieldDescriptor, v protoreflect.Value) driver.Value
- func ResolveQualifiedTableName(dottedName, schemaName string) (string, error)
- func StripIdentifierQuotes(s string) string
- func StripStringLiteralQuotes(s string) string
- func SubInt64Checked(a, b int64) (int64, bool)
- func ToFloat64(v any) (float64, bool)
- func ToIntegerArg(v any, funcName, argName string) (int64, error)
Constants ¶
const DateLayout = "2006-01-02"
DateLayout is the canonical ISO 8601 format used for DATE values.
const TimestampLayout = "2006-01-02 15:04:05"
TimestampLayout is the canonical ISO 8601 format used for TIMESTAMP values in proto storage and SQL display.
const UUIDProtoMessageName = "com.apple.foundationdb.record.UUID"
UUIDProtoMessageName is the fully-qualified name of the tuple_fields.UUID proto message that fdb-relational uses to store UUID column values (matches Java's TupleFieldsProto.UUID).
Variables ¶
This section is empty.
Functions ¶
func AddInt64Checked ¶
AddInt64Checked returns a+b and a success flag. Overflow iff the signs of a and b are the same and the result's sign flips. Matches Java's Math.addExact semantics.
func ApplyBitOp ¶
ApplyBitOp evaluates a bitwise operator. SQL standard + Java both require integer operands; float / string operands are an error (not a silent cast). The grammar exposes bitOperator tokens as concatenated text, so `<<` comes through as "<<" and `>>` as ">>".
Bit-shift operators `<<` / `>>` are intentionally NOT registered — matching fdb-relational 4.11.1.0's behaviour. Java tokenizes the operators but has no entry in the function registry, so its planner returns `RelationalException: Unsupported operator <<`. The Go embedded engine mirrors this by NOT having `<<` / `>>` cases here, so they fall through to the default ErrCodeUnsupportedOperation arm. Same architectural reason in both engines: no evaluator registered for shift operators. Per CLAUDE.md "Java↔Go conformance gotchas": doesn't work in Java → doesn't work in Go.
func ApplyMathOp ¶
ApplyMathOp evaluates one of +, -, *, /, % on two driver-level values with SQL semantics: NULL propagates, int64×int64 stays int64 and is overflow-checked (matching Java's ArithmeticValue. PhysicalOperator.*_LL), mixed int/float widens to float64. Division by zero errors with ErrCodeDivisionByZero; overflow errors with ErrCodeNumericValueOutOfRange.
func CastValue ¶
CastValue implements SQL CAST(v AS typeName). Splits INTEGER (32-bit) from BIGINT (64-bit) per Java CastValue range-check semantics: `CAST(9223372036854775807 AS INTEGER)` errors 22F3H because the value exceeds Integer.MAX_VALUE, even though the runtime representation of int64 doesn't need narrowing.
NULL casts to NULL of the target type. Unsupported source/target combinations error with ErrCodeUnsupportedOperation.
func CompareValues ¶
CompareValues returns -1/0/1 for a < b / a == b / a > b under SQL ordering semantics. NULL sorts before non-NULL (sort-site callers should honour NULLS FIRST / LAST before reaching here). Numeric promotion (int64 ↔ float64) mirrors ORDER BY rules; cross-type comparisons fall back to a stable type-name-based order so `=` correctly fails without a runtime panic.
func ConvertToProtoValue ¶
func ConvertToProtoValue(fd protoreflect.FieldDescriptor, val any) (protoreflect.Value, error)
ConvertToProtoValue converts a SQL-level driver.Value (int64, float64, string, bool, []byte) to a protoreflect.Value matching the field descriptor's kind. Range checks match Java's CastValue behaviour (LONG_TO_INT / DOUBLE_TO_LONG / DOUBLE_TO_FLOAT etc.); NaN/Inf in float columns are rejected as silent-data-corruption vectors.
func FormatDate ¶
FormatDate formats a time.Time as the canonical DATE string (date only).
func FormatTimestamp ¶
FormatTimestamp formats a time.Time as the canonical TIMESTAMP string.
func FullIdToName ¶
func FullIdToName(fid antlrgen.IFullIdContext) string
FullIdToName converts a FullId parse-tree node to a dot-separated, quote-stripped name. Used for table names in INSERT / UPDATE / DELETE and by the scalar function library when an argument is a qualified column reference.
func IsTruthy ¶
IsTruthy returns true when v is a non-nil, non-zero boolean or non-zero numeric. Used by SELECT-projection boolean coercion and by the `IF(cond, a, b)` scalar function.
func LikeMatch ¶
LikeMatch implements SQL LIKE pattern matching: % = any sequence, _ = any single char. If escape >= 0, that rune makes the following char literal (only valid before %, _, or escape itself per SQL standard; we accept any literal char after escape, matching Java's lenient interpretation).
func LiteralMatchesPKKind ¶
func LiteralMatchesPKKind(val any, kind protoreflect.Kind) bool
LiteralMatchesPKKind reports whether a driver-value literal is a safe tuple element for a column of the given proto kind. Only numeric / string / bytes kinds are in scope — booleans and enums can be columns in theory but are unusual and left to the scan path for now.
func MulInt64Checked ¶
MulInt64Checked returns a*b and a success flag. Mirrors Java's Math.multiplyExact. Uses the textbook "divide back" check: overflow iff (a*b)/b != a. The first special case (a == MinInt64 && b == -1) is REQUIRED: p/b would compute MinInt64 / -1, which traps with SIGFPE on amd64 — we must detect and bail before the divide. The second symmetric case is redundant (divide-back would flag it without a hardware trap, because the divisor is MinInt64 not -1) but kept for parallelism with the first so the intent is obvious.
func ParseTimestamp ¶
ParseTimestamp attempts to parse a string as a TIMESTAMP using multiple common layouts. Returns the parsed time in UTC or false.
func ProtoValueToDriver ¶
func ProtoValueToDriver(fd protoreflect.FieldDescriptor, v protoreflect.Value) driver.Value
ProtoValueToDriver maps a protoreflect.Value (read off a record) into a driver.Value for SQL-level consumption. Widens all integer kinds to int64 so the SQL evaluator doesn't need per-kind fan-out.
func ResolveQualifiedTableName ¶
ResolveQualifiedTableName validates and strips a schema qualifier from a dotted table name. Ports Java's SemanticAnalyzer.tableExists qualifier validation (lines 189-207):
- No dot → returns the name as-is.
- One dot (schema.table) → validates qualifier matches schemaName (case-insensitive), returns just the table name.
- Two+ dots → error (Java returns INTERNAL_ERROR).
schemaName is the current schema context (e.g., from session). Returns (tableName, errCode, errMsg). errCode is "" on success.
func StripIdentifierQuotes ¶
StripIdentifierQuotes normalizes an identifier's raw parse text to its canonical lookup form: quoted identifiers are stripped of their surrounding `"` or backticks and otherwise preserved case-for-case; unquoted identifiers are folded to upper case. Mirrors Java's SemanticAnalyzer.normalizeString (case-sensitive=false default).
func StripStringLiteralQuotes ¶
StripStringLiteralQuotes removes a single pair of surrounding single-quotes and unescapes doubled-quote ” sequences to a single quote. Used by every SQL string literal that reaches our code via the parser (the parser leaves the literal's raw source text, including quotes).
func SubInt64Checked ¶
SubInt64Checked returns a-b and a success flag. Overflow iff the signs of a and b differ and the sign of the result flips against a.
func ToFloat64 ¶
ToFloat64 coerces int64 / float64 to float64 for mixed-type arithmetic. Returns false for any other input type — callers error out with "requires numeric operands" on the failure path.
func ToIntegerArg ¶
ToIntegerArg coerces v to int64 for integer-typed function arguments (position, length, count). Whole-value floats are accepted as a convenience (`LEFT('hi', 2.0)` works); fractional floats and non-numeric types error rather than silently truncating to 0.
Types ¶
This section is empty.