Skip to content

Commit f2f580d

Browse files
kesmit13claude
andcommitted
Add server version checks and conditional loading for float16 tests
This commit implements a generalized version-based SQL loading system for tests and adds server version checks for float16 vector tests. Changes: - Add server version check to test_f16_vectors() that skips the test if server version < 9.1 with a descriptive message - Create test_9_1.sql containing float16 vector test data - Implement generalized version-specific SQL file loading in utils.py: - get_server_version(): Extract server version as (major, minor) tuple - find_version_specific_sql_files(): Discover test_X_Y.sql files - load_version_specific_sql(): Conditionally load SQL based on version - Update load_sql() to automatically load version-specific SQL files - Remove f16_vectors table from test.sql (now in test_9_1.sql) The new system automatically discovers and loads SQL files matching the pattern test_X_Y.sql where X is major version and Y is minor version. Files are loaded only if the server version >= the file version. This makes it easy to add version-specific test data in the future (e.g., test_9_2.sql, test_10_0.sql) without modifying Python code. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent adc01ab commit f2f580d

File tree

4 files changed

+155
-7
lines changed

4 files changed

+155
-7
lines changed

singlestoredb/tests/test.sql

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -676,13 +676,8 @@ INSERT INTO i64_vectors VALUES(1, '[1, 2, 3]');
676676
INSERT INTO i64_vectors VALUES(2, '[4, 5, 6]');
677677
INSERT INTO i64_vectors VALUES(3, '[-1, -4, 8]');
678678

679-
CREATE TABLE IF NOT EXISTS `f16_vectors` (
680-
id INT(11),
681-
a VECTOR(3, F16)
682-
);
683-
INSERT INTO f16_vectors VALUES(1, '[0.267, 0.535, 0.802]');
684-
INSERT INTO f16_vectors VALUES(2, '[0.371, 0.557, 0.743]');
685-
INSERT INTO f16_vectors VALUES(3, '[-0.424, -0.566, 0.707]');
679+
-- Float16 vectors require server version 9.1 or later
680+
-- Table creation is handled conditionally in Python code (see utils.py or test setup)
686681

687682

688683
--

singlestoredb/tests/test_9_1.sql

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
-- Test data for SingleStore 9.1+ features
2+
-- This file is automatically loaded by utils.py if server version >= 9.1
3+
4+
-- Float16 (half-precision) vectors
5+
CREATE TABLE IF NOT EXISTS `f16_vectors` (
6+
id INT(11),
7+
a VECTOR(3, F16)
8+
);
9+
INSERT INTO f16_vectors VALUES(1, '[0.267, 0.535, 0.802]');
10+
INSERT INTO f16_vectors VALUES(2, '[0.371, 0.557, 0.743]');
11+
INSERT INTO f16_vectors VALUES(3, '[-0.424, -0.566, 0.707]');

singlestoredb/tests/test_connection.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3101,6 +3101,19 @@ def test_f16_vectors(self):
31013101
if self.conn.driver in ['http', 'https']:
31023102
self.skipTest('Data API does not surface vector information')
31033103

3104+
# Check server version - float16 requires 9.1 or later
3105+
self.cur.execute('select @@memsql_version')
3106+
version_str = list(self.cur)[0][0]
3107+
# Parse version string like "9.1.2" or "9.1.2-abc123"
3108+
version_parts = version_str.split('-')[0].split('.')
3109+
major = int(version_parts[0])
3110+
minor = int(version_parts[1]) if len(version_parts) > 1 else 0
3111+
if major < 9 or (major == 9 and minor < 1):
3112+
self.skipTest(
3113+
f'Float16 vectors require server version 9.1 or later '
3114+
f'(found {version_str})',
3115+
)
3116+
31043117
self.cur.execute('show variables like "enable_extended_types_metadata"')
31053118
out = list(self.cur)
31063119
if not out or out[0][1].lower() == 'off':

singlestoredb/tests/utils.py

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
#!/usr/bin/env python
22
# type: ignore
33
"""Utilities for testing."""
4+
import glob
45
import logging
56
import os
7+
import re
68
import uuid
79
from typing import Any
810
from typing import Dict
11+
from typing import List
12+
from typing import Tuple
913
from urllib.parse import urlparse
1014

1115
import singlestoredb as s2
@@ -23,6 +27,116 @@ def apply_template(content: str, vars: Dict[str, Any]) -> str:
2327
return content
2428

2529

