Some checks failed
go: build dev binaries / cleanup (push) Successful in 4s
Codespell / Check for spelling errors (push) Failing after 3s
docker: build dev containers / build-rust-binaries (amd64, x86_64-unknown-linux-musl) (push) Failing after 3s
docker: build dev containers / build-dev-containers (push) Has been skipped
docker: build dev containers / build-rust-binaries (arm64, true, aarch64-unknown-linux-musl) (push) Failing after 3s
End to End / FUSE Mount (push) Failing after 2s
EC Integration Tests / EC Integration Tests (push) Failing after 30s
FUSE DLM Integration Tests / FUSE DLM Integration Tests (push) Failing after 3s
FUSE Volume Server Failover Tests / FUSE Volume Server Failover (push) Failing after 3s
FUSE Integration Tests / FUSE Integration Testing (push) Failing after 2s
FUSE P2P Peer Chunk Sharing Integration Tests / FUSE P2P Peer Chunk Sharing (push) Failing after 3s
go: build binary / Go Vet (push) Failing after 2s
go: build binary / Go Vet 32-bit (push) Failing after 3s
go: build binary / Build (push) Failing after 4s
go: build binary / Build cross-platform (freebsd/amd64) (push) Failing after 3s
go: build binary / Build cross-platform (windows/amd64) (push) Failing after 3s
go: build binary / Build cross-platform (darwin/arm64) (push) Failing after 3s
go: build binary / Build cross-platform (windows/arm64) (push) Failing after 3s
go: build binary / Test (push) Failing after 2s
go: build binary / Test 32-bit (push) Failing after 3s
helm: lint and test charts / lint-test (push) Failing after 3s
Java Client Integration Tests / Java Integration Tests (11) (push) Failing after 3s
Java Client Integration Tests / Java Integration Tests (17) (push) Failing after 3s
go: build dev binaries / build_dev_linux_windows (amd64, linux) (push) Failing after 2s
go: build dev binaries / build_dev_linux_windows (amd64, windows) (push) Failing after 3s
go: build dev binaries / build_dev_darwin (amd64, darwin) (push) Has been skipped
go: build dev binaries / build_dev_darwin (arm64, darwin) (push) Has been skipped
Java Client Unit Tests / Java Unit Tests (11) (push) Failing after 3s
Java Client Unit Tests / Java Unit Tests (17) (push) Failing after 2s
Java Client Unit Tests / Java Unit Tests (21) (push) Failing after 3s
Java Client Unit Tests / Java Unit Tests (8) (push) Failing after 3s
Kafka Quick Test (Load Test with Schema Registry) / Kafka Client Load Test (Quick) (push) Failing after 3s
Kafka Gateway Tests / Kafka Unit Tests (unit-tests-1) (push) Failing after 11s
Kafka Gateway Tests / Kafka Integration Tests (Critical) (integration-1) (push) Failing after 3s
Kafka Gateway Tests / Kafka End-to-End Tests (with SMQ) (e2e-1) (push) Failing after 3s
Kafka Gateway Tests / Kafka Consumer Group Tests (Highly Isolated) (consumer-group-1) (push) Failing after 2s
Kafka Gateway Tests / Kafka Client Compatibility (with SMQ) (client-compat-1) (push) Failing after 3s
Kafka Gateway Tests / Kafka SMQ Integration Tests (Full Stack) (smq-integration-1) (push) Failing after 3s
Kafka Gateway Tests / Kafka Protocol Tests (Isolated) (protocol-1) (push) Failing after 3s
KMS Tests / KMS Provider Integration Tests (push) Failing after 2s
KMS Tests / S3 KMS End-to-End Tests (push) Failing after 3s
Master Cold Start Tests / Master Cold Start Tests (push) Failing after 4s
Metadata Subscribe Integration Tests / Metadata Subscribe Integration Tests (push) Failing after 3s
Multi-Master Tests / Multi-Master Failover Tests (push) Failing after 3s
Performance / CPU and Heap Profile (push) Failing after 2s
Performance / S3 Read/Write Benchmark (rust volume) (push) Failing after 3s
pjdfstest POSIX Compliance / pjdfstest (push) Failing after 2s
Plugin Worker Integration Tests / Plugin Worker: erasure_coding (push) Failing after 3s
Plugin Worker Integration Tests / Plugin Worker: vacuum (push) Failing after 3s
Rust Volume Server Tests / Rust Integration Tests (push) Failing after 3s
Rust Volume Server Tests / Go Tests with Rust Volume (grpc - Shard 1) (push) Failing after 2s
Rust Volume Server Tests / Go Tests with Rust Volume (http - Shard 1) (push) Failing after 3s
Rust Volume Server Tests / Go Tests with Rust Volume (grpc - Shard 2) (push) Failing after 3s
Rust Volume Server Tests / Go Tests with Rust Volume (http - Shard 2) (push) Failing after 3s
Rust Volume Server Tests / Go Tests with Rust Volume (grpc - Shard 3) (push) Failing after 3s
S3 IAM Integration Tests / S3 IAM Distributed Tests (push) Failing after 2s
S3 IAM Integration Tests / S3 IAM Performance Tests (push) Failing after 3s
Performance / Throughput Benchmark (go volume) (push) Failing after 3s
Performance / Throughput Benchmark (rust volume) (push) Failing after 2s
Performance / S3 Read/Write Benchmark (go volume) (push) Failing after 3s
Plugin Worker Integration Tests / Plugin Worker: volume_balance (push) Failing after 3s
PostgreSQL Gateway Tests / PostgreSQL Basic Tests (push) Failing after 3s
Rust Volume Server Tests / Rust Unit Tests (push) Failing after 2s
Rust Volume Server Tests / Go Tests with Rust Volume (http - Shard 3) (push) Failing after 3s
Rust Plugin Worker Tests / Rust Plugin Worker Build and Unit Tests (push) Failing after 3s
rust: build dev volume server binaries / cleanup (push) Successful in 3s
S3 ETag and ACL Tests / S3 ETag + ACL Integration Tests (push) Failing after 3s
S3 IAM Integration Tests / IAM Unit Tests (push) Failing after 3s
S3 IAM Integration Tests / S3 IAM Integration Tests (advanced) (push) Failing after 3s
S3 IAM Integration Tests / S3 IAM Integration Tests (basic) (push) Failing after 2s
S3 IAM Integration Tests / S3 IAM Integration Tests (group) (push) Failing after 3s
S3 IAM Integration Tests / S3 IAM Integration Tests (policy-enforcement) (push) Failing after 2s
S3 IAM Integration Tests / S3 IAM Integration Tests (sts) (push) Failing after 4s
S3 Keycloak Integration Tests / S3 Keycloak Integration Tests (push) Failing after 3s
S3 PyArrow Parquet Tests / PyArrow Parquet Tests (Python 3.11) (push) Failing after 3s
S3 PyArrow Parquet Tests / Go Unit Tests (Implicit Directory) (push) Has been cancelled
S3 PyArrow Parquet Tests / PyArrow Parquet Tests (Python 3.12) (push) Has been cancelled
rust: build dev volume server binaries / build-rust-volume-dev-darwin (darwin-amd64, x86_64-apple-darwin) (push) Has been cancelled
rust: build dev volume server binaries / build-rust-volume-dev-darwin (darwin-arm64, aarch64-apple-darwin) (push) Has been cancelled
rust: build dev volume server binaries / build-rust-volume-dev-linux (linux-amd64, x86_64-unknown-linux-gnu) (push) Has been cancelled
S3 PyArrow Parquet Tests / PyArrow Parquet Tests (Python 3.9) (push) Has been cancelled
S3 Proxy Signature Tests / S3 Proxy Signature Verification Tests (push) Has been cancelled
S3 SDK V2 Route Disambiguation Tests / S3 SDK V2 Routing Tests (push) Has been cancelled
S3 SSE Tests / S3 SSE Integration Tests (quick) (push) Has been cancelled
S3 SSE Tests / S3 SSE Compatibility Test (push) Has been cancelled
S3 SSE Tests / S3 SSE Metadata Persistence Test (push) Has been cancelled
S3 SSE Tests / S3 SSE Copy Operations Test (push) Has been cancelled
S3 SSE Tests / S3 SSE Multipart Upload Test (push) Has been cancelled
S3 SSE Tests / S3 SSE Performance Test (push) Has been cancelled
S3 SSE Tests / S3 Volume Encryption Test (push) Has been cancelled
S3 SSE Tests / S3 SSE Integration Tests (comprehensive) (push) Has been cancelled
Spark Integration Tests / Spark Integration Tests (push) Failing after 2s
Telemetry Integration Tests / telemetry-integration-test (push) Failing after 3s
Volume Server Integration Tests / Volume Server Integration Tests (grpc - Shard 1) (push) Failing after 3s
Volume Server Integration Tests / Volume Server Integration Tests (http - Shard 1) (push) Failing after 3s
Ceph S3 tests / Basic S3 tests (KV store) (push) Has been cancelled
Ceph S3 tests / S3 Versioning & Object Lock tests (push) Has been cancelled
S3 Policy Integration Tests / S3 Policy Unit Tests (push) Failing after 3s
Ceph S3 tests / S3 CORS tests (push) Has been cancelled
Ceph S3 tests / SeaweedFS Custom S3 Copy tests (push) Has been cancelled
Ceph S3 tests / Basic S3 tests (SQL store) (push) Has been cancelled
test s3 over https using aws-cli / awscli-tests (push) Has been cancelled
TLS Rotation Integration Tests / TLS Rotation Integration Tests (push) Has been cancelled
Vacuum Integration Tests / Vacuum Integration Tests (push) Has been cancelled
S3 Policy Integration Tests / S3 Policy Variables Integration Tests (push) Failing after 3s
S3 Policy Integration Tests / S3 Policy Enforcement Integration Tests (advanced-policy) (push) Failing after 3s
S3 Policy Integration Tests / S3 Policy Enforcement Integration Tests (basic-policy) (push) Failing after 2s
S3 Policy Integration Tests / S3 Policy Enforcement Integration Tests (contextual-policy) (push) Failing after 4s
S3 Policy Integration Tests / Trusted Proxy Detection Tests (push) Failing after 2s
S3 Policy Integration Tests / S3 Policy Shell Integration Tests (push) Failing after 3s
Samba on FUSE Integration / samba-integration (push) Failing after 2s
SFTP Integration Tests / SFTP Integration Testing (push) Failing after 3s
terraform: validate and test modules / fmt, validate, plan-level tests (push) Failing after 3s
terraform: validate and test modules / local cluster smoke test (real weed) (push) Failing after 2s
Volume Server Integration Tests / Volume Server Integration Tests (grpc - Shard 3) (push) Failing after 3s
Volume Server Integration Tests / Volume Server Integration Tests (grpc - Shard 2) (push) Failing after 3s
Volume Server Integration Tests / Volume Server Integration Tests (http - Shard 2) (push) Failing after 2s
Volume Server Integration Tests / Volume Server Integration Tests (http - Shard 3) (push) Failing after 5s
mount: windows conformance / WinFsp conformance (push) Has been cancelled
mount: windows / Mount on Windows (push) Has been cancelled
253 lines
9.8 KiB
Go
253 lines
9.8 KiB
Go
package engine
|
|
|
|
import (
|
|
"strconv"
|
|
"testing"
|
|
|
|
"github.com/seaweedfs/seaweedfs/weed/pb/schema_pb"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
// TestAliasTimestampIntegration tests that SQL aliases work correctly with timestamp query fixes
|
|
func TestAliasTimestampIntegration(t *testing.T) {
|
|
engine := NewTestSQLEngine()
|
|
|
|
// Use the exact timestamps from the original failing production queries
|
|
originalFailingTimestamps := []int64{
|
|
1756947416566456262, // Original failing query 1
|
|
1756947416566439304, // Original failing query 2
|
|
1756913789829292386, // Current data timestamp
|
|
}
|
|
|
|
t.Run("AliasWithLargeTimestamps", func(t *testing.T) {
|
|
for i, timestamp := range originalFailingTimestamps {
|
|
t.Run("Timestamp_"+strconv.Itoa(i+1), func(t *testing.T) {
|
|
// Create test record
|
|
testRecord := &schema_pb.RecordValue{
|
|
Fields: map[string]*schema_pb.Value{
|
|
"_ts_ns": {Kind: &schema_pb.Value_Int64Value{Int64Value: timestamp}},
|
|
"id": {Kind: &schema_pb.Value_Int64Value{Int64Value: int64(1000 + i)}},
|
|
},
|
|
}
|
|
|
|
// Test equality with alias (this was the originally failing pattern)
|
|
sql := "SELECT _ts_ns AS ts, id FROM test WHERE ts = " + strconv.FormatInt(timestamp, 10)
|
|
stmt, err := ParseSQL(sql)
|
|
assert.NoError(t, err, "Should parse alias equality query for timestamp %d", timestamp)
|
|
|
|
selectStmt := stmt.(*SelectStatement)
|
|
predicate, err := engine.buildPredicateWithContext(selectStmt.Where.Expr, selectStmt.SelectExprs)
|
|
assert.NoError(t, err, "Should build predicate for large timestamp with alias")
|
|
|
|
result := predicate(testRecord)
|
|
assert.True(t, result, "Should match exact large timestamp using alias")
|
|
|
|
// Test precision - off by 1 nanosecond should not match
|
|
sqlOffBy1 := "SELECT _ts_ns AS ts, id FROM test WHERE ts = " + strconv.FormatInt(timestamp+1, 10)
|
|
stmt2, err := ParseSQL(sqlOffBy1)
|
|
assert.NoError(t, err)
|
|
selectStmt2 := stmt2.(*SelectStatement)
|
|
predicate2, err := engine.buildPredicateWithContext(selectStmt2.Where.Expr, selectStmt2.SelectExprs)
|
|
assert.NoError(t, err)
|
|
|
|
result2 := predicate2(testRecord)
|
|
assert.False(t, result2, "Should not match timestamp off by 1 nanosecond with alias")
|
|
})
|
|
}
|
|
})
|
|
|
|
t.Run("AliasWithTimestampRangeQueries", func(t *testing.T) {
|
|
timestamp := int64(1756947416566456262)
|
|
|
|
testRecords := []*schema_pb.RecordValue{
|
|
{
|
|
Fields: map[string]*schema_pb.Value{
|
|
"_ts_ns": {Kind: &schema_pb.Value_Int64Value{Int64Value: timestamp - 2}}, // Before range
|
|
},
|
|
},
|
|
{
|
|
Fields: map[string]*schema_pb.Value{
|
|
"_ts_ns": {Kind: &schema_pb.Value_Int64Value{Int64Value: timestamp}}, // In range
|
|
},
|
|
},
|
|
{
|
|
Fields: map[string]*schema_pb.Value{
|
|
"_ts_ns": {Kind: &schema_pb.Value_Int64Value{Int64Value: timestamp + 2}}, // After range
|
|
},
|
|
},
|
|
}
|
|
|
|
// Test range query with alias
|
|
sql := "SELECT _ts_ns AS ts FROM test WHERE ts >= " +
|
|
strconv.FormatInt(timestamp-1, 10) + " AND ts <= " +
|
|
strconv.FormatInt(timestamp+1, 10)
|
|
stmt, err := ParseSQL(sql)
|
|
assert.NoError(t, err, "Should parse range query with alias")
|
|
|
|
selectStmt := stmt.(*SelectStatement)
|
|
predicate, err := engine.buildPredicateWithContext(selectStmt.Where.Expr, selectStmt.SelectExprs)
|
|
assert.NoError(t, err, "Should build range predicate with alias")
|
|
|
|
// Test each record
|
|
assert.False(t, predicate(testRecords[0]), "Should not match record before range")
|
|
assert.True(t, predicate(testRecords[1]), "Should match record in range")
|
|
assert.False(t, predicate(testRecords[2]), "Should not match record after range")
|
|
})
|
|
|
|
t.Run("AliasWithTimestampPrecisionEdgeCases", func(t *testing.T) {
|
|
// Test maximum int64 value
|
|
maxInt64 := int64(9223372036854775807)
|
|
testRecord := &schema_pb.RecordValue{
|
|
Fields: map[string]*schema_pb.Value{
|
|
"_ts_ns": {Kind: &schema_pb.Value_Int64Value{Int64Value: maxInt64}},
|
|
},
|
|
}
|
|
|
|
// Test with alias
|
|
sql := "SELECT _ts_ns AS ts FROM test WHERE ts = " + strconv.FormatInt(maxInt64, 10)
|
|
stmt, err := ParseSQL(sql)
|
|
assert.NoError(t, err, "Should parse max int64 with alias")
|
|
|
|
selectStmt := stmt.(*SelectStatement)
|
|
predicate, err := engine.buildPredicateWithContext(selectStmt.Where.Expr, selectStmt.SelectExprs)
|
|
assert.NoError(t, err, "Should build predicate for max int64 with alias")
|
|
|
|
result := predicate(testRecord)
|
|
assert.True(t, result, "Should handle max int64 value correctly with alias")
|
|
|
|
// Test minimum value
|
|
minInt64 := int64(-9223372036854775808)
|
|
testRecord2 := &schema_pb.RecordValue{
|
|
Fields: map[string]*schema_pb.Value{
|
|
"_ts_ns": {Kind: &schema_pb.Value_Int64Value{Int64Value: minInt64}},
|
|
},
|
|
}
|
|
|
|
sql2 := "SELECT _ts_ns AS ts FROM test WHERE ts = " + strconv.FormatInt(minInt64, 10)
|
|
stmt2, err := ParseSQL(sql2)
|
|
assert.NoError(t, err)
|
|
selectStmt2 := stmt2.(*SelectStatement)
|
|
predicate2, err := engine.buildPredicateWithContext(selectStmt2.Where.Expr, selectStmt2.SelectExprs)
|
|
assert.NoError(t, err)
|
|
|
|
result2 := predicate2(testRecord2)
|
|
assert.True(t, result2, "Should handle min int64 value correctly with alias")
|
|
})
|
|
|
|
t.Run("MultipleAliasesWithTimestamps", func(t *testing.T) {
|
|
// Test multiple aliases including timestamps
|
|
timestamp1 := int64(1756947416566456262)
|
|
timestamp2 := int64(1756913789829292386)
|
|
|
|
testRecord := &schema_pb.RecordValue{
|
|
Fields: map[string]*schema_pb.Value{
|
|
"_ts_ns": {Kind: &schema_pb.Value_Int64Value{Int64Value: timestamp1}},
|
|
"created_at": {Kind: &schema_pb.Value_Int64Value{Int64Value: timestamp2}},
|
|
"id": {Kind: &schema_pb.Value_Int64Value{Int64Value: 12345}},
|
|
},
|
|
}
|
|
|
|
// Use multiple timestamp aliases in WHERE
|
|
sql := "SELECT _ts_ns AS event_time, created_at AS created_time, id AS record_id FROM test " +
|
|
"WHERE event_time = " + strconv.FormatInt(timestamp1, 10) +
|
|
" AND created_time = " + strconv.FormatInt(timestamp2, 10) +
|
|
" AND record_id = 12345"
|
|
|
|
stmt, err := ParseSQL(sql)
|
|
assert.NoError(t, err, "Should parse complex query with multiple timestamp aliases")
|
|
|
|
selectStmt := stmt.(*SelectStatement)
|
|
predicate, err := engine.buildPredicateWithContext(selectStmt.Where.Expr, selectStmt.SelectExprs)
|
|
assert.NoError(t, err, "Should build predicate for multiple timestamp aliases")
|
|
|
|
result := predicate(testRecord)
|
|
assert.True(t, result, "Should match complex query with multiple timestamp aliases")
|
|
})
|
|
|
|
t.Run("CompatibilityWithExistingTimestampFixes", func(t *testing.T) {
|
|
// Verify that all the timestamp fixes (precision, scan boundaries, etc.) still work with aliases
|
|
largeTimestamp := int64(1756947416566456262)
|
|
|
|
// Test all comparison operators with aliases
|
|
operators := []struct {
|
|
sql string
|
|
value int64
|
|
expected bool
|
|
}{
|
|
{"ts = " + strconv.FormatInt(largeTimestamp, 10), largeTimestamp, true},
|
|
{"ts = " + strconv.FormatInt(largeTimestamp+1, 10), largeTimestamp, false},
|
|
{"ts > " + strconv.FormatInt(largeTimestamp-1, 10), largeTimestamp, true},
|
|
{"ts > " + strconv.FormatInt(largeTimestamp, 10), largeTimestamp, false},
|
|
{"ts >= " + strconv.FormatInt(largeTimestamp, 10), largeTimestamp, true},
|
|
{"ts >= " + strconv.FormatInt(largeTimestamp+1, 10), largeTimestamp, false},
|
|
{"ts < " + strconv.FormatInt(largeTimestamp+1, 10), largeTimestamp, true},
|
|
{"ts < " + strconv.FormatInt(largeTimestamp, 10), largeTimestamp, false},
|
|
{"ts <= " + strconv.FormatInt(largeTimestamp, 10), largeTimestamp, true},
|
|
{"ts <= " + strconv.FormatInt(largeTimestamp-1, 10), largeTimestamp, false},
|
|
}
|
|
|
|
for _, op := range operators {
|
|
t.Run(op.sql, func(t *testing.T) {
|
|
testRecord := &schema_pb.RecordValue{
|
|
Fields: map[string]*schema_pb.Value{
|
|
"_ts_ns": {Kind: &schema_pb.Value_Int64Value{Int64Value: op.value}},
|
|
},
|
|
}
|
|
|
|
sql := "SELECT _ts_ns AS ts FROM test WHERE " + op.sql
|
|
stmt, err := ParseSQL(sql)
|
|
assert.NoError(t, err, "Should parse: %s", op.sql)
|
|
|
|
selectStmt := stmt.(*SelectStatement)
|
|
predicate, err := engine.buildPredicateWithContext(selectStmt.Where.Expr, selectStmt.SelectExprs)
|
|
assert.NoError(t, err, "Should build predicate for: %s", op.sql)
|
|
|
|
result := predicate(testRecord)
|
|
assert.Equal(t, op.expected, result, "Alias operator test failed for: %s", op.sql)
|
|
})
|
|
}
|
|
})
|
|
|
|
t.Run("ProductionScenarioReproduction", func(t *testing.T) {
|
|
// Reproduce the exact production scenario that was originally failing
|
|
|
|
// This was the original failing pattern from the user
|
|
originalFailingSQL := "select id, _ts_ns as ts from ecommerce.user_events where ts = 1756913789829292386"
|
|
|
|
testRecord := &schema_pb.RecordValue{
|
|
Fields: map[string]*schema_pb.Value{
|
|
"_ts_ns": {Kind: &schema_pb.Value_Int64Value{Int64Value: 1756913789829292386}},
|
|
"id": {Kind: &schema_pb.Value_Int64Value{Int64Value: 82460}},
|
|
},
|
|
}
|
|
|
|
stmt, err := ParseSQL(originalFailingSQL)
|
|
assert.NoError(t, err, "Should parse the exact originally failing production query")
|
|
|
|
selectStmt := stmt.(*SelectStatement)
|
|
predicate, err := engine.buildPredicateWithContext(selectStmt.Where.Expr, selectStmt.SelectExprs)
|
|
assert.NoError(t, err, "Should build predicate for original failing query")
|
|
|
|
result := predicate(testRecord)
|
|
assert.True(t, result, "The originally failing production query should now work perfectly")
|
|
|
|
// Also test the other originally failing timestamp
|
|
originalFailingSQL2 := "select id, _ts_ns as ts from ecommerce.user_events where ts = 1756947416566456262"
|
|
testRecord2 := &schema_pb.RecordValue{
|
|
Fields: map[string]*schema_pb.Value{
|
|
"_ts_ns": {Kind: &schema_pb.Value_Int64Value{Int64Value: 1756947416566456262}},
|
|
"id": {Kind: &schema_pb.Value_Int64Value{Int64Value: 897795}},
|
|
},
|
|
}
|
|
|
|
stmt2, err := ParseSQL(originalFailingSQL2)
|
|
assert.NoError(t, err)
|
|
selectStmt2 := stmt2.(*SelectStatement)
|
|
predicate2, err := engine.buildPredicateWithContext(selectStmt2.Where.Expr, selectStmt2.SelectExprs)
|
|
assert.NoError(t, err)
|
|
|
|
result2 := predicate2(testRecord2)
|
|
assert.True(t, result2, "The second originally failing production query should now work perfectly")
|
|
})
|
|
}
|