Skip to content

Commit e58ab56

Browse files
authored
PostgreSQL: forbid unsupported numeric types (#341)
1 parent fc4597f commit e58ab56

File tree

5 files changed

+27
-13
lines changed

5 files changed

+27
-13
lines changed

app/server/datasource/interface.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ type ColumnDescription struct {
6262
Name string // mandatory
6363
Type string // mandatory
6464
Precision *uint8 // filled only for numeric columns
65-
Scale *uint8 // filled only for numeric columns
65+
Scale *int8 // filled only for numeric columns
6666
}
6767

6868
type TypeMapper interface {

app/server/datasource/rdbms/clickhouse/table_metadata_query.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ import (
66
)
77

88
func TableMetadataQuery(request *api_service_protos.TDescribeTableRequest) (string, *rdbms_utils.QueryArgs) {
9-
query := "SELECT name, type, numeric_precision, numeric_scale FROM system.columns WHERE table = ? and database = ?"
9+
query := `SELECT name, type, numeric_precision, toInt64(numeric_scale)
10+
FROM system.columns WHERE table = ? and database = ?`
1011

1112
var args rdbms_utils.QueryArgs
1213

app/server/datasource/rdbms/postgresql/type_mapping.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,20 @@ func (typeMapper) maybeNumericType(columnDescription *datasource.ColumnDescripti
115115
return nil, nil
116116
}
117117

118-
if columnDescription.Precision == nil || columnDescription.Scale == nil {
119-
return nil, fmt.Errorf("for numeric type both precision and scale must be filled")
118+
if columnDescription.Precision == nil {
119+
return nil, fmt.Errorf("unconstrained numeric types with arbitrary precision are not supported")
120+
}
121+
122+
if *columnDescription.Precision > 35 {
123+
return nil, fmt.Errorf("precision of a numeric type must be less or equal to 35")
124+
}
125+
126+
if columnDescription.Scale == nil {
127+
return nil, fmt.Errorf("scale must be specified for numeric types")
128+
}
129+
130+
if *columnDescription.Scale < 0 {
131+
return nil, fmt.Errorf("scale must be non-negative")
120132
}
121133

122134
return common.MakeDecimalType(uint32(*columnDescription.Precision), uint32(*columnDescription.Scale)), nil

app/server/datasource/rdbms/utils/schema_provider.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,37 +40,37 @@ func (f *defaultSchemaProvider) GetSchema(
4040

4141
defer func() { common.LogCloserError(logger, rows, "close rows") }()
4242

43-
var cd datasource.ColumnDescription
44-
4543
sb := NewSchemaBuilder(f.typeMapper, request.TypeMappingSettings)
4644

4745
var (
4846
columnName *string
4947
typeName *string
5048
precision *uint64
51-
scale *uint64
49+
scale *int64
5250
)
5351

5452
for rows.Next() {
5553
if err = rows.Scan(&columnName, &typeName, &precision, &scale); err != nil {
5654
return nil, fmt.Errorf("rows scan: %w", err)
5755
}
5856

59-
cd.Name = *columnName
60-
cd.Type = *typeName
57+
cd := &datasource.ColumnDescription{
58+
Name: *columnName,
59+
Type: *typeName,
60+
}
6161

6262
if precision != nil {
6363
cd.Precision = new(uint8)
6464
*cd.Precision = uint8(*precision)
6565
}
6666

6767
if scale != nil {
68-
cd.Scale = new(uint8)
69-
*cd.Scale = uint8(*scale)
68+
cd.Scale = new(int8)
69+
*cd.Scale = int8(*scale)
7070
}
7171

72-
if err = sb.AddColumn(&cd); err != nil {
73-
return nil, fmt.Errorf("add column to schema builder: %w", err)
72+
if err = sb.AddColumn(cd); err != nil {
73+
return nil, fmt.Errorf("add column `%s` to schema builder: %w", cd.Name, err)
7474
}
7575
}
7676

scripts/debug/kqprun/script.postgresql.local.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ SELECT col_27_numeric_int, col_28_numeric_rational FROM external_datasource.prim
66

77
-- SELECT col_27_numeric_int, col_28_numeric_rational FROM external_datasource.primitives WHERE col_28_numeric_rational = Decimal("-22.22", 4, 2);
88

9+

0 commit comments

Comments
 (0)