Skip to content

Commit a106a97

Browse files
committed
feat: Return not implemented errors instead of internal errors for unsupported types.
1 parent e171424 commit a106a97

File tree

2 files changed

+210
-10
lines changed

2 files changed

+210
-10
lines changed

src/from_substrait.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ Value TransformLiteralToValue(const substrait::Expression_Literal &literal) {
137137
case PhysicalType::INT128:
138138
return Value::DECIMAL(substrait_value, substrait_decimal.precision(), substrait_decimal.scale());
139139
default:
140-
throw InternalException("Not accepted internal type for decimal");
140+
throw NotImplementedException("Unsupported internal type for decimal: " + decimal_type.ToString());
141141
}
142142
}
143143
case substrait::Expression_Literal::LiteralTypeCase::kBoolean: {
@@ -174,7 +174,7 @@ Value TransformLiteralToValue(const substrait::Expression_Literal &literal) {
174174
case substrait::Expression_Literal::LiteralTypeCase::kVarChar:
175175
return {literal.var_char().value()};
176176
default:
177-
throw SyntaxException("literals of this type number are not implemented: " + to_string(literal.literal_type_case()));
177+
throw NotImplementedException("literals of this type number are not implemented: " + to_string(literal.literal_type_case()));
178178
}
179179
}
180180

@@ -184,7 +184,7 @@ unique_ptr<ParsedExpression> SubstraitToDuckDB::TransformLiteralExpr(const subst
184184

185185
unique_ptr<ParsedExpression> SubstraitToDuckDB::TransformSelectionExpr(const substrait::Expression &sexpr) {
186186
if (!sexpr.selection().has_direct_reference() || !sexpr.selection().direct_reference().has_struct_field()) {
187-
throw InternalException("Can only have direct struct references in selections");
187+
throw SyntaxException("Can only have direct struct references in selections");
188188
}
189189
return make_uniq<PositionalReferenceExpression>(sexpr.selection().direct_reference().struct_field().field() + 1);
190190
}
@@ -322,7 +322,7 @@ LogicalType SubstraitToDuckDB::SubstraitToDuckType(const substrait::Type &s_type
322322
case substrait::Type::KindCase::kFp64:
323323
return {LogicalTypeId::DOUBLE};
324324
default:
325-
throw NotImplementedException("Substrait type not yet supported");
325+
throw NotImplementedException("Substrait type not yet supported: " + to_string(s_type.kind_case()));
326326
}
327327
}
328328

@@ -408,13 +408,13 @@ unique_ptr<ParsedExpression> SubstraitToDuckDB::TransformExpr(const substrait::E
408408
return TransformNested(sexpr, iterator);
409409
case substrait::Expression::RexTypeCase::kSubquery:
410410
default:
411-
throw InternalException("Unsupported expression type " + to_string(sexpr.rex_type_case()));
411+
throw NotImplementedException("Unsupported expression type " + to_string(sexpr.rex_type_case()));
412412
}
413413
}
414414

415415
string SubstraitToDuckDB::FindFunction(uint64_t id) {
416416
if (functions_map.find(id) == functions_map.end()) {
417-
throw InternalException("Could not find aggregate function " + to_string(id));
417+
throw NotImplementedException("Could not find aggregate function " + to_string(id));
418418
}
419419
return functions_map[id];
420420
}
@@ -442,7 +442,7 @@ OrderByNode SubstraitToDuckDB::TransformOrder(const substrait::SortField &sordf)
442442
dnullorder = OrderByNullType::NULLS_LAST;
443443
break;
444444
default:
445-
throw InternalException("Unsupported ordering " + to_string(sordf.direction()));
445+
throw NotImplementedException("Unsupported ordering " + to_string(sordf.direction()));
446446
}
447447