30+
def get_server_version(cursor: Any) -> Tuple[int, int]:
31+
"""
32+
Get the server version as a (major, minor) tuple.
33+
34+
Parameters
35+
----------
36+
cursor : Cursor
37+
Database cursor to execute queries
38+
39+
Returns
40+
-------
41+
(int, int)
42+
Tuple of (major_version, minor_version)
43+
"""
44+
cursor.execute('SELECT @@memsql_version')
45+
version_str = cursor.fetchone()[0]
46+
# Parse version string like "9.1.2" or "9.1.2-abc123"
47+
version_parts = version_str.split('-')[0].split('.')
48+
major = int(version_parts[0])
49+
minor = int(version_parts[1]) if len(version_parts) > 1 else 0
50+
logger.info(f'Detected server version: {major}.{minor} (full: {version_str})')
51+
return (major, minor)
52+
53+
54+
def find_version_specific_sql_files(base_dir: str) -> List[Tuple[int, int, str]]:
55+
"""
56+
Find all version-specific SQL files in the given directory.
57+
58+
Looks for files matching the pattern test_X_Y.sql where X is major
59+
version and Y is minor version.
60+
61+
Parameters
62+
----------
63+
base_dir : str
64+
Directory to search for SQL files
65+
66+
Returns
67+
-------
68+
List[Tuple[int, int, str]]
69+
List of (major, minor, filepath) tuples sorted by version
70+
"""
71+
pattern = os.path.join(base_dir, 'test_*_*.sql')
72+
files = []
73+
74+
for filepath in glob.glob(pattern):
75+
filename = os.path.basename(filepath)
76+
# Match pattern: test_X_Y.sql
77+
match = re.match(r'test_(\d+)_(\d+)\.sql$', filename)
78+
if match:
79+
major = int(match.group(1))
80+
minor = int(match.group(2))
81+
files.append((major, minor, filepath))
82+
logger.debug(
83+
f'Found version-specific SQL file: {filename} '
84+
f'(v{major}.{minor})',
85+
)
86+
87+
# Sort by version (major, minor)
88+
files.sort()
89+
return files
90+
91+
92+
def load_version_specific_sql(
93+
cursor: Any,
94+
base_dir: str,
95+
server_version: Tuple[int, int],
96+
template_vars: Dict[str, Any],
97+
) -> None:
98+
"""
99+
Load version-specific SQL files based on server version.
100+
101+
Parameters
102+
----------
103+
cursor : Cursor
104+
Database cursor to execute queries
105+
base_dir : str
106+
Directory containing SQL files
107+
server_version : Tuple[int, int]
108+
Server version as (major, minor)
109+
template_vars : Dict[str, Any]
110+
Template variables to apply to SQL content
111+
"""
112+
sql_files = find_version_specific_sql_files(base_dir)
113+
server_major, server_minor = server_version
114+
115+
for file_major, file_minor, filepath in sql_files:
116+
# Load if server version >= file version
117+
if (
118+
server_major > file_major or
119+
(server_major == file_major and server_minor >= file_minor)
120+
):
121+
logger.info(
122+
f'Loading version-specific SQL: {os.path.basename(filepath)} '
123+
f'(requires {file_major}.{file_minor}, '
124+
f'server is {server_major}.{server_minor})',
125+
)
126+
with open(filepath, 'r') as sql_file:
127+
for cmd in sql_file.read().split(';\n'):
128+
cmd = apply_template(cmd.strip(), template_vars)
129+
if cmd:
130+
cmd += ';'
131+
cursor.execute(cmd)
132+
else:
133+
logger.info(
134+
f'Skipping version-specific SQL: {os.path.basename(filepath)} '
135+
f'(requires {file_major}.{file_minor}, '
136+
f'server is {server_major}.{server_minor})',
137+
)
138+
139+
26140
def load_sql(sql_file: str) -> str:
27141
"""
28142
Load a file containing SQL code.
@@ -111,6 +225,21 @@ def load_sql(sql_file: str) -> str:
111225
cur.execute('SET GLOBAL HTTP_API=ON;')
112226
cur.execute('RESTART PROXY;')
113227

228+
# Load version-specific SQL files (e.g., test_9_1.sql for 9.1+)
229+
try:
230+
server_version = get_server_version(cur)
231+
sql_dir = os.path.dirname(sql_file)
232+
load_version_specific_sql(
233+
cur,
234+
sql_dir,
235+
server_version,
236+
template_vars,
237+
)
238+
except Exception as e:
239+
logger.warning(
240+
f'Failed to load version-specific SQL files: {e}',
241+
)
242+
114243
return dbname, dbexisted
115244

116245

0 commit comments

Comments
 (0)