Changeset: 19eadb234db5 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/19eadb234db5
Modified Files:
sql/test/bincopy/Tests/bincopy_support.py
Branch: copyintobinary
Log Message:
Extend existing COPY BINARY INTO tests to also test COPY INTO BINARY
diffs (truncated from 317 to 300 lines):
diff --git a/sql/test/bincopy/Tests/bincopy_support.py
b/sql/test/bincopy/Tests/bincopy_support.py
--- a/sql/test/bincopy/Tests/bincopy_support.py
+++ b/sql/test/bincopy/Tests/bincopy_support.py
@@ -3,6 +3,7 @@ import os
import re
import subprocess
import sys
+import tempfile
from MonetDBtesting.sqltest import SQLTestCase
NRECS = 1_000_000
@@ -15,17 +16,38 @@ class DataMaker:
def __init__(self):
self.fixed_substitutions = dict()
self.work_list = set()
+ self.outfile_to_expected = dict()
def additionally(self, key, value):
self.fixed_substitutions[key] = value
def substitute_match(self, match):
+ var = match.group(1)
+
+ if var in self.fixed_substitutions:
+ return self.fixed_substitutions[var]
+
+ if var.startswith('>'):
+ var = var[1:]
+ outfile = tempfile.mktemp(dir=BINCOPY_FILES, prefix='out_' + var +
'_', suffix='.bin')
+ else:
+ outfile = None
+
+ datafile = self.create_datafile(var)
+
+ if outfile:
+ self.outfile_to_expected[outfile] = datafile
+ substitution = outfile
+ else:
+ substitution = datafile
+
+ quoted = substitution.replace("'", "''")
+ return f"R'{quoted}'"
+
+ def create_datafile(self, var):
flags = []
ext = ''
- var = match.group(1)
- if var in self.fixed_substitutions:
- return self.fixed_substitutions[var]
- elif var.startswith('le_'):
+ if var.startswith('le_'):
var = var[3:]
ext = '.le'
flags.append('--little-endian')
@@ -43,7 +65,7 @@ class DataMaker:
if not os.path.isfile(dst_filename):
cmd = ("bincopydata", *flags, var, str(NRECS), tmp_filename)
self.work_list.add( (cmd, tmp_filename, dst_filename))
- return f"R'{dst_filename}'"
+ return dst_filename
def generate_files(self):
processes = []
@@ -59,19 +81,23 @@ class DataMaker:
os.rename(tmp, dst)
+ def outfiles(self):
+ return self.outfile_to_expected.items()
+
def run_test(side, testcase):
code, expected_result = testcase
+ assert len(re.findall('@ON@', code)) == len(re.findall('COPY', code))
assert '@ON@' in code
# generate the query
data_maker = DataMaker()
data_maker.additionally('ON', 'ON ' + side.upper())
data_maker.additionally('NRECS', NRECS)
data_maker.additionally('NRECS_DIV_4', NRECS / 4)
- massage = lambda s: re.sub(r'@(\w+)@', data_maker.substitute_match, s)
+ massage = lambda s: re.sub(r'@(>?\w+)@', data_maker.substitute_match, s)
code = massage(code)
- code = f"START TRANSACTION;\n{code}\nROLLBACK;"
+ code = f"START TRANSACTION;\n{code}\nROLLBACK;\n"
open(os.path.join(BINCOPY_FILES, 'test.sql'), "w").write(code)
# generate the required data files
@@ -89,29 +115,44 @@ def run_test(side, testcase):
if err_msg:
err_msg = massage(err_msg)
tr.assertFailed(err_code, err_msg)
+ for outfile, expected in data_maker.outfiles():
+ safe_maximum = 1024 * 1024 * 1024
+ if not os.path.exists(outfile):
+ tr.fail(f'Output file {outfile} was not created')
+ expected_content = open(expected, 'rb').read(safe_maximum)
+ content = open(outfile, 'rb').read(safe_maximum)
+ if len(content) != len(expected_content):
+ tr.fail(f'Outfile {outfile} has wrong length: {len(content)},
expected {len(expected_content)}')
+ elif content != expected_content:
+ tr.fail(f'Content of outfile {outfile} differs from
{expected}')
+
INTS = ("""
CREATE TABLE foo(id INT NOT NULL);
COPY BINARY INTO foo(id) FROM @ints@ @ON@;
+COPY SELECT id FROM foo INTO BINARY @>ints@ @ON@;
SELECT COUNT(DISTINCT id) FROM foo;
""", [f"{NRECS}"])
MORE_INTS = ("""
CREATE TABLE foo(id INT NOT NULL, i INT);
COPY BINARY INTO foo(id, i) FROM @ints@, @more_ints@ @ON@;
+COPY SELECT i, id FROM foo INTO BINARY @>more_ints@, @>ints@ @ON@;
SELECT COUNT(id) FROM foo WHERE i = id + 1;
""", [f"{NRECS}"])
STRINGS = ("""
CREATE TABLE foo(id INT NOT NULL, s VARCHAR(20));
COPY BINARY INTO foo(id, s) FROM @ints@, @strings@ @ON@;
+COPY SELECT id, s FROM foo INTO BINARY @>ints@, @>strings@ @ON@;
SELECT COUNT(id) FROM foo WHERE s = ('int' || id);
""", [f"{NRECS}"])
NULL_INTS = ("""
CREATE TABLE foo(id INT NOT NULL, i INT);
COPY BINARY INTO foo(id, i) FROM @ints@, @null_ints@ @ON@;
+COPY SELECT i, id FROM foo INTO BINARY @>null_ints@, @>ints@ @ON@;
SELECT COUNT(id) FROM foo
WHERE (id % 2 = 0 AND i IS NULL)
OR (id % 2 = 1 AND i = id);
@@ -120,6 +161,7 @@ OR (id % 2 = 1 AND i = id);
LARGE_STRINGS = ("""
CREATE TABLE foo(id INT NOT NULL, s TEXT);
COPY BINARY INTO foo(id, s) FROM @ints@, @large_strings@ @ON@;
+COPY SELECT id, s FROM foo INTO BINARY @>ints@, @>large_strings@ @ON@;
SELECT COUNT(id) FROM foo
WHERE (id % 10000 <> 0 AND LENGTH(s) = 9)
OR (id % 10000 = 0 AND LENGTH(s) = 280000 + 9);
@@ -141,6 +183,7 @@ SELECT COUNT(id) FROM foo WHERE s = (E'R
NULL_STRINGS = ("""
CREATE TABLE foo(id INT NOT NULL, s TEXT);
COPY BINARY INTO foo(id, s) FROM @ints@, @null_strings@ @ON@;
+COPY SELECT id, s FROM foo INTO BINARY @>ints@, @>null_strings@ @ON@;
SELECT COUNT(id) FROM foo
WHERE (id % 2 = 0 AND s IS NULL)
OR (id % 2 = 1 AND s = 'banana');
@@ -174,6 +217,22 @@ FROM @ints@,
@timestamp_ms@
@ON@;
+COPY SELECT id, ts, dt, tm, "year", "month", "day", "hour", "minute",
"second", ms FROM foo
+INTO BINARY
+ @>ints@,
+ @>timestamps@,
+ @>timestamp_dates@,
+ @>timestamp_times@,
+ @>timestamp_years@,
+ @>timestamp_months@,
+ @>timestamp_days@,
+ @>timestamp_hours@,
+ @>timestamp_minutes@,
+ @>timestamp_seconds@,
+ @>timestamp_ms@
+ @ON@;
+
+
SELECT * FROM foo
WHERE EXTRACT(YEAR FROM ts) <> "year"
LIMIT 4;
@@ -224,6 +283,7 @@ SELECT COUNT(id) FROM foo WHERE i = id +
BOOLS = ("""
CREATE TABLE foo(id INT NOT NULL, b BOOL);
COPY BINARY INTO foo(id, b) FROM @ints@, @bools@ @ON@;
+COPY SELECT id, b FROM foo INTO BINARY @>ints@, @>bools@ @ON@;
SELECT COUNT(id) FROM foo WHERE b = (id % 2 <> 0);
""", [f"{NRECS}"])
@@ -237,12 +297,14 @@ SELECT COUNT(id) FROM foo WHERE i = id +
FLOATS = ("""
CREATE TABLE foo(id INT NOT NULL, r REAL);
COPY BINARY INTO foo(id, r) FROM @ints@, @floats@ @ON@;
+COPY SELECT id, r FROM foo INTO BINARY @>ints@, @>floats@ @ON@;
SELECT COUNT(id) FROM foo WHERE CAST(id AS REAL) + 0.5 = r;
""", [f"{NRECS}"])
DOUBLES = ("""
CREATE TABLE foo(id INT NOT NULL, d DOUBLE);
COPY BINARY INTO foo(id, d) FROM @ints@, @doubles@ @ON@;
+COPY SELECT id, d FROM foo INTO BINARY @>ints@, @>doubles@ @ON@;
SELECT COUNT(id) FROM foo WHERE CAST(id AS REAL) + 0.5 = d;
""", [f"{NRECS}"])
@@ -250,6 +312,9 @@ INTEGER_TYPES = ("""
CREATE TABLE foo(t TINYINT, s SMALLINT, i INT, b BIGINT);
COPY BINARY INTO foo FROM @tinyints@, @smallints@, @ints@, @bigints@ @ON@;
+COPY SELECT t, s, i, b FROM foo
+INTO BINARY @>tinyints@, @>smallints@, @>ints@, @>bigints@ @ON@;
+
WITH
enlarged AS ( -- first go to the largest type
SELECT
@@ -288,6 +353,8 @@ HUGE_INTS = ("""
CREATE TABLE foo(b BIGINT, h HUGEINT);
COPY BINARY INTO foo FROM @bigints@, @hugeints@ @ON@;
+COPY SELECT b, h FROM foo INTO BINARY @>bigints@, @>hugeints@ @ON@;
+
WITH
enlarged AS (
SELECT
@@ -336,6 +403,7 @@ CREATE TABLE foo(
d10_2 DECIMAL(10, 2),
d18_2 DECIMAL(18, 2)
);
+
COPY BINARY INTO foo FROM
-- bte: i1, d1_1, d2_1
@tinyints@, @tinyints@, @tinyints@,
@@ -346,6 +414,21 @@ COPY BINARY INTO foo FROM
-- lng: i8, d10_2, d18_2
@bigints@, @bigints@, @bigints@
@ON@;
+
+COPY
+SELECT i1, d1_1, d2_1, i2, d3_2, d4_2, i4, d5_2, d9_2, i8, d10_2, d18_2
+FROM foo
+INTO BINARY
+ -- bte: i1, d1_1, d2_1
+ @>tinyints@, @>tinyints@, @>tinyints@,
+ -- sht: i2, d3_2, d4_2
+ @>smallints@, @>smallints@, @>smallints@,
+ -- int: i4, d5_2, d9_2
+ @>ints@, @>ints@, @>ints@,
+ -- lng: i8, d10_2, d18_2
+ @>bigints@, @>bigints@, @>bigints@
+ @ON@;
+
WITH verified AS (
SELECT
(d1_1 IS NULL OR 10 * d1_1 = i1) AS d1_1_ok,
@@ -376,9 +459,16 @@ CREATE TABLE foo(
d19_2 DECIMAL(19, 2),
d38_2 DECIMAL(38, 2)
);
+
COPY BINARY INTO foo FROM
@hugeints@, @hugeints@, @hugeints@
@ON@;
+
+COPY SELECT i, d19_2, d38_2 FROM foo
+INTO BINARY
+ @>hugeints@, @>hugeints@, @>hugeints@
+ @ON@;
+
SELECT
(100 * d19_2 = i) AS d19_ok,
(100 * d38_2 = i) AS d38_ok,
@@ -399,6 +489,7 @@ SELECT COUNT(*) FROM foo;
JSON_OBJECTS = ("""
CREATE TABLE foo(i INT, j JSON);
COPY BINARY INTO foo FROM @ints@, @json_objects@ @ON@;
+COPY SELECT i, j FROM foo INTO BINARY @>ints@, @>json_objects@ @ON@;
SELECT COUNT(*) FROM foo
WHERE (i % 100 = 99 AND j IS NULL)
OR (i % 100 <> 99 AND j IS NOT NULL)
@@ -408,6 +499,7 @@ OR (i % 100 <> 99 AND j IS NOT NULL)
UUIDS = ("""
CREATE TABLE foo(t CHAR(16), u UUID);
COPY BINARY INTO foo FROM @text_uuids@, @binary_uuids@ @ON@;
+COPY SELECT t, u FROM foo INTO BINARY @>text_uuids@, @>binary_uuids@ @ON@;
SELECT COUNT(*) FROM foo
WHERE t = CAST(u AS TEXT)
OR u IS NULL
@@ -416,8 +508,12 @@ OR u IS NULL
LITTLE_ENDIANS = ("""
CREATE TABLE foo(t TINYINT, s SMALLINT, i INT, b BIGINT, f FLOAT(4), d DOUBLE);
+
COPY LITTLE ENDIAN BINARY INTO foo FROM @le_tinyints@, @le_smallints@,
@le_ints@, @le_bigints@, @le_floats@, @le_doubles@ @ON@;
+COPY SELECT t, s, i, b, f, d FROM foo
+INTO LITTLE ENDIAN BINARY @>le_tinyints@, @>le_smallints@, @>le_ints@,
@>le_bigints@, @>le_floats@, @>le_doubles@ @ON@;
+
WITH
enlarged AS ( -- first go to the largest type
SELECT
@@ -459,8 +555,12 @@ ORDER BY t_s, s_i, i_b, f_d
BIG_ENDIANS = ("""
CREATE TABLE foo(t TINYINT, s SMALLINT, i INT, b BIGINT, f FLOAT(4), d DOUBLE);
+
COPY BIG ENDIAN BINARY INTO foo FROM @be_tinyints@, @be_smallints@, @be_ints@,
@be_bigints@, @be_floats@, @be_doubles@ @ON@;
+COPY SELECT t, s, i, b, f, d FROM foo
+INTO BIG ENDIAN BINARY @>be_tinyints@, @>be_smallints@, @>be_ints@,
@>be_bigints@, @>be_floats@, @>be_doubles@ @ON@;
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]