448448
return {dordertype, dnullorder, TransformExpr(sordf.expr())};
@@ -472,7 +472,7 @@ shared_ptr<Relation> SubstraitToDuckDB::TransformJoinOp(const substrait::Rel &so
472472
djointype = JoinType::OUTER;
473473
break;
474474
default:
475-
throw InternalException("Unsupported join type");
475+
throw NotImplementedException("Unsupported join type: " + to_string(sjoin.type()));
476476
}
477477
unique_ptr<ParsedExpression> join_condition = TransformExpr(sjoin.expression());
478478
return make_shared_ptr<JoinRelation>(TransformOp(sjoin.left())->Alias("left"),
@@ -543,7 +543,7 @@ const substrait::RelCommon* GetCommon(const substrait::Rel &sop) {
543543
case substrait::Rel::RelTypeCase::kUpdate:
544544
case substrait::Rel::RelTypeCase::kDdl:
545545
default:
546-
throw InternalException("Unsupported relation type " + to_string(sop.rel_type_case()));
546+
throw NotImplementedException("Unsupported relation type " + to_string(sop.rel_type_case()));
547547
}
548548
}
549549

@@ -931,7 +931,7 @@ shared_ptr<Relation> SubstraitToDuckDB::TransformOp(const substrait::Rel &sop,
931931
case substrait::Rel::RelTypeCase::kWrite:
932932
return TransformWriteOp(sop);
933933
default:
934-
throw InternalException("Unsupported relation type " + to_string(sop.rel_type_case()));
934+
throw NotImplementedException("Unsupported relation type " + to_string(sop.rel_type_case()));
935935
}
936936
}
937937

