diff --git a/meta/src/meta/grammar.y b/meta/src/meta/grammar.y index e59d3a38..f5ef184d 100644 --- a/meta/src/meta/grammar.y +++ b/meta/src/meta/grammar.y @@ -1456,9 +1456,11 @@ export_iceberg_config def _extract_value_int32(value: Optional[logic.Value], default: int) -> Int32: - if value is not None and builtin.has_proto_field(builtin.unwrap_option(value), 'int32_value'): + if value is None: + return builtin.int64_to_int32(default) + if builtin.has_proto_field(builtin.unwrap_option(value), 'int32_value'): return builtin.unwrap_option(value).int32_value - return builtin.int64_to_int32(default) + builtin.error("expected an int32 value (e.g. `1i32`) for this config field") def _extract_value_int64(value: Optional[logic.Value], default: int) -> int: diff --git a/sdks/go/src/parser.go b/sdks/go/src/parser.go index dc0ac259..eadde440 100644 --- a/sdks/go/src/parser.go +++ b/sdks/go/src/parser.go @@ -656,205 +656,210 @@ func toPascalCase(s string) string { func (p *Parser) _extract_value_int32(value *pb.Value, default_ int64) int32 { var _t2212 interface{} - if (value != nil && hasProtoField(value, "int32_value")) { - return value.GetInt32Value() + if value == nil { + return int32(default_) } _ = _t2212 - return int32(default_) + var _t2213 interface{} + if hasProtoField(value, "int32_value") { + return value.GetInt32Value() + } + _ = _t2213 + panic(ParseError{msg: "expected an int32 value (e.g. `1i32`) for this config field"}) } func (p *Parser) _extract_value_int64(value *pb.Value, default_ int64) int64 { - var _t2213 interface{} + var _t2214 interface{} if (value != nil && hasProtoField(value, "int_value")) { return value.GetIntValue() } - _ = _t2213 + _ = _t2214 return default_ } func (p *Parser) _extract_value_string(value *pb.Value, default_ string) string { - var _t2214 interface{} + var _t2215 interface{} if (value != nil && hasProtoField(value, "string_value")) { return value.GetStringValue() } - _ = _t2214 + _ = _t2215 return default_ } func (p *Parser) _extract_value_boolean(value *pb.Value, default_ bool) bool { - var _t2215 interface{} + var _t2216 interface{} if (value != nil && hasProtoField(value, "boolean_value")) { return value.GetBooleanValue() } - _ = _t2215 + _ = _t2216 return default_ } func (p *Parser) _extract_value_string_list(value *pb.Value, default_ []string) []string { - var _t2216 interface{} + var _t2217 interface{} if (value != nil && hasProtoField(value, "string_value")) { return []string{value.GetStringValue()} } - _ = _t2216 + _ = _t2217 return default_ } func (p *Parser) _try_extract_value_int64(value *pb.Value) *int64 { - var _t2217 interface{} + var _t2218 interface{} if (value != nil && hasProtoField(value, "int_value")) { return ptr(value.GetIntValue()) } - _ = _t2217 + _ = _t2218 return nil } func (p *Parser) _try_extract_value_float64(value *pb.Value) *float64 { - var _t2218 interface{} + var _t2219 interface{} if (value != nil && hasProtoField(value, "float_value")) { return ptr(value.GetFloatValue()) } - _ = _t2218 + _ = _t2219 return nil } func (p *Parser) _try_extract_value_bytes(value *pb.Value) []byte { - var _t2219 interface{} + var _t2220 interface{} if (value != nil && hasProtoField(value, "string_value")) { return []byte(value.GetStringValue()) } - _ = _t2219 + _ = _t2220 return nil } func (p *Parser) _try_extract_value_uint128(value *pb.Value) *pb.UInt128Value { - var _t2220 interface{} + var _t2221 interface{} if (value != nil && hasProtoField(value, "uint128_value")) { return value.GetUint128Value() } - _ = _t2220 + _ = _t2221 return nil } func (p *Parser) construct_non_cdc_relations(targets []*pb.TargetRelation) *pb.TargetRelations { - _t2221 := &pb.PlainTargets{Targets: targets} - _t2222 := &pb.TargetRelations{Keys: []*pb.NamedColumn{}} - _t2222.Body = &pb.TargetRelations_Plain{Plain: _t2221} - return _t2222 + _t2222 := &pb.PlainTargets{Targets: targets} + _t2223 := &pb.TargetRelations{Keys: []*pb.NamedColumn{}} + _t2223.Body = &pb.TargetRelations_Plain{Plain: _t2222} + return _t2223 } func (p *Parser) construct_cdc_relations(inserts []*pb.TargetRelation, deletes []*pb.TargetRelation) *pb.TargetRelations { - _t2223 := &pb.CDCTargets{Inserts: inserts, Deletes: deletes} - _t2224 := &pb.TargetRelations{Keys: []*pb.NamedColumn{}} - _t2224.Body = &pb.TargetRelations_Cdc{Cdc: _t2223} - return _t2224 + _t2224 := &pb.CDCTargets{Inserts: inserts, Deletes: deletes} + _t2225 := &pb.TargetRelations{Keys: []*pb.NamedColumn{}} + _t2225.Body = &pb.TargetRelations_Cdc{Cdc: _t2224} + return _t2225 } func (p *Parser) construct_relations(keys []*pb.NamedColumn, body *pb.TargetRelations) *pb.TargetRelations { - var _t2225 interface{} + var _t2226 interface{} if hasProtoField(body, "plain") { - _t2226 := &pb.TargetRelations{Keys: keys} - _t2226.Body = &pb.TargetRelations_Plain{Plain: body.GetPlain()} - return _t2226 + _t2227 := &pb.TargetRelations{Keys: keys} + _t2227.Body = &pb.TargetRelations_Plain{Plain: body.GetPlain()} + return _t2227 } - _ = _t2225 - _t2227 := &pb.TargetRelations{Keys: keys} - _t2227.Body = &pb.TargetRelations_Cdc{Cdc: body.GetCdc()} - return _t2227 + _ = _t2226 + _t2228 := &pb.TargetRelations{Keys: keys} + _t2228.Body = &pb.TargetRelations_Cdc{Cdc: body.GetCdc()} + return _t2228 } func (p *Parser) construct_csv_data(locator *pb.CSVLocator, config *pb.CSVConfig, columns_opt []*pb.GNFColumn, relations_opt *pb.TargetRelations, asof string) *pb.CSVData { - _t2228 := columns_opt + _t2229 := columns_opt if columns_opt == nil { - _t2228 = []*pb.GNFColumn{} + _t2229 = []*pb.GNFColumn{} } - _t2229 := &pb.CSVData{Locator: locator, Config: config, Columns: _t2228, Asof: asof, Relations: relations_opt} - return _t2229 + _t2230 := &pb.CSVData{Locator: locator, Config: config, Columns: _t2229, Asof: asof, Relations: relations_opt} + return _t2230 } func (p *Parser) construct_csv_config(config_dict [][]interface{}, storage_integration_opt [][]interface{}) *pb.CSVConfig { config := dictFromList(config_dict) - _t2230 := p._extract_value_int32(dictGetValue(config, "csv_header_row"), 1) - header_row := _t2230 - _t2231 := p._extract_value_int64(dictGetValue(config, "csv_skip"), 0) - skip := _t2231 - _t2232 := p._extract_value_string(dictGetValue(config, "csv_new_line"), "") - new_line := _t2232 - _t2233 := p._extract_value_string(dictGetValue(config, "csv_delimiter"), ",") - delimiter := _t2233 - _t2234 := p._extract_value_string(dictGetValue(config, "csv_quotechar"), "\"") - quotechar := _t2234 - _t2235 := p._extract_value_string(dictGetValue(config, "csv_escapechar"), "\"") - escapechar := _t2235 - _t2236 := p._extract_value_string(dictGetValue(config, "csv_comment"), "") - comment := _t2236 - _t2237 := p._extract_value_string_list(dictGetValue(config, "csv_missing_strings"), []string{}) - missing_strings := _t2237 - _t2238 := p._extract_value_string(dictGetValue(config, "csv_decimal_separator"), ".") - decimal_separator := _t2238 - _t2239 := p._extract_value_string(dictGetValue(config, "csv_encoding"), "utf-8") - encoding := _t2239 - _t2240 := p._extract_value_string(dictGetValue(config, "csv_compression"), "") - compression := _t2240 - _t2241 := p._extract_value_int64(dictGetValue(config, "csv_partition_size_mb"), 0) - partition_size_mb := _t2241 - _t2242 := p.construct_csv_storage_integration(storage_integration_opt) - storage_integration := _t2242 - _t2243 := &pb.CSVConfig{HeaderRow: header_row, Skip: skip, NewLine: new_line, Delimiter: delimiter, Quotechar: quotechar, Escapechar: escapechar, Comment: comment, MissingStrings: missing_strings, DecimalSeparator: decimal_separator, Encoding: encoding, Compression: compression, PartitionSizeMb: partition_size_mb, StorageIntegration: storage_integration} - return _t2243 + _t2231 := p._extract_value_int32(dictGetValue(config, "csv_header_row"), 1) + header_row := _t2231 + _t2232 := p._extract_value_int64(dictGetValue(config, "csv_skip"), 0) + skip := _t2232 + _t2233 := p._extract_value_string(dictGetValue(config, "csv_new_line"), "") + new_line := _t2233 + _t2234 := p._extract_value_string(dictGetValue(config, "csv_delimiter"), ",") + delimiter := _t2234 + _t2235 := p._extract_value_string(dictGetValue(config, "csv_quotechar"), "\"") + quotechar := _t2235 + _t2236 := p._extract_value_string(dictGetValue(config, "csv_escapechar"), "\"") + escapechar := _t2236 + _t2237 := p._extract_value_string(dictGetValue(config, "csv_comment"), "") + comment := _t2237 + _t2238 := p._extract_value_string_list(dictGetValue(config, "csv_missing_strings"), []string{}) + missing_strings := _t2238 + _t2239 := p._extract_value_string(dictGetValue(config, "csv_decimal_separator"), ".") + decimal_separator := _t2239 + _t2240 := p._extract_value_string(dictGetValue(config, "csv_encoding"), "utf-8") + encoding := _t2240 + _t2241 := p._extract_value_string(dictGetValue(config, "csv_compression"), "") + compression := _t2241 + _t2242 := p._extract_value_int64(dictGetValue(config, "csv_partition_size_mb"), 0) + partition_size_mb := _t2242 + _t2243 := p.construct_csv_storage_integration(storage_integration_opt) + storage_integration := _t2243 + _t2244 := &pb.CSVConfig{HeaderRow: header_row, Skip: skip, NewLine: new_line, Delimiter: delimiter, Quotechar: quotechar, Escapechar: escapechar, Comment: comment, MissingStrings: missing_strings, DecimalSeparator: decimal_separator, Encoding: encoding, Compression: compression, PartitionSizeMb: partition_size_mb, StorageIntegration: storage_integration} + return _t2244 } func (p *Parser) construct_csv_storage_integration(storage_integration_opt [][]interface{}) *pb.StorageIntegration { - var _t2244 interface{} + var _t2245 interface{} if storage_integration_opt == nil { return nil } - _ = _t2244 + _ = _t2245 config := dictFromList(storage_integration_opt) - _t2245 := p._extract_value_string(dictGetValue(config, "provider"), "") - _t2246 := p._extract_value_string(dictGetValue(config, "azure_sas_token"), "") - _t2247 := p._extract_value_string(dictGetValue(config, "s3_region"), "") - _t2248 := p._extract_value_string(dictGetValue(config, "s3_access_key_id"), "") - _t2249 := p._extract_value_string(dictGetValue(config, "s3_secret_access_key"), "") - _t2250 := &pb.StorageIntegration{Provider: _t2245, AzureSasToken: _t2246, S3Region: _t2247, S3AccessKeyId: _t2248, S3SecretAccessKey: _t2249} - return _t2250 + _t2246 := p._extract_value_string(dictGetValue(config, "provider"), "") + _t2247 := p._extract_value_string(dictGetValue(config, "azure_sas_token"), "") + _t2248 := p._extract_value_string(dictGetValue(config, "s3_region"), "") + _t2249 := p._extract_value_string(dictGetValue(config, "s3_access_key_id"), "") + _t2250 := p._extract_value_string(dictGetValue(config, "s3_secret_access_key"), "") + _t2251 := &pb.StorageIntegration{Provider: _t2246, AzureSasToken: _t2247, S3Region: _t2248, S3AccessKeyId: _t2249, S3SecretAccessKey: _t2250} + return _t2251 } func (p *Parser) construct_betree_info(key_types []*pb.Type, value_types []*pb.Type, config_dict [][]interface{}) *pb.BeTreeInfo { config := dictFromList(config_dict) - _t2251 := p._try_extract_value_float64(dictGetValue(config, "betree_config_epsilon")) - epsilon := _t2251 - _t2252 := p._try_extract_value_int64(dictGetValue(config, "betree_config_max_pivots")) - max_pivots := _t2252 - _t2253 := p._try_extract_value_int64(dictGetValue(config, "betree_config_max_deltas")) - max_deltas := _t2253 - _t2254 := p._try_extract_value_int64(dictGetValue(config, "betree_config_max_leaf")) - max_leaf := _t2254 - _t2255 := &pb.BeTreeConfig{Epsilon: deref(epsilon, 0.0), MaxPivots: deref(max_pivots, 0), MaxDeltas: deref(max_deltas, 0), MaxLeaf: deref(max_leaf, 0)} - storage_config := _t2255 - _t2256 := p._try_extract_value_uint128(dictGetValue(config, "betree_locator_root_pageid")) - root_pageid := _t2256 - _t2257 := p._try_extract_value_bytes(dictGetValue(config, "betree_locator_inline_data")) - inline_data := _t2257 - _t2258 := p._try_extract_value_int64(dictGetValue(config, "betree_locator_element_count")) - element_count := _t2258 - _t2259 := p._try_extract_value_int64(dictGetValue(config, "betree_locator_tree_height")) - tree_height := _t2259 - _t2260 := &pb.BeTreeLocator{ElementCount: deref(element_count, 0), TreeHeight: deref(tree_height, 0)} + _t2252 := p._try_extract_value_float64(dictGetValue(config, "betree_config_epsilon")) + epsilon := _t2252 + _t2253 := p._try_extract_value_int64(dictGetValue(config, "betree_config_max_pivots")) + max_pivots := _t2253 + _t2254 := p._try_extract_value_int64(dictGetValue(config, "betree_config_max_deltas")) + max_deltas := _t2254 + _t2255 := p._try_extract_value_int64(dictGetValue(config, "betree_config_max_leaf")) + max_leaf := _t2255 + _t2256 := &pb.BeTreeConfig{Epsilon: deref(epsilon, 0.0), MaxPivots: deref(max_pivots, 0), MaxDeltas: deref(max_deltas, 0), MaxLeaf: deref(max_leaf, 0)} + storage_config := _t2256 + _t2257 := p._try_extract_value_uint128(dictGetValue(config, "betree_locator_root_pageid")) + root_pageid := _t2257 + _t2258 := p._try_extract_value_bytes(dictGetValue(config, "betree_locator_inline_data")) + inline_data := _t2258 + _t2259 := p._try_extract_value_int64(dictGetValue(config, "betree_locator_element_count")) + element_count := _t2259 + _t2260 := p._try_extract_value_int64(dictGetValue(config, "betree_locator_tree_height")) + tree_height := _t2260 + _t2261 := &pb.BeTreeLocator{ElementCount: deref(element_count, 0), TreeHeight: deref(tree_height, 0)} if root_pageid != nil { - _t2260.Location = &pb.BeTreeLocator_RootPageid{RootPageid: root_pageid} + _t2261.Location = &pb.BeTreeLocator_RootPageid{RootPageid: root_pageid} } else { - _t2260.Location = &pb.BeTreeLocator_InlineData{InlineData: inline_data} + _t2261.Location = &pb.BeTreeLocator_InlineData{InlineData: inline_data} } - relation_locator := _t2260 - _t2261 := &pb.BeTreeInfo{KeyTypes: key_types, ValueTypes: value_types, StorageConfig: storage_config, RelationLocator: relation_locator} - return _t2261 + relation_locator := _t2261 + _t2262 := &pb.BeTreeInfo{KeyTypes: key_types, ValueTypes: value_types, StorageConfig: storage_config, RelationLocator: relation_locator} + return _t2262 } func (p *Parser) default_configure() *pb.Configure { - _t2262 := &pb.IVMConfig{Level: pb.MaintenanceLevel_MAINTENANCE_LEVEL_OFF} - ivm_config := _t2262 - _t2263 := &pb.Configure{SemanticsVersion: 0, IvmConfig: ivm_config} - return _t2263 + _t2263 := &pb.IVMConfig{Level: pb.MaintenanceLevel_MAINTENANCE_LEVEL_OFF} + ivm_config := _t2263 + _t2264 := &pb.Configure{SemanticsVersion: 0, IvmConfig: ivm_config} + return _t2264 } func (p *Parser) construct_configure(config_dict [][]interface{}) *pb.Configure { @@ -876,66 +881,66 @@ func (p *Parser) construct_configure(config_dict [][]interface{}) *pb.Configure } } } - _t2264 := &pb.IVMConfig{Level: maintenance_level} - ivm_config := _t2264 - _t2265 := p._extract_value_int64(dictGetValue(config, "semantics_version"), 0) - semantics_version := _t2265 - _t2266 := &pb.Configure{SemanticsVersion: semantics_version, IvmConfig: ivm_config} - return _t2266 + _t2265 := &pb.IVMConfig{Level: maintenance_level} + ivm_config := _t2265 + _t2266 := p._extract_value_int64(dictGetValue(config, "semantics_version"), 0) + semantics_version := _t2266 + _t2267 := &pb.Configure{SemanticsVersion: semantics_version, IvmConfig: ivm_config} + return _t2267 } func (p *Parser) construct_export_csv_config(path string, columns []*pb.ExportCSVColumn, config_dict [][]interface{}) *pb.ExportCSVConfig { config := dictFromList(config_dict) - _t2267 := p._extract_value_int64(dictGetValue(config, "partition_size"), 0) - partition_size := _t2267 - _t2268 := p._extract_value_string(dictGetValue(config, "compression"), "") - compression := _t2268 - _t2269 := p._extract_value_boolean(dictGetValue(config, "syntax_header_row"), true) - syntax_header_row := _t2269 - _t2270 := p._extract_value_string(dictGetValue(config, "syntax_missing_string"), "") - syntax_missing_string := _t2270 - _t2271 := p._extract_value_string(dictGetValue(config, "syntax_delim"), ",") - syntax_delim := _t2271 - _t2272 := p._extract_value_string(dictGetValue(config, "syntax_quotechar"), "\"") - syntax_quotechar := _t2272 - _t2273 := p._extract_value_string(dictGetValue(config, "syntax_escapechar"), "\\") - syntax_escapechar := _t2273 - _t2274 := &pb.ExportCSVConfig{Path: path, DataColumns: columns, PartitionSize: ptr(partition_size), Compression: ptr(compression), SyntaxHeaderRow: ptr(syntax_header_row), SyntaxMissingString: ptr(syntax_missing_string), SyntaxDelim: ptr(syntax_delim), SyntaxQuotechar: ptr(syntax_quotechar), SyntaxEscapechar: ptr(syntax_escapechar)} - return _t2274 + _t2268 := p._extract_value_int64(dictGetValue(config, "partition_size"), 0) + partition_size := _t2268 + _t2269 := p._extract_value_string(dictGetValue(config, "compression"), "") + compression := _t2269 + _t2270 := p._extract_value_boolean(dictGetValue(config, "syntax_header_row"), true) + syntax_header_row := _t2270 + _t2271 := p._extract_value_string(dictGetValue(config, "syntax_missing_string"), "") + syntax_missing_string := _t2271 + _t2272 := p._extract_value_string(dictGetValue(config, "syntax_delim"), ",") + syntax_delim := _t2272 + _t2273 := p._extract_value_string(dictGetValue(config, "syntax_quotechar"), "\"") + syntax_quotechar := _t2273 + _t2274 := p._extract_value_string(dictGetValue(config, "syntax_escapechar"), "\\") + syntax_escapechar := _t2274 + _t2275 := &pb.ExportCSVConfig{Path: path, DataColumns: columns, PartitionSize: ptr(partition_size), Compression: ptr(compression), SyntaxHeaderRow: ptr(syntax_header_row), SyntaxMissingString: ptr(syntax_missing_string), SyntaxDelim: ptr(syntax_delim), SyntaxQuotechar: ptr(syntax_quotechar), SyntaxEscapechar: ptr(syntax_escapechar)} + return _t2275 } func (p *Parser) construct_export_csv_config_with_location(location []interface{}, csv_source *pb.ExportCSVSource, csv_config *pb.CSVConfig) *pb.ExportCSVConfig { - _t2275 := &pb.ExportCSVConfig{Path: location[0].(string), TransactionOutputName: location[1].(string), CsvSource: csv_source, CsvConfig: csv_config} - return _t2275 + _t2276 := &pb.ExportCSVConfig{Path: location[0].(string), TransactionOutputName: location[1].(string), CsvSource: csv_source, CsvConfig: csv_config} + return _t2276 } func (p *Parser) construct_iceberg_catalog_config(catalog_uri string, scope_opt *string, property_pairs [][]interface{}, auth_property_pairs [][]interface{}) *pb.IcebergCatalogConfig { props := stringMapFromPairs(property_pairs) auth_props := stringMapFromPairs(auth_property_pairs) - _t2276 := &pb.IcebergCatalogConfig{CatalogUri: catalog_uri, Scope: ptr(deref(scope_opt, "")), Properties: props, AuthProperties: auth_props} - return _t2276 + _t2277 := &pb.IcebergCatalogConfig{CatalogUri: catalog_uri, Scope: ptr(deref(scope_opt, "")), Properties: props, AuthProperties: auth_props} + return _t2277 } func (p *Parser) construct_iceberg_data(locator *pb.IcebergLocator, config *pb.IcebergCatalogConfig, columns []*pb.GNFColumn, from_snapshot_opt *string, to_snapshot_opt *string, returns_delta bool) *pb.IcebergData { - _t2277 := &pb.IcebergData{Locator: locator, Config: config, Columns: columns, FromSnapshot: ptr(deref(from_snapshot_opt, "")), ToSnapshot: ptr(deref(to_snapshot_opt, "")), ReturnsDelta: returns_delta} - return _t2277 + _t2278 := &pb.IcebergData{Locator: locator, Config: config, Columns: columns, FromSnapshot: ptr(deref(from_snapshot_opt, "")), ToSnapshot: ptr(deref(to_snapshot_opt, "")), ReturnsDelta: returns_delta} + return _t2278 } func (p *Parser) construct_export_iceberg_config_full(locator *pb.IcebergLocator, config *pb.IcebergCatalogConfig, table_def *pb.RelationId, table_property_pairs [][]interface{}, config_dict [][]interface{}) *pb.ExportIcebergConfig { - _t2278 := config_dict + _t2279 := config_dict if config_dict == nil { - _t2278 = [][]interface{}{} - } - cfg := dictFromList(_t2278) - _t2279 := p._extract_value_string(dictGetValue(cfg, "prefix"), "") - prefix := _t2279 - _t2280 := p._extract_value_int64(dictGetValue(cfg, "target_file_size_bytes"), 0) - target_file_size_bytes := _t2280 - _t2281 := p._extract_value_string(dictGetValue(cfg, "compression"), "") - compression := _t2281 + _t2279 = [][]interface{}{} + } + cfg := dictFromList(_t2279) + _t2280 := p._extract_value_string(dictGetValue(cfg, "prefix"), "") + prefix := _t2280 + _t2281 := p._extract_value_int64(dictGetValue(cfg, "target_file_size_bytes"), 0) + target_file_size_bytes := _t2281 + _t2282 := p._extract_value_string(dictGetValue(cfg, "compression"), "") + compression := _t2282 table_props := stringMapFromPairs(table_property_pairs) - _t2282 := &pb.ExportIcebergConfig{Locator: locator, Config: config, TableDef: table_def, Prefix: ptr(prefix), TargetFileSizeBytes: ptr(target_file_size_bytes), Compression: compression, TableProperties: table_props} - return _t2282 + _t2283 := &pb.ExportIcebergConfig{Locator: locator, Config: config, TableDef: table_def, Prefix: ptr(prefix), TargetFileSizeBytes: ptr(target_file_size_bytes), Compression: compression, TableProperties: table_props} + return _t2283 } // --- Parse functions --- diff --git a/sdks/julia/LogicalQueryProtocol.jl/src/parser.jl b/sdks/julia/LogicalQueryProtocol.jl/src/parser.jl index 97bbbe01..e6f0cfa0 100644 --- a/sdks/julia/LogicalQueryProtocol.jl/src/parser.jl +++ b/sdks/julia/LogicalQueryProtocol.jl/src/parser.jl @@ -369,19 +369,24 @@ end # --- Helper functions --- function _extract_value_int32(parser::ParserState, value::Union{Nothing, Proto.Value}, default::Int64)::Int32 - if (!isnothing(value) && _has_proto_field(value, Symbol("int32_value"))) - return _get_oneof_field(value, :int32_value) + if isnothing(value) + return Int32(default) else _t2199 = nothing end - return Int32(default) + if _has_proto_field(value, Symbol("int32_value")) + return _get_oneof_field(value, :int32_value) + else + _t2200 = nothing + end + throw(ParseError("expected an int32 value (e.g. `1i32`) for this config field")) end function _extract_value_int64(parser::ParserState, value::Union{Nothing, Proto.Value}, default::Int64)::Int64 if (!isnothing(value) && _has_proto_field(value, Symbol("int_value"))) return _get_oneof_field(value, :int_value) else - _t2200 = nothing + _t2201 = nothing end return default end @@ -390,7 +395,7 @@ function _extract_value_string(parser::ParserState, value::Union{Nothing, Proto. if (!isnothing(value) && _has_proto_field(value, Symbol("string_value"))) return _get_oneof_field(value, :string_value) else - _t2201 = nothing + _t2202 = nothing end return default end @@ -399,7 +404,7 @@ function _extract_value_boolean(parser::ParserState, value::Union{Nothing, Proto if (!isnothing(value) && _has_proto_field(value, Symbol("boolean_value"))) return _get_oneof_field(value, :boolean_value) else - _t2202 = nothing + _t2203 = nothing end return default end @@ -408,7 +413,7 @@ function _extract_value_string_list(parser::ParserState, value::Union{Nothing, P if (!isnothing(value) && _has_proto_field(value, Symbol("string_value"))) return String[_get_oneof_field(value, :string_value)] else - _t2203 = nothing + _t2204 = nothing end return default end @@ -417,7 +422,7 @@ function _try_extract_value_int64(parser::ParserState, value::Union{Nothing, Pro if (!isnothing(value) && _has_proto_field(value, Symbol("int_value"))) return _get_oneof_field(value, :int_value) else - _t2204 = nothing + _t2205 = nothing end return nothing end @@ -426,7 +431,7 @@ function _try_extract_value_float64(parser::ParserState, value::Union{Nothing, P if (!isnothing(value) && _has_proto_field(value, Symbol("float_value"))) return _get_oneof_field(value, :float_value) else - _t2205 = nothing + _t2206 = nothing end return nothing end @@ -435,7 +440,7 @@ function _try_extract_value_bytes(parser::ParserState, value::Union{Nothing, Pro if (!isnothing(value) && _has_proto_field(value, Symbol("string_value"))) return Vector{UInt8}(_get_oneof_field(value, :string_value)) else - _t2206 = nothing + _t2207 = nothing end return nothing end @@ -444,118 +449,118 @@ function _try_extract_value_uint128(parser::ParserState, value::Union{Nothing, P if (!isnothing(value) && _has_proto_field(value, Symbol("uint128_value"))) return _get_oneof_field(value, :uint128_value) else - _t2207 = nothing + _t2208 = nothing end return nothing end function construct_non_cdc_relations(parser::ParserState, targets::Vector{Proto.TargetRelation})::Proto.TargetRelations - _t2208 = Proto.PlainTargets(targets=targets) - _t2209 = Proto.TargetRelations(body=OneOf(:plain, _t2208), keys=Proto.NamedColumn[]) - return _t2209 + _t2209 = Proto.PlainTargets(targets=targets) + _t2210 = Proto.TargetRelations(body=OneOf(:plain, _t2209), keys=Proto.NamedColumn[]) + return _t2210 end function construct_cdc_relations(parser::ParserState, inserts::Vector{Proto.TargetRelation}, deletes::Vector{Proto.TargetRelation})::Proto.TargetRelations - _t2210 = Proto.CDCTargets(inserts=inserts, deletes=deletes) - _t2211 = Proto.TargetRelations(body=OneOf(:cdc, _t2210), keys=Proto.NamedColumn[]) - return _t2211 + _t2211 = Proto.CDCTargets(inserts=inserts, deletes=deletes) + _t2212 = Proto.TargetRelations(body=OneOf(:cdc, _t2211), keys=Proto.NamedColumn[]) + return _t2212 end function construct_relations(parser::ParserState, keys::Vector{Proto.NamedColumn}, body::Proto.TargetRelations)::Proto.TargetRelations if _has_proto_field(body, Symbol("plain")) - _t2213 = Proto.TargetRelations(body=OneOf(:plain, _get_oneof_field(body, :plain)), keys=keys) - return _t2213 + _t2214 = Proto.TargetRelations(body=OneOf(:plain, _get_oneof_field(body, :plain)), keys=keys) + return _t2214 else - _t2212 = nothing + _t2213 = nothing end - _t2214 = Proto.TargetRelations(body=OneOf(:cdc, _get_oneof_field(body, :cdc)), keys=keys) - return _t2214 + _t2215 = Proto.TargetRelations(body=OneOf(:cdc, _get_oneof_field(body, :cdc)), keys=keys) + return _t2215 end function construct_csv_data(parser::ParserState, locator::Proto.CSVLocator, config::Proto.CSVConfig, columns_opt::Union{Nothing, Vector{Proto.GNFColumn}}, relations_opt::Union{Nothing, Proto.TargetRelations}, asof::String)::Proto.CSVData - _t2215 = Proto.CSVData(locator=locator, config=config, columns=(!isnothing(columns_opt) ? columns_opt : Proto.GNFColumn[]), asof=asof, relations=relations_opt) - return _t2215 + _t2216 = Proto.CSVData(locator=locator, config=config, columns=(!isnothing(columns_opt) ? columns_opt : Proto.GNFColumn[]), asof=asof, relations=relations_opt) + return _t2216 end function construct_csv_config(parser::ParserState, config_dict::Vector{Tuple{String, Proto.Value}}, storage_integration_opt::Union{Nothing, Vector{Tuple{String, Proto.Value}}})::Proto.CSVConfig config = Dict(config_dict) - _t2216 = _extract_value_int32(parser, get(config, "csv_header_row", nothing), 1) - header_row = _t2216 - _t2217 = _extract_value_int64(parser, get(config, "csv_skip", nothing), 0) - skip = _t2217 - _t2218 = _extract_value_string(parser, get(config, "csv_new_line", nothing), "") - new_line = _t2218 - _t2219 = _extract_value_string(parser, get(config, "csv_delimiter", nothing), ",") - delimiter = _t2219 - _t2220 = _extract_value_string(parser, get(config, "csv_quotechar", nothing), "\"") - quotechar = _t2220 - _t2221 = _extract_value_string(parser, get(config, "csv_escapechar", nothing), "\"") - escapechar = _t2221 - _t2222 = _extract_value_string(parser, get(config, "csv_comment", nothing), "") - comment = _t2222 - _t2223 = _extract_value_string_list(parser, get(config, "csv_missing_strings", nothing), String[]) - missing_strings = _t2223 - _t2224 = _extract_value_string(parser, get(config, "csv_decimal_separator", nothing), ".") - decimal_separator = _t2224 - _t2225 = _extract_value_string(parser, get(config, "csv_encoding", nothing), "utf-8") - encoding = _t2225 - _t2226 = _extract_value_string(parser, get(config, "csv_compression", nothing), "") - compression = _t2226 - _t2227 = _extract_value_int64(parser, get(config, "csv_partition_size_mb", nothing), 0) - partition_size_mb = _t2227 - _t2228 = construct_csv_storage_integration(parser, storage_integration_opt) - storage_integration = _t2228 - _t2229 = Proto.CSVConfig(header_row=header_row, skip=skip, new_line=new_line, delimiter=delimiter, quotechar=quotechar, escapechar=escapechar, comment=comment, missing_strings=missing_strings, decimal_separator=decimal_separator, encoding=encoding, compression=compression, partition_size_mb=partition_size_mb, storage_integration=storage_integration) - return _t2229 + _t2217 = _extract_value_int32(parser, get(config, "csv_header_row", nothing), 1) + header_row = _t2217 + _t2218 = _extract_value_int64(parser, get(config, "csv_skip", nothing), 0) + skip = _t2218 + _t2219 = _extract_value_string(parser, get(config, "csv_new_line", nothing), "") + new_line = _t2219 + _t2220 = _extract_value_string(parser, get(config, "csv_delimiter", nothing), ",") + delimiter = _t2220 + _t2221 = _extract_value_string(parser, get(config, "csv_quotechar", nothing), "\"") + quotechar = _t2221 + _t2222 = _extract_value_string(parser, get(config, "csv_escapechar", nothing), "\"") + escapechar = _t2222 + _t2223 = _extract_value_string(parser, get(config, "csv_comment", nothing), "") + comment = _t2223 + _t2224 = _extract_value_string_list(parser, get(config, "csv_missing_strings", nothing), String[]) + missing_strings = _t2224 + _t2225 = _extract_value_string(parser, get(config, "csv_decimal_separator", nothing), ".") + decimal_separator = _t2225 + _t2226 = _extract_value_string(parser, get(config, "csv_encoding", nothing), "utf-8") + encoding = _t2226 + _t2227 = _extract_value_string(parser, get(config, "csv_compression", nothing), "") + compression = _t2227 + _t2228 = _extract_value_int64(parser, get(config, "csv_partition_size_mb", nothing), 0) + partition_size_mb = _t2228 + _t2229 = construct_csv_storage_integration(parser, storage_integration_opt) + storage_integration = _t2229 + _t2230 = Proto.CSVConfig(header_row=header_row, skip=skip, new_line=new_line, delimiter=delimiter, quotechar=quotechar, escapechar=escapechar, comment=comment, missing_strings=missing_strings, decimal_separator=decimal_separator, encoding=encoding, compression=compression, partition_size_mb=partition_size_mb, storage_integration=storage_integration) + return _t2230 end function construct_csv_storage_integration(parser::ParserState, storage_integration_opt::Union{Nothing, Vector{Tuple{String, Proto.Value}}})::Union{Nothing, Proto.StorageIntegration} if isnothing(storage_integration_opt) return nothing else - _t2230 = nothing + _t2231 = nothing end config = Dict(storage_integration_opt) - _t2231 = _extract_value_string(parser, get(config, "provider", nothing), "") - _t2232 = _extract_value_string(parser, get(config, "azure_sas_token", nothing), "") - _t2233 = _extract_value_string(parser, get(config, "s3_region", nothing), "") - _t2234 = _extract_value_string(parser, get(config, "s3_access_key_id", nothing), "") - _t2235 = _extract_value_string(parser, get(config, "s3_secret_access_key", nothing), "") - _t2236 = Proto.StorageIntegration(provider=_t2231, azure_sas_token=_t2232, s3_region=_t2233, s3_access_key_id=_t2234, s3_secret_access_key=_t2235) - return _t2236 + _t2232 = _extract_value_string(parser, get(config, "provider", nothing), "") + _t2233 = _extract_value_string(parser, get(config, "azure_sas_token", nothing), "") + _t2234 = _extract_value_string(parser, get(config, "s3_region", nothing), "") + _t2235 = _extract_value_string(parser, get(config, "s3_access_key_id", nothing), "") + _t2236 = _extract_value_string(parser, get(config, "s3_secret_access_key", nothing), "") + _t2237 = Proto.StorageIntegration(provider=_t2232, azure_sas_token=_t2233, s3_region=_t2234, s3_access_key_id=_t2235, s3_secret_access_key=_t2236) + return _t2237 end function construct_betree_info(parser::ParserState, key_types::Vector{Proto.var"#Type"}, value_types::Vector{Proto.var"#Type"}, config_dict::Vector{Tuple{String, Proto.Value}})::Proto.BeTreeInfo config = Dict(config_dict) - _t2237 = _try_extract_value_float64(parser, get(config, "betree_config_epsilon", nothing)) - epsilon = _t2237 - _t2238 = _try_extract_value_int64(parser, get(config, "betree_config_max_pivots", nothing)) - max_pivots = _t2238 - _t2239 = _try_extract_value_int64(parser, get(config, "betree_config_max_deltas", nothing)) - max_deltas = _t2239 - _t2240 = _try_extract_value_int64(parser, get(config, "betree_config_max_leaf", nothing)) - max_leaf = _t2240 - _t2241 = Proto.BeTreeConfig(epsilon=epsilon, max_pivots=max_pivots, max_deltas=max_deltas, max_leaf=max_leaf) - storage_config = _t2241 - _t2242 = _try_extract_value_uint128(parser, get(config, "betree_locator_root_pageid", nothing)) - root_pageid = _t2242 - _t2243 = _try_extract_value_bytes(parser, get(config, "betree_locator_inline_data", nothing)) - inline_data = _t2243 - _t2244 = _try_extract_value_int64(parser, get(config, "betree_locator_element_count", nothing)) - element_count = _t2244 - _t2245 = _try_extract_value_int64(parser, get(config, "betree_locator_tree_height", nothing)) - tree_height = _t2245 - _t2246 = Proto.BeTreeLocator(location=(!isnothing(root_pageid) ? OneOf(:root_pageid, root_pageid) : (!isnothing(inline_data) ? OneOf(:inline_data, inline_data) : nothing)), element_count=element_count, tree_height=tree_height) - relation_locator = _t2246 - _t2247 = Proto.BeTreeInfo(key_types=key_types, value_types=value_types, storage_config=storage_config, relation_locator=relation_locator) - return _t2247 + _t2238 = _try_extract_value_float64(parser, get(config, "betree_config_epsilon", nothing)) + epsilon = _t2238 + _t2239 = _try_extract_value_int64(parser, get(config, "betree_config_max_pivots", nothing)) + max_pivots = _t2239 + _t2240 = _try_extract_value_int64(parser, get(config, "betree_config_max_deltas", nothing)) + max_deltas = _t2240 + _t2241 = _try_extract_value_int64(parser, get(config, "betree_config_max_leaf", nothing)) + max_leaf = _t2241 + _t2242 = Proto.BeTreeConfig(epsilon=epsilon, max_pivots=max_pivots, max_deltas=max_deltas, max_leaf=max_leaf) + storage_config = _t2242 + _t2243 = _try_extract_value_uint128(parser, get(config, "betree_locator_root_pageid", nothing)) + root_pageid = _t2243 + _t2244 = _try_extract_value_bytes(parser, get(config, "betree_locator_inline_data", nothing)) + inline_data = _t2244 + _t2245 = _try_extract_value_int64(parser, get(config, "betree_locator_element_count", nothing)) + element_count = _t2245 + _t2246 = _try_extract_value_int64(parser, get(config, "betree_locator_tree_height", nothing)) + tree_height = _t2246 + _t2247 = Proto.BeTreeLocator(location=(!isnothing(root_pageid) ? OneOf(:root_pageid, root_pageid) : (!isnothing(inline_data) ? OneOf(:inline_data, inline_data) : nothing)), element_count=element_count, tree_height=tree_height) + relation_locator = _t2247 + _t2248 = Proto.BeTreeInfo(key_types=key_types, value_types=value_types, storage_config=storage_config, relation_locator=relation_locator) + return _t2248 end function default_configure(parser::ParserState)::Proto.Configure - _t2248 = Proto.IVMConfig(level=Proto.MaintenanceLevel.MAINTENANCE_LEVEL_OFF) - ivm_config = _t2248 - _t2249 = Proto.Configure(semantics_version=0, ivm_config=ivm_config) - return _t2249 + _t2249 = Proto.IVMConfig(level=Proto.MaintenanceLevel.MAINTENANCE_LEVEL_OFF) + ivm_config = _t2249 + _t2250 = Proto.Configure(semantics_version=0, ivm_config=ivm_config) + return _t2250 end function construct_configure(parser::ParserState, config_dict::Vector{Tuple{String, Proto.Value}})::Proto.Configure @@ -577,62 +582,62 @@ function construct_configure(parser::ParserState, config_dict::Vector{Tuple{Stri end end end - _t2250 = Proto.IVMConfig(level=maintenance_level) - ivm_config = _t2250 - _t2251 = _extract_value_int64(parser, get(config, "semantics_version", nothing), 0) - semantics_version = _t2251 - _t2252 = Proto.Configure(semantics_version=semantics_version, ivm_config=ivm_config) - return _t2252 + _t2251 = Proto.IVMConfig(level=maintenance_level) + ivm_config = _t2251 + _t2252 = _extract_value_int64(parser, get(config, "semantics_version", nothing), 0) + semantics_version = _t2252 + _t2253 = Proto.Configure(semantics_version=semantics_version, ivm_config=ivm_config) + return _t2253 end function construct_export_csv_config(parser::ParserState, path::String, columns::Vector{Proto.ExportCSVColumn}, config_dict::Vector{Tuple{String, Proto.Value}})::Proto.ExportCSVConfig config = Dict(config_dict) - _t2253 = _extract_value_int64(parser, get(config, "partition_size", nothing), 0) - partition_size = _t2253 - _t2254 = _extract_value_string(parser, get(config, "compression", nothing), "") - compression = _t2254 - _t2255 = _extract_value_boolean(parser, get(config, "syntax_header_row", nothing), true) - syntax_header_row = _t2255 - _t2256 = _extract_value_string(parser, get(config, "syntax_missing_string", nothing), "") - syntax_missing_string = _t2256 - _t2257 = _extract_value_string(parser, get(config, "syntax_delim", nothing), ",") - syntax_delim = _t2257 - _t2258 = _extract_value_string(parser, get(config, "syntax_quotechar", nothing), "\"") - syntax_quotechar = _t2258 - _t2259 = _extract_value_string(parser, get(config, "syntax_escapechar", nothing), "\\") - syntax_escapechar = _t2259 - _t2260 = Proto.ExportCSVConfig(path=path, data_columns=columns, partition_size=partition_size, compression=compression, syntax_header_row=syntax_header_row, syntax_missing_string=syntax_missing_string, syntax_delim=syntax_delim, syntax_quotechar=syntax_quotechar, syntax_escapechar=syntax_escapechar) - return _t2260 + _t2254 = _extract_value_int64(parser, get(config, "partition_size", nothing), 0) + partition_size = _t2254 + _t2255 = _extract_value_string(parser, get(config, "compression", nothing), "") + compression = _t2255 + _t2256 = _extract_value_boolean(parser, get(config, "syntax_header_row", nothing), true) + syntax_header_row = _t2256 + _t2257 = _extract_value_string(parser, get(config, "syntax_missing_string", nothing), "") + syntax_missing_string = _t2257 + _t2258 = _extract_value_string(parser, get(config, "syntax_delim", nothing), ",") + syntax_delim = _t2258 + _t2259 = _extract_value_string(parser, get(config, "syntax_quotechar", nothing), "\"") + syntax_quotechar = _t2259 + _t2260 = _extract_value_string(parser, get(config, "syntax_escapechar", nothing), "\\") + syntax_escapechar = _t2260 + _t2261 = Proto.ExportCSVConfig(path=path, data_columns=columns, partition_size=partition_size, compression=compression, syntax_header_row=syntax_header_row, syntax_missing_string=syntax_missing_string, syntax_delim=syntax_delim, syntax_quotechar=syntax_quotechar, syntax_escapechar=syntax_escapechar) + return _t2261 end function construct_export_csv_config_with_location(parser::ParserState, location::Tuple{String, String}, csv_source::Proto.ExportCSVSource, csv_config::Proto.CSVConfig)::Proto.ExportCSVConfig - _t2261 = Proto.ExportCSVConfig(path=location[1], transaction_output_name=location[2], csv_source=csv_source, csv_config=csv_config) - return _t2261 + _t2262 = Proto.ExportCSVConfig(path=location[1], transaction_output_name=location[2], csv_source=csv_source, csv_config=csv_config) + return _t2262 end function construct_iceberg_catalog_config(parser::ParserState, catalog_uri::String, scope_opt::Union{Nothing, String}, property_pairs::Vector{Tuple{String, String}}, auth_property_pairs::Vector{Tuple{String, String}})::Proto.IcebergCatalogConfig props = Dict(property_pairs) auth_props = Dict(auth_property_pairs) - _t2262 = Proto.IcebergCatalogConfig(catalog_uri=catalog_uri, scope=(!isnothing(scope_opt) ? scope_opt : ""), properties=props, auth_properties=auth_props) - return _t2262 + _t2263 = Proto.IcebergCatalogConfig(catalog_uri=catalog_uri, scope=(!isnothing(scope_opt) ? scope_opt : ""), properties=props, auth_properties=auth_props) + return _t2263 end function construct_iceberg_data(parser::ParserState, locator::Proto.IcebergLocator, config::Proto.IcebergCatalogConfig, columns::Vector{Proto.GNFColumn}, from_snapshot_opt::Union{Nothing, String}, to_snapshot_opt::Union{Nothing, String}, returns_delta::Bool)::Proto.IcebergData - _t2263 = Proto.IcebergData(locator=locator, config=config, columns=columns, from_snapshot=(!isnothing(from_snapshot_opt) ? from_snapshot_opt : ""), to_snapshot=(!isnothing(to_snapshot_opt) ? to_snapshot_opt : ""), returns_delta=returns_delta) - return _t2263 + _t2264 = Proto.IcebergData(locator=locator, config=config, columns=columns, from_snapshot=(!isnothing(from_snapshot_opt) ? from_snapshot_opt : ""), to_snapshot=(!isnothing(to_snapshot_opt) ? to_snapshot_opt : ""), returns_delta=returns_delta) + return _t2264 end function construct_export_iceberg_config_full(parser::ParserState, locator::Proto.IcebergLocator, config::Proto.IcebergCatalogConfig, table_def::Proto.RelationId, table_property_pairs::Vector{Tuple{String, String}}, config_dict::Union{Nothing, Vector{Tuple{String, Proto.Value}}})::Proto.ExportIcebergConfig cfg = Dict((!isnothing(config_dict) ? config_dict : Tuple{String, Proto.Value}[])) - _t2264 = _extract_value_string(parser, get(cfg, "prefix", nothing), "") - prefix = _t2264 - _t2265 = _extract_value_int64(parser, get(cfg, "target_file_size_bytes", nothing), 0) - target_file_size_bytes = _t2265 - _t2266 = _extract_value_string(parser, get(cfg, "compression", nothing), "") - compression = _t2266 + _t2265 = _extract_value_string(parser, get(cfg, "prefix", nothing), "") + prefix = _t2265 + _t2266 = _extract_value_int64(parser, get(cfg, "target_file_size_bytes", nothing), 0) + target_file_size_bytes = _t2266 + _t2267 = _extract_value_string(parser, get(cfg, "compression", nothing), "") + compression = _t2267 table_props = Dict(table_property_pairs) - _t2267 = Proto.ExportIcebergConfig(locator=locator, config=config, table_def=table_def, prefix=prefix, target_file_size_bytes=target_file_size_bytes, compression=compression, table_properties=table_props) - return _t2267 + _t2268 = Proto.ExportIcebergConfig(locator=locator, config=config, table_def=table_def, prefix=prefix, target_file_size_bytes=target_file_size_bytes, compression=compression, table_properties=table_props) + return _t2268 end # --- Parse functions --- diff --git a/sdks/julia/LogicalQueryProtocol.jl/test/parser_tests.jl b/sdks/julia/LogicalQueryProtocol.jl/test/parser_tests.jl index b53b18d2..80d9a3e8 100644 --- a/sdks/julia/LogicalQueryProtocol.jl/test/parser_tests.jl +++ b/sdks/julia/LogicalQueryProtocol.jl/test/parser_tests.jl @@ -161,6 +161,31 @@ end ) end +@testitem "int32 config field requires i32 suffix" setup=[ParserSetup] begin + # Wrap a `csv_config` (whose `:csv_header_row` is an int32 field) in a + # minimal fragment so we can exercise int32 config extraction end-to-end. + csv_fragment(header_row) = + "(fragment :f (csv_data (csv_locator (paths \"x.csv\")) " * + "(csv_config { :csv_header_row " * header_row * " }) " * + "(columns (column \"c\" :c [INT])) (asof \"2025-01-01T00:00:00Z\")))" + + header_row_of(fragment) = + Parser.parse_fragment(fragment).declarations[1].declaration_type.value.data_type.value.config.header_row + + # A properly-typed int32 value parses. + @test header_row_of(csv_fragment("2i32")) == 2 + + # A bare int on an int32 config field errors loudly rather than silently + # falling back to the default. + @test_throws ParseError Parser.parse_fragment(csv_fragment("2")) + + # Omitting the field entirely still yields the default (1). + empty_fragment = + "(fragment :f (csv_data (csv_locator (paths \"x.csv\")) (csv_config {}) " * + "(columns (column \"c\" :c [INT])) (asof \"2025-01-01T00:00:00Z\")))" + @test header_row_of(empty_fragment) == 1 +end + @testitem "Parser - SYMBOL lexer regex" setup=[ParserSetup] begin # Hyphen must be a literal character, not part of a range lexer = Lexer("my-relation") diff --git a/sdks/python/src/lqp/gen/parser.py b/sdks/python/src/lqp/gen/parser.py index f8d74db1..a1813ac1 100644 --- a/sdks/python/src/lqp/gen/parser.py +++ b/sdks/python/src/lqp/gen/parser.py @@ -422,17 +422,17 @@ def relation_id_to_uint128(self, msg): # --- Helper functions --- def _extract_value_int32(self, value: logic_pb2.Value | None, default: int) -> int: - if value is not None: - assert value is not None - _t2199 = value.HasField("int32_value") + if value is None: + return int(default) else: - _t2199 = False - if _t2199: + _t2199 = None + assert value is not None + if value.HasField("int32_value"): assert value is not None return value.int32_value else: _t2200 = None - return int(default) + raise ParseError("expected an int32 value (e.g. `1i32`) for this config field") def _extract_value_int64(self, value: logic_pb2.Value | None, default: int) -> int: if value is not None: diff --git a/sdks/python/tests/test_parser.py b/sdks/python/tests/test_parser.py index ff2b4bcc..1b7dfc1b 100644 --- a/sdks/python/tests/test_parser.py +++ b/sdks/python/tests/test_parser.py @@ -68,6 +68,38 @@ def test_parse_transaction_rejects_fragment(): parse_transaction(_SIMPLE_FRAGMENT) +def _csv_fragment(header_row: str) -> str: + # Wrap a `csv_config` (whose `:csv_header_row` is an int32 field) in a + # minimal fragment so we can exercise int32 config extraction end-to-end. + return ( + '(fragment :f (csv_data (csv_locator (paths "x.csv")) ' + f"(csv_config {{ :csv_header_row {header_row} }}) " + '(columns (column "c" :c [INT])) (asof "2025-01-01T00:00:00Z")))' + ) + + +def _header_row_of(fragment: str) -> int: + result, _provenance = parse_fragment(fragment) + return result.declarations[0].data.csv_data.config.header_row + + +def test_int32_config_requires_i32_suffix(): + # A properly-typed int32 value parses. + assert _header_row_of(_csv_fragment("2i32")) == 2 + + # A bare int on an int32 config field errors loudly rather than silently + # falling back to the default. + with pytest.raises(ParseError): + parse_fragment(_csv_fragment("2")) + + # Omitting the field entirely still yields the default (1). + empty_fragment = ( + '(fragment :f (csv_data (csv_locator (paths "x.csv")) (csv_config {}) ' + '(columns (column "c" :c [INT])) (asof "2025-01-01T00:00:00Z")))' + ) + assert _header_row_of(empty_fragment) == 1 + + class TestSymbolLexing: """Tests for SYMBOL token regex — hyphen must be literal, not a range."""