This is an automated email from the ASF dual-hosted git repository.
JingsongLi pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/paimon.git
The following commit(s) were added to refs/heads/master by this push:
new 65c9a506c6 [python] Parse SQL NOT NULL case-insensitively in pypaimon
(#10373)
65c9a506c6 is described below
commit 65c9a506c6f934fb7c6ff947b3b3406a690c7857
Author: jackylee <[email protected]>
AuthorDate: Mon Oct 5 20:42:44 2026 +0800
[python] Parse SQL NOT NULL case-insensitively in pypaimon (#10373)
---
paimon-python/pypaimon/schema/data_types.py | 5 +++--
paimon-python/pypaimon/tests/data_types_test.py | 24 +++++++++++++++++++++++-
2 files changed, 26 insertions(+), 3 deletions(-)
diff --git a/paimon-python/pypaimon/schema/data_types.py
b/paimon-python/pypaimon/schema/data_types.py
index f4b176fe6f..6d420f0759 100755
--- a/paimon-python/pypaimon/schema/data_types.py
+++ b/paimon-python/pypaimon/schema/data_types.py
@@ -505,9 +505,10 @@ class DataTypeParser:
@staticmethod
def parse_nullability(type_string: str) -> bool:
- if "NOT NULL" in type_string:
+ type_upper = type_string.upper()
+ if "NOT NULL" in type_upper:
return False
- elif "NULL" in type_string:
+ elif "NULL" in type_upper:
return True
return True
diff --git a/paimon-python/pypaimon/tests/data_types_test.py
b/paimon-python/pypaimon/tests/data_types_test.py
index 8d0957fac0..e106f1fdf3 100755
--- a/paimon-python/pypaimon/tests/data_types_test.py
+++ b/paimon-python/pypaimon/tests/data_types_test.py
@@ -20,7 +20,7 @@ from parameterized import parameterized
import pyarrow as pa
from pypaimon.schema.data_types import (DataField, AtomicType, ArrayType,
MultisetType, MapType,
- RowType, VectorType,
PyarrowFieldParser,
+ RowType, VectorType,
PyarrowFieldParser, DataTypeParser,
is_blob_file_type)
@@ -83,6 +83,28 @@ class DataTypesTest(unittest.TestCase):
self.assertEqual(parsed.to_dict(), original.to_dict(), type_str)
PyarrowFieldParser.from_paimon_type(parsed)
+ def test_parse_nullability_is_case_insensitive(self):
+ # The CLI ``table alter --type`` path feeds the user's raw declaration
to
+ # the parser, and SQL type keywords are conventionally written
lowercase.
+ # A lowercase "not null" must still be read as NOT NULL rather than
being
+ # silently treated as nullable.
+ self.assertFalse(DataTypeParser.parse_nullability("bigint not null"))
+ self.assertFalse(DataTypeParser.parse_nullability("BIGINT NOT NULL"))
+ self.assertFalse(DataTypeParser.parse_nullability("Int Not Null"))
+ self.assertTrue(DataTypeParser.parse_nullability("bigint"))
+ self.assertTrue(DataTypeParser.parse_nullability("int null"))
+
+ def test_parse_atomic_type_lowercase_not_null(self):
+ # End to end: a lowercase declaration keeps NOT NULL through the atomic
+ # parser, for both plain and parameterized types.
+ parsed = DataTypeParser.parse_atomic_type_sql_string("bigint not null")
+ self.assertEqual(parsed.type, "BIGINT")
+ self.assertFalse(parsed.nullable)
+
+ parsed_decimal =
DataTypeParser.parse_atomic_type_sql_string("decimal(12, 2) not null")
+ self.assertEqual(parsed_decimal.type, "DECIMAL(12, 2)")
+ self.assertFalse(parsed_decimal.nullable)
+
@parameterized.expand([
(ArrayType, AtomicType("TIMESTAMP(6)"), "ARRAY<TIMESTAMP(6)>",
"ARRAY<ARRAY<TIMESTAMP(6)>>"),
(MultisetType, AtomicType("TIMESTAMP(6)"), "MULTISET<TIMESTAMP(6)>",
"MULTISET<MULTISET<TIMESTAMP(6)>>")