test/sql/test_literals.test

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
# name: test/sql/test_types.test
2+
# description: Test type usage in substrait
3+
# group: [sql]
4+
5+
require substrait
6+
7+
statement ok
8+
PRAGMA enable_verification
9+
10+
# boolean
11+
query I
12+
CALL from_substrait_json('{"version":{"minorNumber":29, "producer":"substrait-go"}, "relations":[{"root":{"input":{"project":{"common":{"direct":{}}, "input":{"read":{"common":{"direct":{}}, "baseSchema":{"struct":{"nullability":"NULLABILITY_REQUIRED"}}, "virtualTable":{"expressions":[{}]}}}, "expressions":[{"literal":{"boolean":false, "nullable":true}}]}}, "names":["?column?"]}}]}')
13+
----
14+
false
15+
16+
# i8
17+
query I
18+
CALL from_substrait_json('{"version":{"minorNumber":29, "producer":"substrait-go"}, "relations":[{"root":{"input":{"project":{"common":{"direct":{}}, "input":{"read":{"common":{"direct":{}}, "baseSchema":{"struct":{"nullability":"NULLABILITY_REQUIRED"}}, "virtualTable":{"expressions":[{}]}}}, "expressions":[{"literal":{"i8":123, "nullable":true}}]}}, "names":["?column?"]}}]}')
19+
----
20+
123
21+
22+
# i16
23+
statement error
24+
CALL from_substrait_json('{"version":{"minorNumber":29, "producer":"substrait-go"}, "relations":[{"root":{"input":{"project":{"common":{"direct":{}}, "input":{"read":{"common":{"direct":{}}, "baseSchema":{"struct":{"nullability":"NULLABILITY_REQUIRED"}}, "virtualTable":{"expressions":[{}]}}}, "expressions":[{"literal":{"i16":123, "nullable":true}}]}}, "names":["?column?"]}}]}')
25+
----
26+
Not implemented Error: literals of this type number are not implemented: 3
27+
28+
# i32
29+
query I
30+
CALL from_substrait_json('{"version":{"minorNumber":29, "producer":"substrait-go"}, "relations":[{"root":{"input":{"project":{"common":{"direct":{}}, "input":{"read":{"common":{"direct":{}}, "baseSchema":{"struct":{"nullability":"NULLABILITY_REQUIRED"}}, "virtualTable":{"expressions":[{}]}}}, "expressions":[{"literal":{"i32":123, "nullable":true}}]}}, "names":["?column?"]}}]}')
31+
----
32+
123
33+
34+
# i64
35+
query I
36+
CALL from_substrait_json('{"version":{"minorNumber":29, "producer":"substrait-go"}, "relations":[{"root":{"input":{"project":{"common":{"direct":{}}, "input":{"read":{"common":{"direct":{}}, "baseSchema":{"struct":{"nullability":"NULLABILITY_REQUIRED"}}, "virtualTable":{"expressions":[{}]}}}, "expressions":[{"literal":{"i64":123, "nullable":true}}]}}, "names":["?column?"]}}]}')
37+
----
38+
123
39+
40+
# fp32
41+
query I
42+
CALL from_substrait_json('{"version":{"minorNumber":29, "producer":"substrait-go"}, "relations":[{"root":{"input":{"project":{"common":{"direct":{}}, "input":{"read":{"common":{"direct":{}}, "baseSchema":{"struct":{"nullability":"NULLABILITY_REQUIRED"}}, "virtualTable":{"expressions":[{}]}}}, "expressions":[{"literal":{"fp32":123, "nullable":true}}]}}, "names":["?column?"]}}]}')
43+
----
44+
123.0
45+
46+
# fp64
47+
query I
48+
CALL from_substrait_json('{"version":{"minorNumber":29, "producer":"substrait-go"}, "relations":[{"root":{"input":{"project":{"common":{"direct":{}}, "input":{"read":{"common":{"direct":{}}, "baseSchema":{"struct":{"nullability":"NULLABILITY_REQUIRED"}}, "virtualTable":{"expressions":[{}]}}}, "expressions":[{"literal":{"fp64":123, "nullable":true}}]}}, "names":["?column?"]}}]}')
49+
----
50+
123.0
51+
52+
# string
53+
query I
54+
CALL from_substrait_json('{"version":{"minorNumber":29, "producer":"substrait-go"}, "relations":[{"root":{"input":{"project":{"common":{"direct":{}}, "input":{"read":{"common":{"direct":{}}, "baseSchema":{"struct":{"nullability":"NULLABILITY_REQUIRED"}}, "virtualTable":{"expressions":[{}]}}}, "expressions":[{"literal":{"string":"abc", "nullable":true}}]}}, "names":["?column?"]}}]}')
55+
----
56+
abc
57+
58+
# binary
59+
statement error
60+
CALL from_substrait_json('{"version":{"minorNumber":29, "producer":"substrait-go"}, "relations":[{"root":{"input":{"project":{"common":{"direct":{}}, "input":{"read":{"common":{"direct":{}}, "baseSchema":{"struct":{"nullability":"NULLABILITY_REQUIRED"}}, "virtualTable":{"expressions":[{}]}}}, "expressions":[{"literal":{"binary":"XDAwXDAxXDAy", "nullable":true}}]}}, "names":["?column?"]}}]}')
61+
----
62+
Not implemented Error: literals of this type number are not implemented: 13
63+
64+
# timestamp
65+
statement error
66+
CALL from_substrait_json('{"version":{"minorNumber":29, "producer":"substrait-go"}, "relations":[{"root":{"input":{"project":{"common":{"direct":{}}, "input":{"read":{"common":{"direct":{}}, "baseSchema":{"struct":{"nullability":"NULLABILITY_REQUIRED"}}, "virtualTable":{"expressions":[{}]}}}, "expressions":[{"literal":{"timestamp":99999999, "nullable":true}}]}}, "names":["?column?"]}}]}')
67+
----
68+
Not implemented Error: literals of this type number are not implemented: 14
69+
70+
# date
71+
query I
72+
CALL from_substrait_json('{"version":{"minorNumber":29, "producer":"substrait-go"}, "relations":[{"root":{"input":{"project":{"common":{"direct":{}}, "input":{"read":{"common":{"direct":{}}, "baseSchema":{"struct":{"nullability":"NULLABILITY_REQUIRED"}}, "virtualTable":{"expressions":[{}]}}}, "expressions":[{"literal":{"date":9999, "nullable":true}}]}}, "names":["?column?"]}}]}')
73+
----
74+
1997-05-18
75+
76+
# time
77+
query I
78+
CALL from_substrait_json('{"version":{"minorNumber":29, "producer":"substrait-go"}, "relations":[{"root":{"input":{"project":{"common":{"direct":{}}, "input":{"read":{"common":{"direct":{}}, "baseSchema":{"struct":{"nullability":"NULLABILITY_REQUIRED"}}, "virtualTable":{"expressions":[{}]}}}, "expressions":[{"literal":{"time":99999999, "nullable":true}}]}}, "names":["?column?"]}}]}')
79+
----
80+
00:01:39.999999
81+
82+
# interval year to month (wrong, should include be 38 months)
83+
query I
84+
CALL from_substrait_json('{"version":{"minorNumber":29, "producer":"substrait-go"}, "relations":[{"root":{"input":{"project":{"common":{"direct":{}}, "input":{"read":{"common":{"direct":{}}, "baseSchema":{"struct":{"nullability":"NULLABILITY_REQUIRED"}}, "virtualTable":{"expressions":[{}]}}}, "expressions":[{"literal":{"interval_year_to_month":{"years":3,"months":2}, "nullable":true}}]}}, "names":["?column?"]}}]}')
85+
----
86+
2 months
87+
88+
# interval day to second (deprecated microseconds) (wrong, should include seconds)
89+
query I
90+
CALL from_substrait_json('{"version":{"minorNumber":29, "producer":"substrait-go"}, "relations":[{"root":{"input":{"project":{"common":{"direct":{}}, "input":{"read":{"common":{"direct":{}}, "baseSchema":{"struct":{"nullability":"NULLABILITY_REQUIRED"}}, "virtualTable":{"expressions":[{}]}}}, "expressions":[{"literal":{"interval_day_to_second":{"days":3,"seconds":2,"microseconds":23}, "nullable":true}}]}}, "names":["?column?"]}}]}')
91+
----
92+
3 days 00:00:00.000023
93+
94+
# interval day to second (precision) (wrong, should include seconds and subseconds)
95+
query I
96+
CALL from_substrait_json('{"version":{"minorNumber":29, "producer":"substrait-go"}, "relations":[{"root":{"input":{"project":{"common":{"direct":{}}, "input":{"read":{"common":{"direct":{}}, "baseSchema":{"struct":{"nullability":"NULLABILITY_REQUIRED"}}, "virtualTable":{"expressions":[{}]}}}, "expressions":[{"literal":{"interval_day_to_second":{"days":3,"seconds":2,"precision":9,"subseconds":23}, "nullable":true}}]}}, "names":["?column?"]}}]}')
97+
----
98+
3 days
99+
100+
# interval compound
101+
statement error
102+
CALL from_substrait_json('{"version":{"minorNumber":29, "producer":"substrait-go"}, "relations":[{"root":{"input":{"project":{"common":{"direct":{}}, "input":{"read":{"common":{"direct":{}}, "baseSchema":{"struct":{"nullability":"NULLABILITY_REQUIRED"}}, "virtualTable":{"expressions":[{}]}}}, "expressions":[{"literal":{"interval_compound":{"interval_year_to_month":{"years":3,"months":2}, "interval_day_to_second":{"days":3,"seconds":2,"precision":9,"subseconds":23}}, "nullable":true}}]}}, "names":["?column?"]}}]}')
103+
----
104+
Not implemented Error: literals of this type number are not implemented: 36
105+
106+
# fixed char
107+
statement error
108+
CALL from_substrait_json('{"version":{"minorNumber":29, "producer":"substrait-go"}, "relations":[{"root":{"input":{"project":{"common":{"direct":{}}, "input":{"read":{"common":{"direct":{}}, "baseSchema":{"struct":{"nullability":"NULLABILITY_REQUIRED"}}, "virtualTable":{"expressions":[{}]}}}, "expressions":[{"literal":{"fixed_char":"abcd", "nullable":true}}]}}, "names":["?column?"]}}]}')
109+
----
110+
Not implemented Error: literals of this type number are not implemented: 21
111+
112+
# var char
113+
query I
114+
CALL from_substrait_json('{"version":{"minorNumber":29, "producer":"substrait-go"}, "relations":[{"root":{"input":{"project":{"common":{"direct":{}}, "input":{"read":{"common":{"direct":{}}, "baseSchema":{"struct":{"nullability":"NULLABILITY_REQUIRED"}}, "virtualTable":{"expressions":[{}]}}}, "expressions":[{"literal":{"var_char":{"value":"abcd","length":4}, "nullable":true}}]}}, "names":["?column?"]}}]}')
115+
----
116+
abcd
117+
118+
# fixed binary
119+
statement error
120+
CALL from_substrait_json('{"version":{"minorNumber":29, "producer":"substrait-go"}, "relations":[{"root":{"input":{"project":{"common":{"direct":{}}, "input":{"read":{"common":{"direct":{}}, "baseSchema":{"struct":{"nullability":"NULLABILITY_REQUIRED"}}, "virtualTable":{"expressions":[{}]}}}, "expressions":[{"literal":{"fixed_binary":"XDAwXDAxXDAy", "nullable":true}}]}}, "names":["?column?"]}}]}')
121+
----
122+
Not implemented Error: literals of this type number are not implemented: 23
123+
124+
# decimal invalid
125+
statement error
126+
CALL from_substrait_json('{"version":{"minorNumber":29, "producer":"substrait-go"}, "relations":[{"root":{"input":{"project":{"common":{"direct":{}}, "input":{"read":{"common":{"direct":{}}, "baseSchema":{"struct":{"nullability":"NULLABILITY_REQUIRED"}}, "virtualTable":{"expressions":[{}]}}}, "expressions":[{"literal":{"decimal":{"value":"AQ==", "precision":1}, "nullable":true}}]}}, "names":["?column?"]}}]}')
127+
----
128+
Invalid Input Error: Decimal value must have 16 bytes, but has 1
129+
130+
# decimal ok
131+
query I
132+
CALL from_substrait_json('{"version":{"minorNumber":29, "producer":"substrait-go"}, "relations":[{"root":{"input":{"project":{"common":{"direct":{}}, "input":{"read":{"common":{"direct":{}}, "baseSchema":{"struct":{"nullability":"NULLABILITY_REQUIRED"}}, "virtualTable":{"expressions":[{}]}}}, "expressions":[{"literal":{"decimal":{"value":"AQAAAAAAAAAAAAAAAAAAAA==", "precision":1}, "nullable":true}}]}}, "names":["?column?"]}}]}')
133+
----
134+
1
135+
136+
# precision timestamp
137+
statement error
138+
CALL from_substrait_json('{"version":{"minorNumber":29, "producer":"substrait-go"}, "relations":[{"root":{"input":{"project":{"common":{"direct":{}}, "input":{"read":{"common":{"direct":{}}, "baseSchema":{"struct":{"nullability":"NULLABILITY_REQUIRED"}}, "virtualTable":{"expressions":[{}]}}}, "expressions":[{"literal":{"precision_timestamp":{"value":9999,"precision":3}, "nullable":true}}]}}, "names":["?column?"]}}]}')
139+
----
140+
Not implemented Error: literals of this type number are not implemented: 34
141+
142+
# precision timestamp tz
143+
statement error
144+
CALL from_substrait_json('{"version":{"minorNumber":29, "producer":"substrait-go"}, "relations":[{"root":{"input":{"project":{"common":{"direct":{}}, "input":{"read":{"common":{"direct":{}}, "baseSchema":{"struct":{"nullability":"NULLABILITY_REQUIRED"}}, "virtualTable":{"expressions":[{}]}}}, "expressions":[{"literal":{"precision_timestamp_tz":{"value":9999,"precision":3}, "nullable":true}}]}}, "names":["?column?"]}}]}')
145+
----
146+
Not implemented Error: literals of this type number are not implemented: 35
147+
148+
# struct
149+
statement error
150+
CALL from_substrait_json('{"version":{"minorNumber":29, "producer":"substrait-go"}, "relations":[{"root":{"input":{"project":{"common":{"direct":{}}, "input":{"read":{"common":{"direct":{}}, "baseSchema":{"struct":{"nullability":"NULLABILITY_REQUIRED"}}, "virtualTable":{"expressions":[{}]}}}, "expressions":[{"literal":{"struct":{}, "nullable":true}}]}}, "names":["?column?"]}}]}')
151+
----
152+
Not implemented Error: literals of this type number are not implemented: 25
153+
154+
# map
155+
statement error
156+
CALL from_substrait_json('{"version":{"minorNumber":29, "producer":"substrait-go"}, "relations":[{"root":{"input":{"project":{"common":{"direct":{}}, "input":{"read":{"common":{"direct":{}}, "baseSchema":{"struct":{"nullability":"NULLABILITY_REQUIRED"}}, "virtualTable":{"expressions":[{}]}}}, "expressions":[{"literal":{"map":{}, "nullable":true}}]}}, "names":["?column?"]}}]}')
157+
----
158+
Not implemented Error: literals of this type number are not implemented: 26
159+
160+
# timestamp_tz
161+
statement error
162+
CALL from_substrait_json('{"version":{"minorNumber":29, "producer":"substrait-go"}, "relations":[{"root":{"input":{"project":{"common":{"direct":{}}, "input":{"read":{"common":{"direct":{}}, "baseSchema":{"struct":{"nullability":"NULLABILITY_REQUIRED"}}, "virtualTable":{"expressions":[{}]}}}, "expressions":[{"literal":{"timestamp_tz":99999999, "nullable":true}}]}}, "names":["?column?"]}}]}')
163+
----
164+
Not implemented Error: literals of this type number are not implemented: 27
165+
166+
# uuid
167+
statement error
168+
CALL from_substrait_json('{"version":{"minorNumber":29, "producer":"substrait-go"}, "relations":[{"root":{"input":{"project":{"common":{"direct":{}}, "input":{"read":{"common":{"direct":{}}, "baseSchema":{"struct":{"nullability":"NULLABILITY_REQUIRED"}}, "virtualTable":{"expressions":[{}]}}}, "expressions":[{"literal":{"uuid":"XDAwXDAxXDAy", "nullable":true}}]}}, "names":["?column?"]}}]}')
169+
----
170+
Not implemented Error: literals of this type number are not implemented: 28
171+
172+
# null i8
173+
query I
174+
CALL from_substrait_json('{"version":{"minorNumber":29, "producer":"substrait-go"}, "relations":[{"root":{"input":{"project":{"common":{"direct":{}}, "input":{"read":{"common":{"direct":{}}, "baseSchema":{"struct":{"nullability":"NULLABILITY_REQUIRED"}}, "virtualTable":{"expressions":[{}]}}}, "expressions":[{"literal":{"null":{"i8":{"nullability":"NULLABILITY_REQUIRED"}}}}]}}, "names":["?column?"]}}]}')
175+
----
176+
NULL
177+
178+
# list
179+
statement error
180+
CALL from_substrait_json('{"version":{"minorNumber":29, "producer":"substrait-go"}, "relations":[{"root":{"input":{"project":{"common":{"direct":{}}, "input":{"read":{"common":{"direct":{}}, "baseSchema":{"struct":{"nullability":"NULLABILITY_REQUIRED"}}, "virtualTable":{"expressions":[{}]}}}, "expressions":[{"literal":{"list":{}, "nullable":true}}]}}, "names":["?column?"]}}]}')
181+
----
182+
Not implemented Error: literals of this type number are not implemented: 30
183+
184+
# empty list
185+
statement error
186+
CALL from_substrait_json('{"version":{"minorNumber":29, "producer":"substrait-go"}, "relations":[{"root":{"input":{"project":{"common":{"direct":{}}, "input":{"read":{"common":{"direct":{}}, "baseSchema":{"struct":{"nullability":"NULLABILITY_REQUIRED"}}, "virtualTable":{"expressions":[{}]}}}, "expressions":[{"literal":{"empty_list":{}, "nullable":true}}]}}, "names":["?column?"]}}]}')
187+
----
188+
Not implemented Error: literals of this type number are not implemented: 31
189+
190+
# empty map
191+
statement error
192+
CALL from_substrait_json('{"version":{"minorNumber":29, "producer":"substrait-go"}, "relations":[{"root":{"input":{"project":{"common":{"direct":{}}, "input":{"read":{"common":{"direct":{}}, "baseSchema":{"struct":{"nullability":"NULLABILITY_REQUIRED"}}, "virtualTable":{"expressions":[{}]}}}, "expressions":[{"literal":{"empty_map":{}, "nullable":true}}]}}, "names":["?column?"]}}]}')
193+
----
194+
Not implemented Error: literals of this type number are not implemented: 32
195+
196+
# user defined
197+
statement error
198+
CALL from_substrait_json('{"version":{"minorNumber":29, "producer":"substrait-go"}, "relations":[{"root":{"input":{"project":{"common":{"direct":{}}, "input":{"read":{"common":{"direct":{}}, "baseSchema":{"struct":{"nullability":"NULLABILITY_REQUIRED"}}, "virtualTable":{"expressions":[{}]}}}, "expressions":[{"literal":{"user_defined":{}, "nullable":true}}]}}, "names":["?column?"]}}]}')
199+
----
200+
Not implemented Error: literals of this type number are not implemented: 33

0 commit comments

Comments
 (0)