Skip to content

Commit aa6156a

Browse files
authored
Feature/make test (#44)
* feat: considef mysqld_version when judge STRING is var * feat: BLOB * feat: mysql 5 parse bit, char * feat: create table add some column
1 parent 3f63d18 commit aa6156a

File tree

6 files changed

+72
-12
lines changed

6 files changed

+72
-12
lines changed

devtools/create_table.py

+50-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import sqlalchemy
22
from sqlalchemy.dialects import mysql as dmysql
3-
from sqlalchemy.orm import declarative_base
3+
from sqlalchemy.orm import declarative_base, sessionmaker
44
from sqlalchemy import Column
5-
from sqlalchemy import text
5+
from sqlalchemy import text, insert
6+
import time
67

78
with open(".deploy_mysqld") as f:
89
url = f.readline().strip()
@@ -18,7 +19,7 @@
1819
all_type = [
1920
t
2021
for t in dir(dmysql.types)
21-
if t.isupper() and t not in ["ARRAY", "NULLTYPE", "STRINGTYPE"] and "CHAR" not in t
22+
if t.isupper() and t not in ["ARRAY", "NULLTYPE", "STRINGTYPE", "DECIMAL"] and "CHAR" not in t
2223
]
2324
Base = declarative_base()
2425
all_type_column = [
@@ -31,6 +32,15 @@
3132
)
3233
all_type_column.append(" ENUM = Column(dmysql.ENUM('hello', 'world', 'a'))")
3334
all_type_column.append(" SET = Column(dmysql.SET('a', 'b', 'c'))")
35+
all_type_column.append(
36+
" DECIMAL = Column(dmysql.types.DECIMAL(10, 2))"
37+
)
38+
all_type_column.append(
39+
" CHAR = Column(dmysql.types.CHAR(20))"
40+
)
41+
all_type_column.append(
42+
" VARBINARY = Column(dmysql.VARBINARY(203))"
43+
)
3444
all_type_column.append(
3545
" int_def_col = Column(dmysql.types.BIGINT, server_default=text('42'))"
3646
)
@@ -40,4 +50,41 @@
4050
exec("\n".join(all_type_column))
4151
AllType = locals().get("AllType")
4252
engine = sqlalchemy.create_engine(url)
53+
54+
with engine.connect() as conn:
55+
conn.exec_driver_sql("use test")
56+
conn.exec_driver_sql("drop table if exists all_type")
57+
conn.commit()
58+
4359
Base.metadata.create_all(engine)
60+
61+
with sessionmaker(bind=engine)() as session:
62+
test_data = AllType(BIGINT=98283201,
63+
BIT = 1,
64+
DATETIME='2024-01-01 09:00:01',
65+
DOUBLE = 3.1415926,
66+
FLOAT = 6.189,
67+
INTEGER = 8621,
68+
DECIMAL=910.79,
69+
LONGBLOB=text("repeat('x', 100)"),
70+
LONGTEXT = text("repeat('g', 3)"),
71+
MEDIUMBLOB = text("NULL"),
72+
MEDIUMINT = 999999,
73+
MEDIUMTEXT = text("NULL"),
74+
NUMERIC = 10.9,
75+
REAL = 1092.892,
76+
SMALLINT = 981,
77+
TEXT = "TEXT",
78+
TIME = '03:04:00',
79+
TIMESTAMP = "2024-07-24 09:05:28",
80+
YEAR = 2024,
81+
ENUM = "a",
82+
SET = "a,b,c",
83+
TINYBLOB = b"TINYBLOB",
84+
TINYINT = 99,
85+
TINYTEXT = "TINYTEXT",
86+
CHAR = "09283012",
87+
VARBINARY = b"VARBINARY",
88+
)
89+
session.add(test_data)
90+
session.commit()

src/pyinnodb/const/dd_column_type.py

+11-2
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,17 @@ def is_number(cls, t):
4545
return cls(t) in _number_type
4646

4747
@classmethod
48-
def is_var(cls, t):
49-
return cls(t) in _var_type
48+
def is_var(cls, t, mysqld_version=None):
49+
tt = cls(t)
50+
if tt != DDColumnType.STRING:
51+
return tt in _var_type
52+
else:
53+
if mysqld_version is None:
54+
return False
55+
elif mysqld_version < 80000:
56+
return False
57+
else:
58+
return True
5059

5160
@classmethod
5261
def is_big(cls, t):

src/pyinnodb/disk_struct/index.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ def value_parser(rh: MRecordHeader, f):
126126
logger.debug("record header is instant, with data version: %d", data_schema_version)
127127

128128
cols_disk_layout = [d for d in primary_data_layout_col if d[0].version_valid(data_schema_version)]
129-
logger.debug("primary data layout is %s", ",".join(c[0].name for c in primary_data_layout_col))
129+
logger.debug("primary data layout is %s", ",".join(f"{c[0].name}({c[0].ordinal_position})" for c in primary_data_layout_col))
130130

131131

132132
if rh.instant == 1:
@@ -158,9 +158,9 @@ def value_parser(rh: MRecordHeader, f):
158158
may_var_col = [
159159
(i, c[0])
160160
for i, c in enumerate(cols_disk_layout)
161-
if DDColumnType.is_big(c[0].type) or DDColumnType.is_var(c[0].type)
161+
if DDColumnType.is_big(c[0].type) or DDColumnType.is_var(c[0].type, mysqld_version=dd_object.mysql_version_id)
162162
]
163-
logger.debug("may_var_col is %s", ",".join(c.name for i, c in may_var_col))
163+
logger.debug("may_var_col is %s", ",".join(f"({i})({c.ordinal_position}){c.name}" for i, c in may_var_col))
164164

165165

166166
## read var

src/pyinnodb/disk_struct/varsize.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ def read_data(self, stream):
1919
logger.debug("blob header is %s", blob_header)
2020
return blob_header.get_data(stream)
2121
else:
22-
first_page = pointer.get_first_page(stream)
22+
first_page = self.get_first_page(stream)
2323
real_data = first_page.get_data(stream)
2424
return real_data
2525

src/pyinnodb/frm/frm.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ class MFrmColumn(CC): # 17
6767
def to_dd_column(self, name: str, pos: int, labels: typing.List[typing.List[str]]) -> Column:
6868
c = Column()
6969
c.hidden = const.column_hidden_type.ColumnHiddenType.HT_VISIBLE.value
70-
c.ordinal_position = pos
70+
c.ordinal_position = pos + 1
7171
if self.type_code < 20:
7272
c.type = self.type_code + 1
7373
else:
@@ -80,11 +80,15 @@ def to_dd_column(self, name: str, pos: int, labels: typing.List[typing.List[str]
8080
c.numeric_precision -= 1
8181
if c.numeric_precision:
8282
c.numeric_precision -= 1
83+
elif c.type == const.dd_column_type.DDColumnType.BIT.value:
84+
c.numeric_precision = self.length
8385
elif c.type in [const.dd_column_type.DDColumnType.ENUM.value,
8486
const.dd_column_type.DDColumnType.SET.value]:
8587
if self.label_id <= len(labels):
8688
for i, name in enumerate(labels[self.label_id-1]):
8789
c.elements.append(ColumnElement(name=b64encode(name), index=i+1))
90+
elif c.type == const.dd_column_type.DDColumnType.STRING.value:
91+
c.column_type_utf8 = f"char({self.length})"
8892

8993

9094
c.is_nullable = bool(self.flags & FieldFlag.MAYBE_NULL.value)

src/pyinnodb/sdi/table.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ def size(self):
232232
elif dtype == DDColumnType.SET: # bit mask
233233
return int((len(self.elements) + 7) / 8)
234234

235-
elif dtype == DDColumnType.STRING:
235+
elif dtype == DDColumnType.STRING: # if column don't have varsize
236236
sizes = column_type_size.findall(self.column_type_utf8)
237237
if len(sizes) == 0:
238238
return 0
@@ -403,7 +403,7 @@ def read_data(self, stream, size=None):
403403
return self._read_varchar(stream, dsize).decode(errors='replace').strip()
404404
elif dtype == DDColumnType.VARCHAR:
405405
return self._read_varchar(stream, dsize).decode(errors='replace')
406-
elif dtype in [DDColumnType.LONG_BLOB, DDColumnType.MEDIUM_BLOB]:
406+
elif dtype in [DDColumnType.LONG_BLOB, DDColumnType.MEDIUM_BLOB, DDColumnType.BLOB]:
407407
return self._read_varchar(stream, dsize).decode(errors='replace')
408408
elif dtype == DDColumnType.TINY_BLOB:
409409
return self._read_varchar(stream, dsize).decode(errors='replace')

0 commit comments

Comments
 (0)