From 97e330f9947027e535fb5e088c923529374b8417 Mon Sep 17 00:00:00 2001 From: Jeremy Yang Date: Wed, 28 May 2025 15:46:22 -0700 Subject: [PATCH] Parser: 25.2 snapshot --- .github/workflows/go.yml | 2 +- go.mod | 63 +- go.sum | 672 +- parser_test.go | 2 +- ...e-names.sql => 0002-fix-quote-names.patch} | 8 +- patches/0004-enc-always-quoted.patch | 35 + patches/0004-fix-bazel-compl.patch | 64 - patches/0005-delete-plpgsql-files.patch | 3099 - pkg/build/bazel/bazel.go | 10 +- pkg/build/bazel/non_bazel.go | 10 +- pkg/build/bazel/util/tinystringer/main.go | 23 +- pkg/build/cgo_compiler.go | 9 +- pkg/build/cgo_compiler_nocgo.go | 10 +- pkg/build/info.go | 121 +- pkg/build/info.pb.go | 2 +- pkg/build/info.proto | 9 +- pkg/build/version.txt | 2 +- pkg/cli/exit/codes.go | 9 +- pkg/cli/exit/doc.go | 9 +- pkg/cli/exit/exit.go | 9 +- pkg/col/coldata/batch.go | 203 +- pkg/col/coldata/bytes.go | 16 +- pkg/col/coldata/datum_vec.go | 11 +- pkg/col/coldata/json.go | 9 +- pkg/col/coldata/native_types.go | 11 +- pkg/col/coldata/nulls.go | 36 +- pkg/col/coldata/testutils.go | 13 +- pkg/col/coldata/vec.eg.go | 427 +- pkg/col/coldata/vec.go | 341 +- pkg/col/coldata/vec_tmpl.go | 104 +- pkg/col/typeconv/typeconv.go | 9 +- pkg/docs/docs.go | 13 +- pkg/geo/bbox.go | 9 +- pkg/geo/encode.go | 15 +- pkg/geo/errors.go | 9 +- pkg/geo/geo.go | 9 +- pkg/geo/geopb/config.go | 24 + pkg/geo/geopb/config.pb.go | 1191 + pkg/geo/geopb/config.proto | 60 + pkg/geo/geopb/geopb.go | 21 +- pkg/geo/geopb/geopb.pb.go | 2 +- pkg/geo/geopb/geopb.proto | 9 +- pkg/geo/geopb/types.go | 9 +- .../geoprojbase/embeddedproj/embedded_proj.go | 9 +- pkg/geo/geoprojbase/geoprojbase.go | 9 +- pkg/geo/geoprojbase/projections.go | 9 +- pkg/geo/hilbert.go | 9 +- pkg/geo/iterator.go | 9 +- pkg/geo/latlng.go | 9 +- pkg/geo/parse.go | 9 +- pkg/geo/polyline.go | 9 +- pkg/geo/summary.go | 9 +- pkg/keysbase/data.go | 9 +- .../kvserver/concurrency/isolation/levels.go | 9 +- .../concurrency/isolation/levels.proto | 9 +- pkg/security/username/username.go | 9 +- pkg/settings/bool.go | 160 + pkg/settings/byte_size.go | 94 + pkg/settings/common.go | 193 + pkg/settings/doc.go | 110 + pkg/settings/duration.go | 286 + pkg/settings/encoding.go | 23 + pkg/settings/encoding.pb.go | 381 + pkg/settings/encoding.proto | 21 + pkg/settings/enum.go | 232 + pkg/settings/float.go | 260 + pkg/settings/int.go | 238 + pkg/settings/masked.go | 92 + pkg/settings/options.go | 128 + pkg/settings/protobuf.go | 241 + pkg/settings/registry.go | 574 + pkg/settings/setting.go | 333 + pkg/settings/string.go | 149 + pkg/settings/updater.go | 246 + pkg/settings/values.go | 307 + pkg/settings/version.go | 190 + .../execgen/cmd/execgen/agg_gen_util.go | 59 +- .../cmd/execgen/and_or_projection_gen.go | 9 +- .../cmd/execgen/any_not_null_agg_gen.go | 13 +- .../execgen/cmd/execgen/avg_agg_gen.go | 23 +- .../cmd/execgen/bool_and_or_agg_gen.go | 13 +- .../colexec/execgen/cmd/execgen/cast_gen.go | 9 +- .../execgen/cmd/execgen/cast_gen_util.go | 14 +- .../execgen/cmd/execgen/concat_agg_gen.go | 13 +- .../colexec/execgen/cmd/execgen/const_gen.go | 9 +- .../execgen/cmd/execgen/count_agg_gen.go | 14 +- .../execgen/cmd/execgen/crossjoiner_gen.go | 9 +- .../cmd/execgen/data_manipulation_gen.go | 9 +- .../execgen/cmd/execgen/datum_to_vec_gen.go | 9 +- .../execgen/cmd/execgen/default_agg_gen.go | 13 +- .../cmd/execgen/default_cmp_expr_gen.go | 9 +- .../cmd/execgen/default_cmp_proj_ops_gen.go | 18 +- .../cmd/execgen/default_cmp_sel_ops_gen.go | 9 +- .../execgen/cmd/execgen/distinct_gen.go | 18 +- .../cmd/execgen/first_last_nth_value_gen.go | 9 +- .../cmd/execgen/hash_aggregator_gen.go | 9 +- .../execgen/cmd/execgen/hash_utils_gen.go | 17 +- .../execgen/cmd/execgen/hashjoiner_gen.go | 9 +- .../execgen/cmd/execgen/hashtable_gen.go | 9 +- .../execgen/cmd/execgen/is_null_ops_gen.go | 9 +- .../execgen/cmd/execgen/lead_lag_gen.go | 9 +- .../execgen/cmd/execgen/like_ops_gen.go | 18 +- pkg/sql/colexec/execgen/cmd/execgen/main.go | 14 +- .../execgen/cmd/execgen/mergejoinbase_gen.go | 9 +- .../execgen/cmd/execgen/mergejoiner_gen.go | 9 +- .../execgen/cmd/execgen/min_max_agg_gen.go | 13 +- .../cmd/execgen/min_max_removable_agg_gen.go | 9 +- .../colexec/execgen/cmd/execgen/ntile_gen.go | 9 +- .../cmd/execgen/ordered_synchronizer_gen.go | 9 +- .../execgen/cmd/execgen/overloads_abbr.go | 9 +- .../execgen/cmd/execgen/overloads_base.go | 13 +- .../execgen/cmd/execgen/overloads_bin.go | 42 +- .../execgen/cmd/execgen/overloads_cmp.go | 9 +- .../execgen/cmd/execgen/overloads_gen_util.go | 9 +- .../execgen/cmd/execgen/overloads_hash.go | 9 +- .../execgen/cmd/execgen/projection_ops_gen.go | 9 +- .../cmd/execgen/range_offset_handler_gen.go | 9 +- .../colexec/execgen/cmd/execgen/rank_gen.go | 9 +- .../execgen/cmd/execgen/relative_rank_gen.go | 9 +- .../execgen/cmd/execgen/row_number_gen.go | 9 +- .../execgen/cmd/execgen/rowtovec_gen.go | 9 +- .../execgen/cmd/execgen/select_in_gen.go | 10 +- .../execgen/cmd/execgen/selection_ops_gen.go | 9 +- .../colexec/execgen/cmd/execgen/sort_gen.go | 9 +- .../execgen/cmd/execgen/sorttopk_gen.go | 9 +- .../execgen/cmd/execgen/span_encoder_gen.go | 9 +- .../execgen/cmd/execgen/substring_gen.go | 9 +- .../execgen/cmd/execgen/sum_agg_gen.go | 28 +- .../execgen/cmd/execgen/values_differ_gen.go | 9 +- .../cmd/execgen/vec_comparators_gen.go | 9 +- .../colexec/execgen/cmd/execgen/vec_gen.go | 9 +- .../execgen/cmd/execgen/vec_to_datum_gen.go | 9 +- .../cmd/execgen/window_aggregator_gen.go | 9 +- .../execgen/cmd/execgen/window_framer_gen.go | 9 +- .../cmd/execgen/window_peer_grouper_gen.go | 9 +- pkg/sql/colexec/execgen/execgen.go | 9 +- pkg/sql/colexec/execgen/inline.go | 9 +- pkg/sql/colexec/execgen/placeholders.go | 9 +- .../colexec/execgen/supported_bin_cmp_ops.go | 9 +- pkg/sql/colexec/execgen/template.go | 9 +- pkg/sql/colexec/execgen/util.go | 9 +- pkg/sql/colexecerror/error.go | 202 +- pkg/sql/inverted/expression.go | 41 +- pkg/sql/inverted/span_expression.pb.go | 2 +- pkg/sql/inverted/span_expression.proto | 9 +- pkg/sql/lex/encode.go | 18 +- pkg/sql/lex/encode.proto | 9 +- pkg/sql/lexbase/allkeywords/main.go | 9 +- pkg/sql/lexbase/encode.go | 32 +- pkg/sql/lexbase/experimental_keywords.go | 9 +- pkg/sql/lexbase/keywords.go | 102 +- pkg/sql/lexbase/normalize.go | 9 +- pkg/sql/lexbase/predicates.go | 9 +- pkg/sql/lexbase/reserved_keywords.go | 1 + pkg/sql/lexbase/sql-gen.sh | 14 +- pkg/sql/lexbase/tokens.go | 1313 +- pkg/sql/oidext/oidext.go | 22 +- pkg/sql/parser/help.go | 9 +- pkg/sql/parser/help_gen_test.sh | 6 + pkg/sql/parser/help_messages.go | 1431 +- pkg/sql/parser/lexer.go | 30 +- pkg/sql/parser/parse.go | 87 +- pkg/sql/parser/scanner.go | 24 +- pkg/sql/parser/show_syntax.go | 9 +- pkg/sql/parser/sql.go | 67796 ++++++++-------- pkg/sql/parser/sql.y | 2051 +- pkg/sql/parser/statements/statement.go | 28 +- pkg/sql/pgrepl/lsn/lsn.go | 9 +- pkg/sql/pgwire/pgcode/codes.go | 23 +- pkg/sql/pgwire/pgcode/doc.go | 9 +- pkg/sql/pgwire/pgcode/generate.sh | 6 + pkg/sql/pgwire/pgcode/generate_names.sh | 6 + pkg/sql/pgwire/pgcode/plpgsql_codenames.go | 9 +- pkg/sql/pgwire/pgerror/constraint_name.go | 9 +- pkg/sql/pgwire/pgerror/errors.go | 9 +- pkg/sql/pgwire/pgerror/errors.pb.go | 2 +- pkg/sql/pgwire/pgerror/errors.proto | 9 +- pkg/sql/pgwire/pgerror/flatten.go | 9 +- pkg/sql/pgwire/pgerror/internal_errors.go | 12 +- pkg/sql/pgwire/pgerror/pgcode.go | 9 +- pkg/sql/pgwire/pgerror/severity.go | 9 +- pkg/sql/pgwire/pgerror/with_candidate_code.go | 9 +- pkg/sql/pgwire/pgerror/wrap.go | 9 +- pkg/sql/plpgsql/parser/lexbase/keywords.go | 359 + pkg/sql/plpgsql/parser/lexbase/tokens.go | 135 + pkg/sql/plpgsql/parser/lexbase/utils.go | 7 + pkg/sql/plpgsql/parser/lexer.go | 677 + pkg/sql/plpgsql/parser/parse.go | 139 + pkg/sql/plpgsql/parser/plpgsql.go | 2592 + pkg/sql/plpgsql/parser/plpgsql.y | 1756 + pkg/sql/privilege/kind.go | 31 +- pkg/sql/privilege/privilege.go | 18 +- pkg/sql/privilege/target_object_type.go | 9 +- pkg/sql/scanner/jsonpath_scan.go | 147 + pkg/sql/scanner/plpgsql_scan.go | 341 + pkg/sql/scanner/scan.go | 112 +- .../builtinsregistry/builtins_registry.go | 13 +- pkg/sql/sem/cast/cast.go | 56 +- pkg/sql/sem/cast/cast_map.go | 84 +- pkg/sql/sem/cast/cast_map_gen.sh | 6 + pkg/sql/sem/cast/type_name.go | 12 +- pkg/sql/sem/catconstants/constants.go | 36 +- pkg/sql/sem/catconstants/namespace.go | 9 +- pkg/sql/sem/catconstants/schemas.go | 9 +- pkg/sql/sem/catid/ids.go | 23 +- pkg/sql/sem/catid/index_id_set.go | 9 +- pkg/sql/sem/idxtype/idxtype.go | 75 + pkg/sql/sem/idxtype/idxtype.pb.go | 83 + pkg/sql/sem/idxtype/idxtype.proto | 27 + pkg/sql/sem/plpgsqltree/constants.go | 9 +- pkg/sql/sem/plpgsqltree/exception.go | 30 +- pkg/sql/sem/plpgsqltree/statements.go | 851 +- pkg/sql/sem/plpgsqltree/variable.go | 9 +- pkg/sql/sem/plpgsqltree/visitor.go | 344 +- pkg/sql/sem/semenumpb/constraint.go | 18 - pkg/sql/sem/semenumpb/constraint.pb.go | 40 +- pkg/sql/sem/semenumpb/constraint.proto | 13 +- pkg/sql/sem/semenumpb/enum.go | 23 + pkg/sql/sem/semenumpb/trigger.pb.go | 120 + pkg/sql/sem/semenumpb/trigger.proto | 32 + pkg/sql/sem/tree/adjust_constants.go | 366 + pkg/sql/sem/tree/alter_backup.go | 15 +- pkg/sql/sem/tree/alter_backup_schedule.go | 27 +- pkg/sql/sem/tree/alter_changefeed.go | 19 +- pkg/sql/sem/tree/alter_database.go | 9 +- pkg/sql/sem/tree/alter_default_privileges.go | 9 +- pkg/sql/sem/tree/alter_index.go | 9 +- pkg/sql/sem/tree/alter_policy.go | 37 + pkg/sql/sem/tree/alter_range.go | 9 +- pkg/sql/sem/tree/alter_role.go | 9 +- pkg/sql/sem/tree/alter_schema.go | 9 +- pkg/sql/sem/tree/alter_sequence.go | 9 +- pkg/sql/sem/tree/alter_table.go | 200 +- pkg/sql/sem/tree/alter_tenant.go | 59 +- pkg/sql/sem/tree/alter_type.go | 9 +- pkg/sql/sem/tree/analyze.go | 9 +- pkg/sql/sem/tree/annotation.go | 9 +- pkg/sql/sem/tree/backup.go | 157 +- pkg/sql/sem/tree/batch.go | 9 +- pkg/sql/sem/tree/call.go | 9 +- pkg/sql/sem/tree/changefeed.go | 11 +- pkg/sql/sem/tree/check.go | 81 + pkg/sql/sem/tree/col_name.go | 9 +- pkg/sql/sem/tree/comment_on_column.go | 9 +- pkg/sql/sem/tree/comment_on_constraint.go | 9 +- pkg/sql/sem/tree/comment_on_database.go | 9 +- pkg/sql/sem/tree/comment_on_index.go | 9 +- pkg/sql/sem/tree/comment_on_schema.go | 9 +- pkg/sql/sem/tree/comment_on_table.go | 9 +- pkg/sql/sem/tree/comment_on_type.go | 32 + pkg/sql/sem/tree/compare.go | 9 +- pkg/sql/sem/tree/constant.go | 41 +- pkg/sql/sem/tree/constant_eval.go | 9 +- pkg/sql/sem/tree/constants.go | 9 +- pkg/sql/sem/tree/constraint.go | 25 +- pkg/sql/sem/tree/copy.go | 24 +- pkg/sql/sem/tree/create.go | 134 +- .../sem/tree/create_logical_replication.go | 270 + pkg/sql/sem/tree/create_policy.go | 113 + pkg/sql/sem/tree/create_routine.go | 170 +- pkg/sql/sem/tree/create_trigger.go | 270 + pkg/sql/sem/tree/createtypevariety_string.go | 5 + pkg/sql/sem/tree/cursor.go | 9 +- pkg/sql/sem/tree/data_placement.go | 9 +- pkg/sql/sem/tree/datum.go | 1587 +- pkg/sql/sem/tree/datum_alloc.go | 417 +- pkg/sql/sem/tree/decimal.go | 9 +- pkg/sql/sem/tree/delete.go | 9 +- pkg/sql/sem/tree/discard.go | 9 +- pkg/sql/sem/tree/do.go | 85 + pkg/sql/sem/tree/drop.go | 9 +- pkg/sql/sem/tree/drop_owned_by.go | 9 +- pkg/sql/sem/tree/drop_policy.go | 31 + pkg/sql/sem/tree/eval.go | 176 +- pkg/sql/sem/tree/eval_binary_ops.go | 24 +- pkg/sql/sem/tree/eval_expr_generated.go | 25 +- pkg/sql/sem/tree/eval_op_generated.go | 45 +- pkg/sql/sem/tree/eval_unary_ops.go | 9 +- pkg/sql/sem/tree/evalgen/eval_gen.go | 18 +- pkg/sql/sem/tree/evalgen/expr.go | 9 +- pkg/sql/sem/tree/evalgen/op.go | 9 +- pkg/sql/sem/tree/evalgen/string_set.go | 9 +- pkg/sql/sem/tree/explain.go | 9 +- pkg/sql/sem/tree/export.go | 11 +- pkg/sql/sem/tree/expr.go | 43 +- pkg/sql/sem/tree/format.go | 253 +- pkg/sql/sem/tree/format_fingerprint.go | 150 + pkg/sql/sem/tree/function_definition.go | 300 +- pkg/sql/sem/tree/function_name.go | 10 +- pkg/sql/sem/tree/fuzz.go | 10 +- pkg/sql/sem/tree/grant.go | 9 +- pkg/sql/sem/tree/hide_constants.go | 199 - pkg/sql/sem/tree/import.go | 22 +- pkg/sql/sem/tree/indexed_vars.go | 102 +- pkg/sql/sem/tree/insert.go | 21 +- pkg/sql/sem/tree/name_part.go | 9 +- pkg/sql/sem/tree/name_resolution.go | 9 +- pkg/sql/sem/tree/object_name.go | 14 +- pkg/sql/sem/tree/overload.go | 678 +- pkg/sql/sem/tree/parse_array.go | 31 +- pkg/sql/sem/tree/parse_string.go | 36 +- pkg/sql/sem/tree/parse_tuple.go | 11 +- pkg/sql/sem/tree/persistence.go | 9 +- pkg/sql/sem/tree/pgwire_encode.go | 39 +- pkg/sql/sem/tree/placeholders.go | 24 +- pkg/sql/sem/tree/prepare.go | 9 +- pkg/sql/sem/tree/pretty.go | 77 +- pkg/sql/sem/tree/reassign_owned_by.go | 9 +- pkg/sql/sem/tree/regexp_cache.go | 41 +- pkg/sql/sem/tree/region.go | 9 +- pkg/sql/sem/tree/rename.go | 9 +- pkg/sql/sem/tree/returning.go | 9 +- pkg/sql/sem/tree/revoke.go | 9 +- pkg/sql/sem/tree/role_spec.go | 9 +- pkg/sql/sem/tree/routine.go | 228 +- pkg/sql/sem/tree/run_control.go | 23 +- pkg/sql/sem/tree/schedule.go | 11 +- pkg/sql/sem/tree/schema_feature_name.go | 9 +- pkg/sql/sem/tree/schema_helpers.go | 94 + pkg/sql/sem/tree/scrub.go | 9 +- pkg/sql/sem/tree/select.go | 60 +- pkg/sql/sem/tree/set.go | 28 +- pkg/sql/sem/tree/show.go | 237 +- pkg/sql/sem/tree/split.go | 9 +- .../sem/tree/statementreturntype_string.go | 5 + pkg/sql/sem/tree/statementtype_string.go | 5 + pkg/sql/sem/tree/stmt.go | 280 +- pkg/sql/sem/tree/survival_goal.go | 9 +- pkg/sql/sem/tree/table_name.go | 9 +- pkg/sql/sem/tree/table_pattern.go | 9 +- pkg/sql/sem/tree/table_ref.go | 9 +- pkg/sql/sem/tree/tenant.go | 9 +- pkg/sql/sem/tree/tenant_settings.go | 9 +- pkg/sql/sem/tree/testutils.go | 11 +- pkg/sql/sem/tree/time.go | 9 +- pkg/sql/sem/tree/treebin/binary_operator.go | 15 +- pkg/sql/sem/tree/treebin/doc.go | 9 +- .../sem/tree/treecmp/comparison_operator.go | 9 +- pkg/sql/sem/tree/treecmp/doc.go | 9 +- pkg/sql/sem/tree/treewindow/constants.go | 9 +- pkg/sql/sem/tree/treewindow/doc.go | 9 +- pkg/sql/sem/tree/truncate.go | 9 +- pkg/sql/sem/tree/txn.go | 119 +- pkg/sql/sem/tree/type_check.go | 606 +- pkg/sql/sem/tree/type_name.go | 30 +- pkg/sql/sem/tree/typing.go | 9 +- pkg/sql/sem/tree/union.go | 9 +- pkg/sql/sem/tree/unlisten.go | 9 +- pkg/sql/sem/tree/unsupported_error.go | 9 +- pkg/sql/sem/tree/update.go | 9 +- pkg/sql/sem/tree/values.go | 9 +- pkg/sql/sem/tree/var_expr.go | 9 +- pkg/sql/sem/tree/var_name.go | 9 +- pkg/sql/sem/tree/walk.go | 253 +- pkg/sql/sem/tree/with.go | 9 +- pkg/sql/sem/tree/zone.go | 32 +- pkg/sql/sem/volatility/volatility.go | 15 +- .../sessiondatapb/local_only_session_data.go | 69 +- .../local_only_session_data.pb.go | 5211 +- .../local_only_session_data.proto | 240 +- pkg/sql/sessiondatapb/sequence_cache.go | 9 +- pkg/sql/sessiondatapb/sequence_cache_node.go | 82 + pkg/sql/sessiondatapb/session_data.go | 37 +- pkg/sql/sessiondatapb/session_data.pb.go | 317 +- pkg/sql/sessiondatapb/session_data.proto | 22 +- pkg/sql/sessiondatapb/session_migration.pb.go | 42 +- pkg/sql/sessiondatapb/session_migration.proto | 9 +- .../sessiondatapb/session_revival_token.pb.go | 2 +- .../sessiondatapb/session_revival_token.proto | 9 +- pkg/sql/types/alias.go | 9 +- pkg/sql/types/oid.go | 21 +- pkg/sql/types/testutils.go | 9 +- pkg/sql/types/types.go | 321 +- pkg/sql/types/types.pb.go | 182 +- pkg/sql/types/types.proto | 25 +- pkg/sql/types/types_jsonpb.go | 9 +- .../admissionpb/admission_stats.pb.go | 125 +- .../admissionpb/admission_stats.proto | 36 +- pkg/util/admission/admissionpb/admissionpb.go | 146 +- pkg/util/admission/admissionpb/doc.go | 9 +- .../admission/admissionpb/io_threshold.go | 32 +- .../admission/admissionpb/io_threshold.pb.go | 2 +- .../admission/admissionpb/io_threshold.proto | 9 +- pkg/util/allstacks/allstacks.go | 37 + pkg/util/arith/arith.go | 9 +- pkg/util/base64/base64.go | 84 + pkg/util/bitarray/bitarray.go | 15 +- pkg/util/buildutil/crdb_test_off.go | 10 +- pkg/util/buildutil/crdb_test_on.go | 10 +- pkg/util/cache/cache.go | 9 +- pkg/util/collatedstring/collatedstring.go | 9 +- pkg/util/constants.go | 191 - pkg/util/constants_metamorphic_disable.go | 18 - pkg/util/ctxutil/canceler_1_20.go | 46 + pkg/util/ctxutil/canceler_1_21.go | 27 + pkg/util/ctxutil/canceler_1_21_bazel.go | 27 + pkg/util/ctxutil/context.go | 9 + pkg/util/ctxutil/context_linkname.go | 82 + pkg/util/ctxutil/context_no_linkname.go | 27 + pkg/util/ctxutil/doc.go | 38 + pkg/util/ctxutil/fast_value.go | 249 + pkg/util/debugutil/debugutil.go | 64 + .../unique.go => deduplicate/deduplicate.go} | 28 +- pkg/util/duration/duration.go | 35 +- pkg/util/duration/duration.proto | 9 +- pkg/util/duration/parse.go | 9 +- pkg/util/encoding/complement_fast.go | 10 +- pkg/util/encoding/complement_safe.go | 10 +- pkg/util/encoding/decimal.go | 9 +- pkg/util/encoding/encoding.go | 225 +- .../encoding/encodingtype/encoding_type.go | 9 +- pkg/util/encoding/float.go | 9 +- pkg/util/encoding/type_string.go | 8 + pkg/util/envutil/env.go | 16 +- pkg/util/errorutil/catch.go | 9 +- pkg/util/errorutil/error.go | 9 +- pkg/util/errorutil/sentinel.go | 9 +- pkg/util/errorutil/tenant.go | 9 +- .../errorutil/tenant_deprecated_wrapper.go | 9 +- .../errorutil/unimplemented/unimplemented.go | 9 +- pkg/util/every_n.go | 9 +- pkg/util/fast_int_map.go | 16 +- pkg/util/grunning/disabled.go | 18 +- pkg/util/grunning/enabled.go | 28 +- pkg/util/grunning/grunning.go | 21 +- pkg/util/hash.go | 9 +- pkg/util/hlc/doc.go | 325 + pkg/util/hlc/hlc.go | 695 + pkg/util/hlc/legacy_timestamp.pb.go | 435 + pkg/util/hlc/legacy_timestamp.proto | 29 + pkg/util/hlc/timestamp.go | 414 + pkg/util/hlc/timestamp.pb.go | 440 + pkg/util/hlc/timestamp.proto | 27 + pkg/util/humanizeutil/count.go | 21 +- pkg/util/humanizeutil/duration.go | 9 +- pkg/util/humanizeutil/humanize.go | 9 +- pkg/util/interval/btree_based_interval.go | 9 +- pkg/util/interval/bu23.go | 12 +- pkg/util/interval/interval.go | 11 +- pkg/util/interval/llrb_based_interval.go | 11 +- pkg/util/interval/range_group.go | 9 +- pkg/util/interval/td234.go | 12 +- pkg/util/intsets/bitmap.go | 9 +- pkg/util/intsets/fast.go | 50 +- pkg/util/intsets/fast_large.go | 10 +- pkg/util/intsets/fast_small.go | 10 +- pkg/util/intsets/fast_str.go | 9 +- pkg/util/intsets/fast_testonly.go | 45 +- pkg/util/intsets/oracle.go | 9 +- pkg/util/intsets/sparse.go | 9 +- pkg/util/ipaddr/ip.go | 9 +- pkg/util/ipaddr/ipaddr.go | 9 +- pkg/util/iterutil/iterutil.go | 53 +- pkg/util/json/config.go | 15 +- pkg/util/json/contains.go | 9 +- pkg/util/json/contains_testers.go | 9 +- pkg/util/json/encode.go | 28 +- pkg/util/json/encoded.go | 34 +- pkg/util/json/encoded_format.go | 221 + pkg/util/json/fuzz.go | 10 +- pkg/util/json/iterator.go | 9 +- pkg/util/json/jentry.go | 11 +- pkg/util/json/json.go | 212 +- pkg/util/json/parser.go | 16 +- pkg/util/json/random.go | 11 +- pkg/util/json/tables.go | 9 +- pkg/util/json/tokenizer/buffer.go | 9 +- pkg/util/json/tokenizer/decoder.go | 9 +- pkg/util/json/tokenizer/scanner.go | 9 +- pkg/util/jsonbytes/jsonbytes.go | 9 +- pkg/util/jsonpath/jsonpath.go | 28 + pkg/util/jsonpath/method.go | 51 + pkg/util/jsonpath/operation.go | 149 + pkg/util/jsonpath/parser/jsonpath.go | 1524 + pkg/util/jsonpath/parser/jsonpath.y | 804 + pkg/util/jsonpath/parser/lexbase/keywords.go | 122 + pkg/util/jsonpath/parser/lexbase/tokens.go | 70 + pkg/util/jsonpath/parser/lexbase/utils.go | 6 + pkg/util/jsonpath/parser/lexer.go | 109 + pkg/util/jsonpath/parser/parse.go | 115 + pkg/util/jsonpath/path.go | 279 + pkg/util/jsonpath/scalar.go | 50 + pkg/util/log/eventpb/eventpbgen/gen.go | 46 +- pkg/util/log/logpb/event.go | 9 +- pkg/util/log/logpb/event.pb.go | 2 +- pkg/util/log/logpb/event.proto | 9 +- pkg/util/log/logpb/log.pb.go | 2 +- pkg/util/log/logpb/log.proto | 9 +- pkg/util/log/logpb/severity.go | 9 +- pkg/util/log/logpb/test_utils.go | 9 +- pkg/util/metamorphic/constants.go | 299 + .../constants_metamorphic_disable.go | 12 + .../constants_metamorphic_enable.go | 12 +- .../metamorphicutil/is_metamorphic.go | 18 + pkg/util/netutil/addr/addr.go | 9 +- pkg/util/nocopy.go | 9 +- pkg/util/num32/doc.go | 23 + pkg/util/num32/mat.go | 101 + pkg/util/num32/scalar.go | 39 + pkg/util/num32/vec.go | 241 + pkg/util/pluralize.go | 13 +- pkg/util/pretty/document.go | 9 +- pkg/util/pretty/pretty.go | 9 +- pkg/util/pretty/util.go | 9 +- pkg/util/protoutil/clone.go | 9 +- pkg/util/protoutil/clone.pb.go | 2 +- pkg/util/protoutil/clone.proto | 9 +- pkg/util/protoutil/jsonpb_marshal.go | 9 +- pkg/util/protoutil/marshal.go | 20 +- pkg/util/protoutil/marshaler.go | 9 +- pkg/util/race_off.go | 10 +- pkg/util/race_on.go | 10 +- pkg/util/randutil/rand.go | 22 +- pkg/util/reflect.go | 9 +- pkg/util/ring/ring_buffer.go | 230 + pkg/util/slices.go | 36 +- pkg/util/smalltrace.go | 9 +- pkg/util/stringencoding/string_encoding.go | 9 +- pkg/util/strings.go | 9 +- pkg/util/strutil/util.go | 9 +- pkg/util/syncutil/atomic.go | 81 +- pkg/util/syncutil/{int_map.go => map.go} | 244 +- pkg/util/syncutil/mutex_deadlock.go | 15 +- pkg/util/syncutil/mutex_sync.go | 10 +- pkg/util/syncutil/mutex_sync_race.go | 47 +- pkg/util/syncutil/mutex_tracing.go | 120 + pkg/util/syncutil/set.go | 57 + pkg/util/system/cache_line.go | 27 + pkg/util/system/num_cpu.go | 22 + pkg/util/testaddr_default.go | 10 +- pkg/util/testaddr_random.go | 10 +- pkg/util/timeofday/time_of_day.go | 9 +- pkg/util/timetz/timetz.go | 11 +- pkg/util/timeutil/cpustopwatch.go | 11 +- pkg/util/timeutil/gen/main.go | 18 +- .../timeutil/lowercase_timezones_generated.go | 9 +- pkg/util/timeutil/manual_time.go | 9 +- pkg/util/timeutil/pgdate/field_extract.go | 28 +- pkg/util/timeutil/pgdate/field_string.go | 5 + pkg/util/timeutil/pgdate/fields.go | 9 +- pkg/util/timeutil/pgdate/math.go | 9 +- pkg/util/timeutil/pgdate/parsing.go | 168 +- pkg/util/timeutil/pgdate/pgdate.go | 9 +- pkg/util/timeutil/pgdate/pgdate.pb.go | 2 +- pkg/util/timeutil/pgdate/pgdate.proto | 9 +- pkg/util/timeutil/pgdate/setters.go | 9 +- pkg/util/timeutil/pgdate/zone_cache.go | 9 +- pkg/util/timeutil/stopwatch.go | 11 +- pkg/util/timeutil/ticker.go | 142 + pkg/util/timeutil/time.go | 19 +- pkg/util/timeutil/time_source.go | 13 +- pkg/util/timeutil/time_zone_util.go | 54 +- pkg/util/timeutil/timeout.go | 15 +- pkg/util/timeutil/timeout_error.go | 33 +- pkg/util/timeutil/timer.go | 63 +- pkg/util/timeutil/timeutil.go | 9 +- pkg/util/timeutil/zoneinfo.go | 9 +- pkg/util/topk.go | 9 +- pkg/util/tracing/context.go | 68 + pkg/util/tracing/crdbspan.go | 1496 + pkg/util/tracing/doc.go | 96 + pkg/util/tracing/span.go | 965 + pkg/util/tracing/span_finalizer_race_off.go | 21 + pkg/util/tracing/span_finalizer_race_on.go | 11 + pkg/util/tracing/span_inner.go | 292 + pkg/util/tracing/span_options.go | 496 + pkg/util/tracing/tags.go | 55 + pkg/util/tracing/test_utils.go | 254 + pkg/util/tracing/tracer.go | 1767 + pkg/util/tracing/tracer_snapshots.go | 338 + pkg/util/tracing/tracing_aggregator.go | 102 + pkg/util/tracing/tracingpb/recorded_span.go | 213 + .../tracing/tracingpb/recorded_span.pb.go | 3410 + .../tracing/tracingpb/recorded_span.proto | 191 + pkg/util/tracing/tracingpb/recording.go | 548 + pkg/util/tracing/tracingpb/tracing.go | 11 + pkg/util/tracing/tracingpb/tracing.pb.go | 661 + pkg/util/tracing/tracingpb/tracing.proto | 42 + pkg/util/tracing/utils.go | 58 + pkg/util/treeprinter/tree_printer.go | 9 +- pkg/util/tsearch/config.go | 9 +- pkg/util/tsearch/encoding.go | 9 +- pkg/util/tsearch/eval.go | 9 +- pkg/util/tsearch/lex.go | 9 +- pkg/util/tsearch/random.go | 9 +- pkg/util/tsearch/rank.go | 9 +- pkg/util/tsearch/snowball.go | 9 +- pkg/util/tsearch/stopwords.go | 9 +- pkg/util/tsearch/tsquery.go | 9 +- pkg/util/tsearch/tsvector.go | 9 +- pkg/util/uint128/uint128.go | 9 +- pkg/util/unresolved_addr.go | 9 +- pkg/util/unresolved_addr.pb.go | 2 +- pkg/util/unresolved_addr.proto | 9 +- pkg/util/uuid/codec.go | 9 +- pkg/util/uuid/fuzz.go | 10 +- pkg/util/uuid/generator.go | 98 +- pkg/util/uuid/sql.go | 9 +- pkg/util/uuid/uuid.go | 25 +- pkg/util/uuid/uuid_wrapper.go | 84 +- pkg/util/vector/vector.go | 297 + pkg/util/vector/vector.pb.go | 403 + pkg/util/vector/vector.proto | 27 + pkg/util/vector/vector_set.go | 228 + pkg/util/version/version.go | 237 - snapshot.sh | 3 +- version | 2 +- 607 files changed, 86880 insertions(+), 46294 deletions(-) rename patches/{0002-fix-quote-names.sql => 0002-fix-quote-names.patch} (84%) create mode 100644 patches/0004-enc-always-quoted.patch delete mode 100644 patches/0004-fix-bazel-compl.patch delete mode 100644 patches/0005-delete-plpgsql-files.patch create mode 100644 pkg/geo/geopb/config.go create mode 100644 pkg/geo/geopb/config.pb.go create mode 100644 pkg/geo/geopb/config.proto create mode 100644 pkg/settings/bool.go create mode 100644 pkg/settings/byte_size.go create mode 100644 pkg/settings/common.go create mode 100644 pkg/settings/doc.go create mode 100644 pkg/settings/duration.go create mode 100644 pkg/settings/encoding.go create mode 100644 pkg/settings/encoding.pb.go create mode 100644 pkg/settings/encoding.proto create mode 100644 pkg/settings/enum.go create mode 100644 pkg/settings/float.go create mode 100644 pkg/settings/int.go create mode 100644 pkg/settings/masked.go create mode 100644 pkg/settings/options.go create mode 100644 pkg/settings/protobuf.go create mode 100644 pkg/settings/registry.go create mode 100644 pkg/settings/setting.go create mode 100644 pkg/settings/string.go create mode 100644 pkg/settings/updater.go create mode 100644 pkg/settings/values.go create mode 100644 pkg/settings/version.go create mode 100644 pkg/sql/plpgsql/parser/lexbase/keywords.go create mode 100644 pkg/sql/plpgsql/parser/lexbase/tokens.go create mode 100644 pkg/sql/plpgsql/parser/lexbase/utils.go create mode 100644 pkg/sql/plpgsql/parser/lexer.go create mode 100644 pkg/sql/plpgsql/parser/parse.go create mode 100644 pkg/sql/plpgsql/parser/plpgsql.go create mode 100644 pkg/sql/plpgsql/parser/plpgsql.y create mode 100644 pkg/sql/scanner/jsonpath_scan.go create mode 100644 pkg/sql/scanner/plpgsql_scan.go create mode 100644 pkg/sql/sem/idxtype/idxtype.go create mode 100644 pkg/sql/sem/idxtype/idxtype.pb.go create mode 100644 pkg/sql/sem/idxtype/idxtype.proto delete mode 100644 pkg/sql/sem/semenumpb/constraint.go create mode 100644 pkg/sql/sem/semenumpb/enum.go create mode 100644 pkg/sql/sem/semenumpb/trigger.pb.go create mode 100644 pkg/sql/sem/semenumpb/trigger.proto create mode 100644 pkg/sql/sem/tree/adjust_constants.go create mode 100644 pkg/sql/sem/tree/alter_policy.go create mode 100644 pkg/sql/sem/tree/check.go create mode 100644 pkg/sql/sem/tree/comment_on_type.go create mode 100644 pkg/sql/sem/tree/create_logical_replication.go create mode 100644 pkg/sql/sem/tree/create_policy.go create mode 100644 pkg/sql/sem/tree/create_trigger.go create mode 100644 pkg/sql/sem/tree/do.go create mode 100644 pkg/sql/sem/tree/drop_policy.go create mode 100644 pkg/sql/sem/tree/format_fingerprint.go delete mode 100644 pkg/sql/sem/tree/hide_constants.go create mode 100644 pkg/sql/sem/tree/schema_helpers.go create mode 100644 pkg/sql/sessiondatapb/sequence_cache_node.go create mode 100644 pkg/util/allstacks/allstacks.go create mode 100644 pkg/util/base64/base64.go delete mode 100644 pkg/util/constants.go delete mode 100644 pkg/util/constants_metamorphic_disable.go create mode 100644 pkg/util/ctxutil/canceler_1_20.go create mode 100644 pkg/util/ctxutil/canceler_1_21.go create mode 100644 pkg/util/ctxutil/canceler_1_21_bazel.go create mode 100644 pkg/util/ctxutil/context.go create mode 100644 pkg/util/ctxutil/context_linkname.go create mode 100644 pkg/util/ctxutil/context_no_linkname.go create mode 100644 pkg/util/ctxutil/doc.go create mode 100644 pkg/util/ctxutil/fast_value.go create mode 100644 pkg/util/debugutil/debugutil.go rename pkg/util/{unique/unique.go => deduplicate/deduplicate.go} (78%) create mode 100644 pkg/util/hlc/doc.go create mode 100644 pkg/util/hlc/hlc.go create mode 100644 pkg/util/hlc/legacy_timestamp.pb.go create mode 100644 pkg/util/hlc/legacy_timestamp.proto create mode 100644 pkg/util/hlc/timestamp.go create mode 100644 pkg/util/hlc/timestamp.pb.go create mode 100644 pkg/util/hlc/timestamp.proto create mode 100644 pkg/util/json/encoded_format.go create mode 100644 pkg/util/jsonpath/jsonpath.go create mode 100644 pkg/util/jsonpath/method.go create mode 100644 pkg/util/jsonpath/operation.go create mode 100644 pkg/util/jsonpath/parser/jsonpath.go create mode 100644 pkg/util/jsonpath/parser/jsonpath.y create mode 100644 pkg/util/jsonpath/parser/lexbase/keywords.go create mode 100644 pkg/util/jsonpath/parser/lexbase/tokens.go create mode 100644 pkg/util/jsonpath/parser/lexbase/utils.go create mode 100644 pkg/util/jsonpath/parser/lexer.go create mode 100644 pkg/util/jsonpath/parser/parse.go create mode 100644 pkg/util/jsonpath/path.go create mode 100644 pkg/util/jsonpath/scalar.go create mode 100644 pkg/util/metamorphic/constants.go create mode 100644 pkg/util/metamorphic/constants_metamorphic_disable.go rename pkg/util/{ => metamorphic}/constants_metamorphic_enable.go (50%) create mode 100644 pkg/util/metamorphic/metamorphicutil/is_metamorphic.go create mode 100644 pkg/util/num32/doc.go create mode 100644 pkg/util/num32/mat.go create mode 100644 pkg/util/num32/scalar.go create mode 100644 pkg/util/num32/vec.go create mode 100644 pkg/util/ring/ring_buffer.go rename pkg/util/syncutil/{int_map.go => map.go} (57%) create mode 100644 pkg/util/syncutil/mutex_tracing.go create mode 100644 pkg/util/syncutil/set.go create mode 100644 pkg/util/system/cache_line.go create mode 100644 pkg/util/system/num_cpu.go create mode 100644 pkg/util/timeutil/ticker.go create mode 100644 pkg/util/tracing/context.go create mode 100644 pkg/util/tracing/crdbspan.go create mode 100644 pkg/util/tracing/doc.go create mode 100644 pkg/util/tracing/span.go create mode 100644 pkg/util/tracing/span_finalizer_race_off.go create mode 100644 pkg/util/tracing/span_finalizer_race_on.go create mode 100644 pkg/util/tracing/span_inner.go create mode 100644 pkg/util/tracing/span_options.go create mode 100644 pkg/util/tracing/tags.go create mode 100644 pkg/util/tracing/test_utils.go create mode 100644 pkg/util/tracing/tracer.go create mode 100644 pkg/util/tracing/tracer_snapshots.go create mode 100644 pkg/util/tracing/tracing_aggregator.go create mode 100644 pkg/util/tracing/tracingpb/recorded_span.go create mode 100644 pkg/util/tracing/tracingpb/recorded_span.pb.go create mode 100644 pkg/util/tracing/tracingpb/recorded_span.proto create mode 100644 pkg/util/tracing/tracingpb/recording.go create mode 100644 pkg/util/tracing/tracingpb/tracing.go create mode 100644 pkg/util/tracing/tracingpb/tracing.pb.go create mode 100644 pkg/util/tracing/tracingpb/tracing.proto create mode 100644 pkg/util/tracing/utils.go create mode 100644 pkg/util/vector/vector.go create mode 100644 pkg/util/vector/vector.pb.go create mode 100644 pkg/util/vector/vector.proto create mode 100644 pkg/util/vector/vector_set.go delete mode 100644 pkg/util/version/version.go diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 3c1f6cf..010d5f2 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -19,7 +19,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v3 with: - go-version: 1.21 + go-version: 1.23 - name: Build run: go build -v ./... diff --git a/go.mod b/go.mod index 74912df..976220b 100644 --- a/go.mod +++ b/go.mod @@ -1,50 +1,69 @@ module github.com/cockroachdb/cockroachdb-parser -go 1.21.1 - -toolchain go1.21.3 +go 1.23.8 require ( github.com/bazelbuild/rules_go v0.46.0 github.com/biogo/store v0.0.0-20201120204734-aad293a2328f github.com/blevesearch/snowballstem v0.9.0 github.com/cockroachdb/apd/v3 v3.1.0 - github.com/cockroachdb/errors v1.9.0 + github.com/cockroachdb/errors v1.11.3 github.com/cockroachdb/gostdlib v1.19.0 - github.com/cockroachdb/redact v1.1.3 + github.com/cockroachdb/logtags v0.0.0-20241215232642-bb51bb14a506 + github.com/cockroachdb/redact v1.1.5 + github.com/cockroachdb/version v0.0.0-20250314144055-3860cd14adf2 github.com/dave/dst v0.27.2 github.com/dustin/go-humanize v1.0.0 + github.com/elastic/gosigar v0.14.3 github.com/gogo/protobuf v1.3.2 github.com/golang/geo v0.0.0-20210211234256-740aa86cb551 - github.com/google/go-cmp v0.5.8 + github.com/google/go-cmp v0.7.0 github.com/grpc-ecosystem/grpc-gateway v1.16.0 + github.com/jaegertracing/jaeger v1.18.1 github.com/lib/pq v1.10.6 + github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 github.com/pierrre/geohash v1.0.0 + github.com/pmezard/go-difflib v1.0.0 github.com/sasha-s/go-deadlock v0.3.1 github.com/spf13/pflag v1.0.5 - github.com/stretchr/testify v1.7.0 + github.com/stretchr/testify v1.10.0 github.com/twpayne/go-geom v1.4.1 + go.opentelemetry.io/otel v1.36.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.36.0 + go.opentelemetry.io/otel/exporters/zipkin v1.36.0 + go.opentelemetry.io/otel/sdk v1.36.0 + go.opentelemetry.io/otel/trace v1.36.0 golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3 - golang.org/x/text v0.14.0 - golang.org/x/tools v0.17.0 + golang.org/x/net v0.40.0 + golang.org/x/sys v0.33.0 + golang.org/x/text v0.25.0 + golang.org/x/tools v0.26.0 + gonum.org/v1/gonum v0.16.0 + google.golang.org/grpc v1.72.1 + google.golang.org/protobuf v1.36.6 ) require ( - github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f // indirect + github.com/cenkalti/backoff/v5 v5.0.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/getsentry/sentry-go v0.12.0 // indirect - github.com/golang/protobuf v1.5.3 // indirect - github.com/kr/pretty v0.3.0 // indirect + github.com/getsentry/sentry-go v0.27.0 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect + github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect - github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect + github.com/openzipkin/zipkin-go v0.4.3 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/rogpeppe/go-internal v1.8.1 // indirect + github.com/rogpeppe/go-internal v1.13.1 // indirect github.com/twpayne/go-kml v1.5.2 // indirect - golang.org/x/mod v0.14.0 // indirect - golang.org/x/sys v0.15.0 // indirect - google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84 // indirect - google.golang.org/grpc v1.40.1 // indirect - google.golang.org/protobuf v1.31.0 // indirect - gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect + go.opentelemetry.io/auto/sdk v1.1.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0 // indirect + go.opentelemetry.io/otel/metric v1.36.0 // indirect + go.opentelemetry.io/proto/otlp v1.6.0 // indirect + golang.org/x/mod v0.21.0 // indirect + golang.org/x/sync v0.14.0 // indirect + google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index e6655cb..22bf7b5 100644 --- a/go.sum +++ b/go.sum @@ -1,69 +1,86 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw= -github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= -github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible/go.mod h1:HPYO+50pSWkPoj9Q/eq0aRGByCL6ScRlUmiEX5Zgm+w= -github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= github.com/Codefor/geohash v0.0.0-20140723084247-1b41c28e3a9d h1:iG9B49Q218F/XxXNRM7k/vWf7MKmLIS8AcJV9cGN4nA= github.com/Codefor/geohash v0.0.0-20140723084247-1b41c28e3a9d/go.mod h1:RVnhzAX71far8Kc3TQeA0k/dcaEKUnTDSOyet/JCmGI= github.com/DATA-DOG/go-sqlmock v1.3.2 h1:2L2f5t3kKnCLxnClDD/PrDfExFFa1wjESgxHG/B1ibo= github.com/DATA-DOG/go-sqlmock v1.3.2/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= -github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= -github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM= +github.com/DataDog/zstd v1.3.6-0.20190409195224-796139022798/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= +github.com/DataDog/zstd v1.4.4/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= +github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/Shopify/sarama v1.22.2-0.20190604114437-cd910a683f9f/go.mod h1:XLH1GYJnLVE0XCr6KdJGVJRTwY30moWNJ4sERjXX6fs= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/TomiHiltunen/geohash-golang v0.0.0-20150112065804-b3e4e625abfb h1:wumPkzt4zaxO4rHPBrjDK8iZMR41C1qs7njNqlacwQg= github.com/TomiHiltunen/geohash-golang v0.0.0-20150112065804-b3e4e625abfb/go.mod h1:QiYsIBRQEO+Z4Rz7GoI+dsHVneZNONvhczuA+llOZNM= -github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= +github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= +github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= +github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/apache/thrift v0.0.0-20151001171628-53dd39833a08/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= +github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= +github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= +github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= github.com/bazelbuild/rules_go v0.46.0 h1:CTefzjN/D3Cdn3rkrM6qMWuQj59OBcuOjyIp3m4hZ7s= github.com/bazelbuild/rules_go v0.46.0/go.mod h1:Dhcz716Kqg1RHNWos+N6MlXNkjNP2EwZQ0LukRKJfMs= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/biogo/store v0.0.0-20201120204734-aad293a2328f h1:+6okTAeUsUrdQr/qN7fIODzowrjjCrnJDg/gkYqcSXY= github.com/biogo/store v0.0.0-20201120204734-aad293a2328f/go.mod h1:z52shMwD6SGwRg2iYFjjDwX5Ene4ENTw6HfXraUy/08= +github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k= github.com/blevesearch/snowballstem v0.9.0 h1:lMQ189YspGP6sXvZQ4WZ+MLawfV8wOmPoD/iWeNXm8s= github.com/blevesearch/snowballstem v0.9.0/go.mod h1:PivSj3JMc8WuaFkTSRDW2SlrulNWPl4ABg1tC/hlgLs= +github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= +github.com/bmizerany/perks v0.0.0-20141205001514-d9a9656a3a4b/go.mod h1:ac9efd0D1fsDb3EJvhqgXRbFx7bs2wqZ10HQPeU8U/Q= github.com/broady/gogeohash v0.0.0-20120525094510-7b2c40d64042 h1:iEdmkrNMLXbM7ecffOAtZJQOQUTE4iMonxrb5opUgE4= github.com/broady/gogeohash v0.0.0-20120525094510-7b2c40d64042/go.mod h1:f1L9YvXvlt9JTa+A17trQjSMM6bV40f+tHjB+Pi+Fqk= +github.com/bsm/sarama-cluster v2.1.13+incompatible/go.mod h1:r7ao+4tTNXvWm+VRpRJchr2kQhqxgmAp2iEX5W96gMM= github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs= +github.com/cenkalti/backoff/v5 v5.0.2 h1:rIfFVxEf1QsI7E1ZHfp/B4DF/6QBAUhmgkxc0H7Zss8= +github.com/cenkalti/backoff/v5 v5.0.2/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/apd/v3 v3.1.0 h1:MK3Ow7LH0W8zkd5GMKA1PvS9qG3bWFI95WaVNfyZJ/w= github.com/cockroachdb/apd/v3 v3.1.0/go.mod h1:6qgPBMXjATAdD/VefbRP9NoSLKjbB4LCoA7gN4LpHs4= -github.com/cockroachdb/datadriven v1.0.1-0.20211007161720-b558070c3be0/go.mod h1:5Ib8Meh+jk1RlHIXej6Pzevx/NLlNvQB9pmSBZErGA4= -github.com/cockroachdb/datadriven v1.0.1-0.20220214170620-9913f5bc19b7/go.mod h1:hi0MtSY3AYDQNDi83kDkMH5/yqM/CsIrsOITkSoH7KI= -github.com/cockroachdb/errors v1.6.1/go.mod h1:tm6FTP5G81vwJ5lC0SizQo374JNCOPrHyXGitRJoDqM= -github.com/cockroachdb/errors v1.8.8/go.mod h1:z6VnEL3hZ/2ONZEvG7S5Ym0bU2AqPcEKnIiA1wbsSu0= -github.com/cockroachdb/errors v1.9.0 h1:B48dYem5SlAY7iU8AKsgedb4gH6mo+bDkbtLIvM/a88= -github.com/cockroachdb/errors v1.9.0/go.mod h1:vaNcEYYqbIqB5JhKBhFV9CneUqeuEbB2OYJBK4GBNYQ= +github.com/cockroachdb/errors v1.11.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I= +github.com/cockroachdb/errors v1.11.3/go.mod h1:m4UIW4CDjx+R5cybPsNrRbreomiFqt8o1h1wUVazSd8= github.com/cockroachdb/gostdlib v1.19.0 h1:cSISxkVnTlWhTkyple/T6NXzOi5659FkhxvUgZv+Eb0= github.com/cockroachdb/gostdlib v1.19.0/go.mod h1:+dqqpARXbE/gRDEhCak6dm0l14AaTymPZUKMfURjBtY= -github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= -github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f h1:6jduT9Hfc0njg5jJ1DdKCFPdMBrp/mdZfCpa5h+WM74= -github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= -github.com/cockroachdb/redact v1.1.3 h1:AKZds10rFSIj7qADf0g46UixK8NNLwWTNdCIGS5wfSQ= -github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= -github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2/go.mod h1:8BT+cPK6xvFOcRlk0R8eg+OTkcqI6baNH4xAkpiYVvQ= -github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= +github.com/cockroachdb/logtags v0.0.0-20241215232642-bb51bb14a506 h1:ASDL+UJcILMqgNeV5jiqR4j+sTuvQNHdf2chuKj1M5k= +github.com/cockroachdb/logtags v0.0.0-20241215232642-bb51bb14a506/go.mod h1:Mw7HqKr2kdtu6aYGn3tPmAftiP3QPX63LdK/zcariIo= +github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= +github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/version v0.0.0-20250314144055-3860cd14adf2 h1:8Vfw2iNEpYIV6aLtMwT5UOGuPmp9MKlEKWKFTuB+MPU= +github.com/cockroachdb/version v0.0.0-20250314144055-3860cd14adf2/go.mod h1:P9WiZOdQ1R/ZZDL0WzF5wlyRvrjtfhNOwMZymFpBwjE= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/containerd/continuity v0.0.0-20190827140505-75bee3e2ccb6/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/crossdock/crossdock-go v0.0.0-20160816171116-049aabb0122b/go.mod h1:v9FBN7gdVTpiD/+LZ7Po0UKvROyT87uLVxTHVky/dlQ= github.com/dave/dst v0.27.2 h1:4Y5VFTkhGLC1oddtNwuxxe36pnyLxMFXT51FOzH8Ekc= github.com/dave/dst v0.27.2/go.mod h1:jHh6EOibnHgcUW3WjKHisiooEkYwqpHLBSX1iOBhEyc= github.com/dave/jennifer v1.5.0 h1:HmgPN93bVDpkQyYbqhCHj5QlgvUkvEOzMyEvKLgCRrg= @@ -71,188 +88,270 @@ github.com/dave/jennifer v1.5.0/go.mod h1:4MnyiFIlZS3l5tSDn8VnzE6ffAhYBMB2SZntBs github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= +github.com/dgraph-io/badger v1.5.3/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/elastic/gosigar v0.14.3 h1:xwkKwPia+hSfg9GqrCUKYdId102m9qTJIIr7egmK/uo= +github.com/elastic/gosigar v0.14.3/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= github.com/fanixk/geohash v0.0.0-20150324002647-c1f9b5fa157a h1:Fyfh/dsHFrC6nkX7H7+nFdTd1wROlX/FxEIWVpKYf1U= github.com/fanixk/geohash v0.0.0-20150324002647-c1f9b5fa157a/go.mod h1:UgNw+PTmmGN8rV7RvjvnBMsoTU8ZXXnaT3hYsDTBlgQ= -github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= -github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= -github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4/go.mod h1:T9YF2M40nIgbVgp3rreNmTged+9HrbNTIQf1PsaIiTA= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= +github.com/frankban/quicktest v1.7.3/go.mod h1:V1d2J5pfxYH6EjBAgSK7YNXcXlTWxUHdE1sVDXkjnig= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= -github.com/getsentry/sentry-go v0.12.0 h1:era7g0re5iY13bHSdN/xMkyV+5zZppjRVQhZrXCaEIk= -github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= +github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= +github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= -github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= -github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= -github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= -github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= -github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= -github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= -github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= -github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= -github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= -github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= +github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= +github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= +github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= +github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= +github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= +github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk= +github.com/go-openapi/analysis v0.19.4/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk= +github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU= +github.com/go-openapi/analysis v0.19.7/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU= +github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= +github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= +github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= +github.com/go-openapi/errors v0.19.3/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= +github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= +github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= +github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= +github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= +github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= +github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= +github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= +github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs= +github.com/go-openapi/loads v0.19.3/go.mod h1:YVfqhUCdahYwR3f3iiwQLhicVRvLlU/WO5WPaZvcvSI= +github.com/go-openapi/loads v0.19.4/go.mod h1:zZVHonKd8DXyxyw4yfnVjPzBjIQcLt0CCsn0N0ZrQsk= +github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA= +github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64= +github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4= +github.com/go-openapi/runtime v0.19.11/go.mod h1:dhGWCTKRXlAfGnQG0ONViOZpjfg0m2gUt9nTQPQZuoo= +github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= +github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= +github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY= +github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= +github.com/go-openapi/spec v0.19.6/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= +github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= +github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= +github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY= +github.com/go-openapi/strfmt v0.19.2/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU= +github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU= +github.com/go-openapi/strfmt v0.19.4/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk= +github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= +github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= +github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.7/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY= +github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= +github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA= +github.com/go-openapi/validate v0.19.3/go.mod h1:90Vh6jjkTn+OT1Eefm0ZixWNFjhtOH7vS9k0lo6zwJo= +github.com/go-openapi/validate v0.19.6/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= +github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= +github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= +github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= +github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= +github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs= +github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= +github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= +github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk= +github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28= +github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo= +github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk= +github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw= +github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360= +github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg= +github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE= +github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8= +github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= +github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= +github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= +github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= +github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= +github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= +github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= +github.com/gocql/gocql v0.0.0-20200228163523-cd4b606dd2fb/go.mod h1:DL0ekTmBSTdlNF25Orwt/JMzqIq3EJ4MVa/J/uK64OY= +github.com/gogo/googleapis v1.0.1-0.20180501115203-b23578765ee5/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= -github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang/geo v0.0.0-20210211234256-740aa86cb551 h1:gtexQ/VGyN+VVFRXSFiguSNcXmS6rkKT+X7FdIrTtfo= github.com/golang/geo v0.0.0-20210211234256-740aa86cb551/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= +github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.2.0/go.mod h1:mJzapYve32yjrKlk9GbyCZHuPgZsrbyIbyKhSzOpg6s= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.13.0/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI= +github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= +github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI= +github.com/hashicorp/go-hclog v0.14.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-plugin v1.3.0/go.mod h1:F9eH4LrE/ZsRdbwhfjs9k9HoDUwAHnYtXdgmf1AVNs0= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= +github.com/hashicorp/yamux v0.0.0-20190923154419-df201c70410d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.3.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= -github.com/hydrogen18/memlistener v0.0.0-20141126152155-54553eb933fb/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= -github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= -github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= -github.com/iris-contrib/i18n v0.0.0-20171121225848-987a633949d0/go.mod h1:pMCz62A0xJL6I+umB2YTlFRwWXaDFA0jy+5HzGiJjqI= -github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= -github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= -github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= +github.com/jaegertracing/jaeger v1.18.1 h1:eFqjEpTKq2FfiZ/YX53oxeCePdIZyWvDfXaTAGj0r5E= +github.com/jaegertracing/jaeger v1.18.1/go.mod h1:WRzMFH62rje1VgbShlgk6UbWUNoo08uFFvs/x50aZKk= +github.com/jcmturner/gofork v0.0.0-20190328161633-dc7c13fece03/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= +github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= +github.com/jhump/protoreflect v1.6.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= -github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= -github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= -github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= -github.com/kataras/golog v0.0.9/go.mod h1:12HJgwBIZFNGL0EJnMRhmvGA0PQGx8VFwrZtM4CqbAk= -github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8= -github.com/kataras/iris/v12 v12.0.1/go.mod h1:udK4vLQKkdDqMGJJVd/msuMtN6hpYJhg/lSzuxjhO+U= -github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE= -github.com/kataras/neffos v0.0.10/go.mod h1:ZYmJC07hQPW67eKuzlfY7SO3bC0mw83A3j6im82hfqw= -github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE= -github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d/go.mod h1:NV88laa9UiiDuX9AhMbDPkGYSPugBOV6yTZB1l2K9Z0= -github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= -github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= +github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.9.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= -github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= +github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= -github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= -github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/lib/pq v0.0.0-20180327071824-d34b9ff171c2/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.6 h1:jbk+ZieJ0D7EVGJYpL9QTz7/YW6UHbmdnZWYyK5cdBs= github.com/lib/pq v1.10.6/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= +github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= -github.com/mediocregopher/mediocre-go-lib v0.0.0-20181029021733-cb65787f37ed/go.mod h1:dSsfyI2zABAdhcbvkXqgxOxrCsbYeHCPgrZkku60dSg= -github.com/mediocregopher/radix/v3 v3.3.0/go.mod h1:EmfVyvspXz1uZEyPBMyGK+kjWiKQGvsUt6O3Pj+LDCQ= -github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= -github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= +github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/mjibson/esc v0.2.0/go.mod h1:9Hw9gxxfHulMF5OJKCyhYD7PzlSdhzXyaGEBRPH1OPs= github.com/mmcloughlin/geohash v0.9.0 h1:FihR004p/aE1Sju6gcVq5OLDqGcMnpBY+8moBqIsVOs= github.com/mmcloughlin/geohash v0.9.0/go.mod h1:oNZxQo5yWJh0eMQEP/8hwQuVx9Z9tjwFUqcTB1SmG0c= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= -github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= -github.com/nats-io/nats.go v1.8.1/go.mod h1:BrFz9vVn0fU3AcH9Vn4Kd7W0NpJ651tD5omQ3M8LwxM= -github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= -github.com/nats-io/nkeys v0.0.2/go.mod h1:dab7URMsZm6Z/jp9Z5UGa87Uutgc2mVpXLC4B7TDb/4= -github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= +github.com/mozilla/tls-observatory v0.0.0-20190404164649-a3c1b6cfecfd/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/olivere/elastic v6.2.27+incompatible/go.mod h1:J+q1zQJTgAz9woqsbVRqGeB5G1iqDKVBWLNSYW8yfJ8= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0= +github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= +github.com/opentracing-contrib/go-stdlib v0.0.0-20190519235532-cf7a6c988dc9/go.mod h1:PLldrQSroqzH70Xl+1DQcGnefIbqsKR7UDaiux3zV+w= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/openzipkin/zipkin-go v0.4.3 h1:9EGwpqkgnwdEIJ+Od7QVSEIH+ocmm5nPat0G7sjsSdg= +github.com/openzipkin/zipkin-go v0.4.3/go.mod h1:M9wCJZFWCo2RiY+o1eBCEMe0Dp2S5LDHcMZmk3RmK7c= github.com/ory/dockertest/v3 v3.6.0/go.mod h1:4ZOpj8qBUmh8fcBSVzkH2bws2s91JdGvHUqan4GHEuQ= +github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= +github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 h1:q2e307iGHPdTGp0hoxKjt1H5pDo6utceo3dQVK3I5XQ= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= +github.com/pierrec/lz4 v0.0.0-20190327172049-315a67e90e41/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= +github.com/pierrec/lz4 v2.4.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrre/compare v1.0.2 h1:k4IUsHgh+dbcAOIWCfxVa/7G6STjADH2qmhomv+1quc= github.com/pierrre/compare v1.0.2/go.mod h1:8UvyRHH+9HS8Pczdd2z5x/wvv67krDwVxoOndaIIDVU= github.com/pierrre/geohash v1.0.0 h1:f/zfjdV4rVofTCz1FhP07T+EMQAvcMM2ioGZVt+zqjI= @@ -264,249 +363,324 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prashantv/protectmem v0.0.0-20171002184600-e20412882b3a/go.mod h1:lzZQ3Noex5pfAy7mkAeCjcBDteYU85uWWnJ/y6gKU8k= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= +github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= +github.com/prometheus/procfs v0.0.10/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg= -github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= +github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0= github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= -github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= -github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= +github.com/sectioneight/md-to-godoc v0.0.0-20161108233149-55e43be6c335/go.mod h1:lPZq22klO8la1kyImIDhrGytugMV0TsrsZB55a+xxI0= +github.com/securego/gosec v0.0.0-20200203094520-d13bb6d2420c/go.mod h1:gp0gaHj0WlmPh9BdsTmo1aq6C27yIPWdxCKGFGdVKBE= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/spf13/viper v1.6.2/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k= +github.com/streadway/quantile v0.0.0-20150917103942-b0c588724d25/go.mod h1:lbP8tGiBjZ5YWIc2fzuRpTaz0b/53vT6PEs3QuAWzuU= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.5.0/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/the42/cartconvert v0.0.0-20131203171324-aae784c392b8 h1:I4DY8wLxJXCrMYzDM6lKCGc3IQwJX0PlTLsd3nQqI3c= github.com/the42/cartconvert v0.0.0-20131203171324-aae784c392b8/go.mod h1:fWO/msnJVhHqN1yX6OBoxSyfj7TEj1hHiL8bJSQsK30= +github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/twpayne/go-geom v1.4.1 h1:LeivFqaGBRfyg0XJJ9pkudcptwhSSrYN9KZUW6HcgdA= github.com/twpayne/go-geom v1.4.1/go.mod h1:k/zktXdL+qnA6OgKsdEGUTA17jbQ2ZPTUa3CCySuGpE= github.com/twpayne/go-kml v1.5.2 h1:rFMw2/EwgkVssGS2MT6YfWSPZz6BgcJkLxQ53jnE8rQ= github.com/twpayne/go-kml v1.5.2/go.mod h1:kz8jAiIz6FIdU2Zjce9qGlVtgFYES9vt7BTPBHf5jl4= github.com/twpayne/go-polyline v1.0.0/go.mod h1:ICh24bcLYBX8CknfvNPKqoTbe+eg+MX1NPyJmSBo7pU= github.com/twpayne/go-waypoint v0.0.0-20200706203930-b263a7f6e4e8/go.mod h1:qj5pHncxKhu9gxtZEYWypA/z097sxhFlbTyOyt9gcnU= +github.com/uber/jaeger-client-go v2.22.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= +github.com/uber/jaeger-lib v2.2.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= +github.com/uber/tchannel-go v1.16.0/go.mod h1:Rrgz1eL8kMjW/nEzZos0t+Heq0O4LhnUJVA32OvWKHo= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= -github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= -github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= -github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= -github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= -github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= -github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= +github.com/vektra/mockery v0.0.0-20181123154057-e78b021dcbb5/go.mod h1:ppEjwdhyy7Y31EnHRDm1JkChoC7LXIJ7Ex0VYLWtZtQ= +github.com/wadey/gocovmerge v0.0.0-20160331181800-b5bfa59ec0ad/go.mod h1:Hy8o65+MXnS6EwGElrSRjUzQDLXreJlzYLlWiHtt8hM= +github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= +github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= +github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= -github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= -github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= -github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= +go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= +go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= +go.mongodb.org/mongo-driver v1.3.0/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg= +go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0 h1:dNzwXjZKpMpE2JhmO+9HsPl42NIXFIFSUSSs0fiqra0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0/go.mod h1:90PoxvaEB5n6AOdZvi+yWJQoE95U8Dhhw2bSyRqnTD0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.36.0 h1:JgtbA0xkWHnTmYk7YusopJFX6uleBmAuZ8n05NEh8nQ= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.36.0/go.mod h1:179AK5aar5R3eS9FucPy6rggvU0g52cvKId8pv4+v0c= +go.opentelemetry.io/otel/exporters/zipkin v1.36.0 h1:s0n95ya5tOG03exJ5JySOdJFtwGo4ZQ+KeY7Zro4CLI= +go.opentelemetry.io/otel/exporters/zipkin v1.36.0/go.mod h1:m9wRxtKA2MZ1HcnNC4BKI+9aYe434qRZTCvI7QGUN7Y= +go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE= +go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs= +go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs= +go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY= +go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk= +go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w= +go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w= +go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA= +go.opentelemetry.io/proto/otlp v1.6.0 h1:jQjP+AQyTf+Fe7OKj/MfkDrmK4MNVtw2NpXsf9fefDI= +go.opentelemetry.io/proto/otlp v1.6.0/go.mod h1:cicgGehlFuNdgZkcALOCh3VE6K/u2tAjzlRhDwmVpZc= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.5.1/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/automaxprocs v1.3.0/go.mod h1:9CWT6lKIep8U41DDaPiH6eFscnTyjfTANNQNx6LrIcA= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= +golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200214034016-1d94cc7ab1c6/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3 h1:/RIbNt/Zr7rVhIkQhooTxCxFcdWLGIKnZA4IXNFSrvo= golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= +golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191003171128-d98b1b443823/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= -golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY= +golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ= +golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200121082415-34d275377bf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= +golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4= +golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181112210238-4b1f3b6b1646/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200203023011-6f24f261dadb/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= -golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= +golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ= +golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20200218151345-dad8c97a84f5/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84 h1:R1r5J0u6Cx+RNl/6mezTw6oA14cmKC96FeUwL6A9bd4= -google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= -google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= +google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= +google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= -google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.40.1 h1:pnP7OclFFFgFi4VHQDQDaoXUVauOFyktqTsqqgzFKbc= -google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/grpc v1.72.1 h1:HR03wO6eyZ7lknl75XlxABNVLLFc2PAb6mHlYh756mA= +google.golang.org/grpc v1.72.1/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= -gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= -gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.52.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo= +gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q= +gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4= +gopkg.in/jcmturner/gokrb5.v7 v7.2.3/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM= +gopkg.in/jcmturner/gokrb5.v7 v7.5.0/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM= +gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= diff --git a/parser_test.go b/parser_test.go index f742391..7534a3a 100644 --- a/parser_test.go +++ b/parser_test.go @@ -12,5 +12,5 @@ func TestParser(t *testing.T) { p, err := parser.ParseOne("CREATE TABLE t (a TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP)") require.NoError(t, err) f := tree.DefaultPrettyCfg() - f.Pretty(p.AST) + t.Log(f.Pretty(p.AST)) } diff --git a/patches/0002-fix-quote-names.sql b/patches/0002-fix-quote-names.patch similarity index 84% rename from patches/0002-fix-quote-names.sql rename to patches/0002-fix-quote-names.patch index d972768..bb615c5 100644 --- a/patches/0002-fix-quote-names.sql +++ b/patches/0002-fix-quote-names.patch @@ -1,8 +1,8 @@ diff --git a/pkg/sql/sem/tree/type_name.go b/pkg/sql/sem/tree/type_name.go -index 898009a..5d4423a 100644 +index 10cd908..98daa0e 100644 --- a/pkg/sql/sem/tree/type_name.go +++ b/pkg/sql/sem/tree/type_name.go -@@ -56,8 +56,7 @@ func (t *TypeName) String() string { +@@ -42,8 +42,7 @@ func (t *TypeName) Format(ctx *FmtCtx) { // SQLString implements the ResolvableTypeReference interface. func (t *TypeName) SQLString() string { @@ -11,8 +11,8 @@ index 898009a..5d4423a 100644 + return AsStringWithFlags(t, FmtSimple) } - // FQString renders the type name in full, not omitting the prefix -@@ -250,14 +249,12 @@ func (node *ArrayTypeReference) Format(ctx *FmtCtx) { + func (t *TypeName) objectName() {} +@@ -240,14 +239,12 @@ func (node *ArrayTypeReference) Format(ctx *FmtCtx) { // SQLString implements the ResolvableTypeReference interface. func (node *ArrayTypeReference) SQLString() string { diff --git a/patches/0004-enc-always-quoted.patch b/patches/0004-enc-always-quoted.patch new file mode 100644 index 0000000..0e29ddf --- /dev/null +++ b/patches/0004-enc-always-quoted.patch @@ -0,0 +1,35 @@ +diff --git a/pkg/sql/lexbase/encode.go b/pkg/sql/lexbase/encode.go +index 0083555..47b9a37 100644 +--- a/pkg/sql/lexbase/encode.go ++++ b/pkg/sql/lexbase/encode.go +@@ -49,6 +49,11 @@ const ( + // EncFirstFreeFlagBit needs to remain unused; it is used as base + // bit offset for tree.FmtFlags. + EncFirstFreeFlagBit ++ ++ // EncAlwaysQuoted makes sure the string is always wrapped with quotes. ++ // This is used only to construct a statement against Oracle source, ++ // as Oracle is case insensitive if object name is not quoted. ++ EncAlwaysQuoted + ) + + // EncodeRestrictedSQLIdent writes the identifier in s to buf. The +@@ -56,8 +61,7 @@ const ( + // contains special characters, or the identifier is a reserved SQL + // keyword. + func EncodeRestrictedSQLIdent(buf *bytes.Buffer, s string, flags EncodeFlags) { +- if flags.HasFlags(EncBareIdentifiers) || +- (IsBareIdentifier(s) && (flags.HasFlags(EncBareReservedKeywords) || !isReservedKeyword(s))) { ++ if !flags.HasFlags(EncAlwaysQuoted) && (flags.HasFlags(EncBareIdentifiers) || (!isReservedKeyword(s) && IsBareIdentifier(s))) { + buf.WriteString(s) + return + } +@@ -68,7 +72,7 @@ func EncodeRestrictedSQLIdent(buf *bytes.Buffer, s string, flags EncodeFlags) { + // The identifier is only quoted if the flags don't tell otherwise and + // the identifier contains special characters. + func EncodeUnrestrictedSQLIdent(buf *bytes.Buffer, s string, flags EncodeFlags) { +- if flags.HasFlags(EncBareIdentifiers) || IsBareIdentifier(s) { ++ if !flags.HasFlags(EncAlwaysQuoted) && (flags.HasFlags(EncBareIdentifiers) || IsBareIdentifier(s)) { + buf.WriteString(s) + return + } diff --git a/patches/0004-fix-bazel-compl.patch b/patches/0004-fix-bazel-compl.patch deleted file mode 100644 index 5e9b3dc..0000000 --- a/patches/0004-fix-bazel-compl.patch +++ /dev/null @@ -1,64 +0,0 @@ -From d300afb062569278ff9e770b4f7e0ed0d84f6f82 Mon Sep 17 00:00:00 2001 -From: Oliver Tan -Date: Mon, 15 May 2023 14:21:32 +1000 -Subject: [PATCH] fix bazel compilation for grunning - ---- - pkg/util/grunning/disabled.go | 5 ----- - pkg/util/grunning/enabled.go | 28 ---------------------------- - 2 files changed, 33 deletions(-) - delete mode 100644 pkg/util/grunning/enabled.go - -diff --git a/pkg/util/grunning/disabled.go b/pkg/util/grunning/disabled.go -index 7fdc2f0..89fcb2d 100644 ---- a/pkg/util/grunning/disabled.go -+++ b/pkg/util/grunning/disabled.go -@@ -8,11 +8,6 @@ - // by the Apache License, Version 2.0, included in the file - // licenses/APL.txt. - --// See grunning.Supported() for an explanation behind this build tag. --// --//go:build freebsd || (linux && s390x) || !bazel --// +build freebsd linux,s390x !bazel -- - package grunning - - func grunningnanos() int64 { return 0 } -diff --git a/pkg/util/grunning/enabled.go b/pkg/util/grunning/enabled.go -deleted file mode 100644 -index ab12aae..0000000 ---- a/pkg/util/grunning/enabled.go -+++ /dev/null -@@ -1,28 +0,0 @@ --// Copyright 2022 The Cockroach Authors. --// --// Use of this software is governed by the Business Source License --// included in the file licenses/BSL.txt. --// --// As of the Change Date specified in that file, in accordance with --// the Business Source License, use of this software will be governed --// by the Apache License, Version 2.0, included in the file --// licenses/APL.txt. -- --// See grunning.Supported() for an explanation behind this build tag. --// --//go:build !(freebsd || (linux && s390x) || !bazel) --// +build !freebsd --// +build !linux !s390x --// +build bazel -- --package grunning -- --import _ "unsafe" // for go:linkname -- --// grunningnanos returns the running time observed by the current goroutine by --// linking to a private symbol in the (patched) runtime package. --// --//go:linkname grunningnanos runtime.grunningnanos --func grunningnanos() int64 -- --func supported() bool { return true } --- -2.39.2 (Apple Git-143) - diff --git a/patches/0005-delete-plpgsql-files.patch b/patches/0005-delete-plpgsql-files.patch deleted file mode 100644 index 9dd47ae..0000000 --- a/patches/0005-delete-plpgsql-files.patch +++ /dev/null @@ -1,3099 +0,0 @@ -From 6f5dc3ecb62864562a1a715962e4c70d0e19c91e Mon Sep 17 00:00:00 2001 -From: Jeremy Yang -Date: Mon, 12 Feb 2024 13:19:27 -0800 -Subject: [PATCH] delete plpgsql files - ---- - pkg/sql/plpgsql/parser/lexbase/keywords.go | 356 ----- - pkg/sql/plpgsql/parser/lexbase/tokens.go | 134 -- - pkg/sql/plpgsql/parser/lexbase/utils.go | 12 - - pkg/sql/plpgsql/parser/lexer.go | 501 ------ - pkg/sql/plpgsql/parser/parse.go | 136 -- - pkg/sql/plpgsql/parser/plpgsql.y | 1647 -------------------- - pkg/sql/scanner/plpgsql_scan.go | 246 --- - 7 files changed, 3032 deletions(-) - delete mode 100644 pkg/sql/plpgsql/parser/lexbase/keywords.go - delete mode 100644 pkg/sql/plpgsql/parser/lexbase/tokens.go - delete mode 100644 pkg/sql/plpgsql/parser/lexbase/utils.go - delete mode 100644 pkg/sql/plpgsql/parser/lexer.go - delete mode 100644 pkg/sql/plpgsql/parser/parse.go - delete mode 100644 pkg/sql/plpgsql/parser/plpgsql.y - delete mode 100644 pkg/sql/scanner/plpgsql_scan.go - -diff --git a/pkg/sql/plpgsql/parser/lexbase/keywords.go b/pkg/sql/plpgsql/parser/lexbase/keywords.go -deleted file mode 100644 -index 8cd3bc1..0000000 ---- a/pkg/sql/plpgsql/parser/lexbase/keywords.go -+++ /dev/null -@@ -1,356 +0,0 @@ --// Code generated by pkg/sql/lexbase/allkeywords. DO NOT EDIT. -- --package lexbase -- --var KeywordsCategories = map[string]string{ --"absolute": "U", --"alias": "U", --"all": "R", --"and": "U", --"array": "U", --"assert": "U", --"backward": "U", --"begin": "R", --"by": "R", --"call": "U", --"case": "R", --"chain": "U", --"close": "U", --"collate": "U", --"column": "U", --"column_name": "U", --"commit": "U", --"constant": "U", --"constraint": "U", --"constraint_name": "U", --"continue": "U", --"current": "U", --"cursor": "U", --"datatype": "U", --"debug": "U", --"declare": "R", --"default": "U", --"detail": "U", --"diagnostics": "U", --"do": "U", --"dump": "U", --"else": "R", --"elsif": "U", --"end": "R", --"end_case": "R", --"end_if": "R", --"errcode": "U", --"error": "U", --"exception": "U", --"execute": "R", --"exit": "U", --"fetch": "U", --"first": "U", --"for": "R", --"foreach": "R", --"forward": "U", --"from": "R", --"get": "U", --"hint": "U", --"if": "R", --"import": "U", --"in": "R", --"info": "U", --"insert": "U", --"into": "R", --"is": "U", --"last": "U", --"log": "U", --"loop": "R", --"merge": "U", --"message": "U", --"message_text": "U", --"move": "U", --"next": "U", --"no": "U", --"not": "R", --"notice": "U", --"no_scroll": "U", --"null": "R", --"open": "U", --"option": "U", --"or": "R", --"perform": "U", --"pg_context": "U", --"pg_datatype_name": "U", --"pg_exception_context": "U", --"pg_exception_detail": "U", --"pg_exception_hint": "U", --"print_strict_params": "U", --"prior": "U", --"query": "U", --"raise": "U", --"relative": "U", --"return": "U", --"returned_sqlstate": "U", --"return_next": "U", --"return_query": "U", --"reverse": "U", --"rollback": "U", --"rowtype": "U", --"row_count": "U", --"schema": "U", --"schema_name": "U", --"scroll": "U", --"slice": "U", --"sqlstate": "U", --"stacked": "U", --"strict": "R", --"table": "U", --"table_name": "U", --"then": "R", --"to": "R", --"type": "U", --"upsert": "U", --"use_column": "U", --"use_variable": "U", --"using": "R", --"variable_conflict": "U", --"warning": "U", --"when": "R", --"while": "R", --} -- --// KeywordNames contains all keywords sorted, so that pg_get_keywords returns --// deterministic results. --var KeywordNames = []string{ --"absolute", --"alias", --"all", --"and", --"array", --"assert", --"backward", --"begin", --"by", --"call", --"case", --"chain", --"close", --"collate", --"column", --"column_name", --"commit", --"constant", --"constraint", --"constraint_name", --"continue", --"current", --"cursor", --"datatype", --"debug", --"declare", --"default", --"detail", --"diagnostics", --"do", --"dump", --"else", --"elsif", --"end", --"end_case", --"end_if", --"errcode", --"error", --"exception", --"execute", --"exit", --"fetch", --"first", --"for", --"foreach", --"forward", --"from", --"get", --"hint", --"if", --"import", --"in", --"info", --"insert", --"into", --"is", --"last", --"log", --"loop", --"merge", --"message", --"message_text", --"move", --"next", --"no", --"not", --"notice", --"no_scroll", --"null", --"open", --"option", --"or", --"perform", --"pg_context", --"pg_datatype_name", --"pg_exception_context", --"pg_exception_detail", --"pg_exception_hint", --"print_strict_params", --"prior", --"query", --"raise", --"relative", --"return", --"returned_sqlstate", --"return_next", --"return_query", --"reverse", --"rollback", --"rowtype", --"row_count", --"schema", --"schema_name", --"scroll", --"slice", --"sqlstate", --"stacked", --"strict", --"table", --"table_name", --"then", --"to", --"type", --"upsert", --"use_column", --"use_variable", --"using", --"variable_conflict", --"warning", --"when", --"while", --} -- --// GetKeywordID returns the lex id of the SQL keyword k or IDENT if k is --// not a keyword. --func GetKeywordID(k string) int32 { -- // The previous implementation generated a map that did a string -> -- // id lookup. Various ideas were benchmarked and the implementation below -- // was the fastest of those, between 3% and 10% faster (at parsing, so the -- // scanning speedup is even more) than the map implementation. -- switch k { -- case "absolute": return ABSOLUTE -- case "alias": return ALIAS -- case "all": return ALL -- case "and": return AND -- case "array": return ARRAY -- case "assert": return ASSERT -- case "backward": return BACKWARD -- case "begin": return BEGIN -- case "by": return BY -- case "call": return CALL -- case "case": return CASE -- case "chain": return CHAIN -- case "close": return CLOSE -- case "collate": return COLLATE -- case "column": return COLUMN -- case "column_name": return COLUMN_NAME -- case "commit": return COMMIT -- case "constant": return CONSTANT -- case "constraint": return CONSTRAINT -- case "constraint_name": return CONSTRAINT_NAME -- case "continue": return CONTINUE -- case "current": return CURRENT -- case "cursor": return CURSOR -- case "datatype": return DATATYPE -- case "debug": return DEBUG -- case "declare": return DECLARE -- case "default": return DEFAULT -- case "detail": return DETAIL -- case "diagnostics": return DIAGNOSTICS -- case "do": return DO -- case "dump": return DUMP -- case "else": return ELSE -- case "elsif": return ELSIF -- case "end": return END -- case "end_case": return END_CASE -- case "end_if": return END_IF -- case "errcode": return ERRCODE -- case "error": return ERROR -- case "exception": return EXCEPTION -- case "execute": return EXECUTE -- case "exit": return EXIT -- case "fetch": return FETCH -- case "first": return FIRST -- case "for": return FOR -- case "foreach": return FOREACH -- case "forward": return FORWARD -- case "from": return FROM -- case "get": return GET -- case "hint": return HINT -- case "if": return IF -- case "import": return IMPORT -- case "in": return IN -- case "info": return INFO -- case "insert": return INSERT -- case "into": return INTO -- case "is": return IS -- case "last": return LAST -- case "log": return LOG -- case "loop": return LOOP -- case "merge": return MERGE -- case "message": return MESSAGE -- case "message_text": return MESSAGE_TEXT -- case "move": return MOVE -- case "next": return NEXT -- case "no": return NO -- case "not": return NOT -- case "notice": return NOTICE -- case "no_scroll": return NO_SCROLL -- case "null": return NULL -- case "open": return OPEN -- case "option": return OPTION -- case "or": return OR -- case "perform": return PERFORM -- case "pg_context": return PG_CONTEXT -- case "pg_datatype_name": return PG_DATATYPE_NAME -- case "pg_exception_context": return PG_EXCEPTION_CONTEXT -- case "pg_exception_detail": return PG_EXCEPTION_DETAIL -- case "pg_exception_hint": return PG_EXCEPTION_HINT -- case "print_strict_params": return PRINT_STRICT_PARAMS -- case "prior": return PRIOR -- case "query": return QUERY -- case "raise": return RAISE -- case "relative": return RELATIVE -- case "return": return RETURN -- case "returned_sqlstate": return RETURNED_SQLSTATE -- case "return_next": return RETURN_NEXT -- case "return_query": return RETURN_QUERY -- case "reverse": return REVERSE -- case "rollback": return ROLLBACK -- case "rowtype": return ROWTYPE -- case "row_count": return ROW_COUNT -- case "schema": return SCHEMA -- case "schema_name": return SCHEMA_NAME -- case "scroll": return SCROLL -- case "slice": return SLICE -- case "sqlstate": return SQLSTATE -- case "stacked": return STACKED -- case "strict": return STRICT -- case "table": return TABLE -- case "table_name": return TABLE_NAME -- case "then": return THEN -- case "to": return TO -- case "type": return TYPE -- case "upsert": return UPSERT -- case "use_column": return USE_COLUMN -- case "use_variable": return USE_VARIABLE -- case "using": return USING -- case "variable_conflict": return VARIABLE_CONFLICT -- case "warning": return WARNING -- case "when": return WHEN -- case "while": return WHILE -- default: return IDENT -- } --} -diff --git a/pkg/sql/plpgsql/parser/lexbase/tokens.go b/pkg/sql/plpgsql/parser/lexbase/tokens.go -deleted file mode 100644 -index 56ac04c..0000000 ---- a/pkg/sql/plpgsql/parser/lexbase/tokens.go -+++ /dev/null -@@ -1,134 +0,0 @@ --// Code generated by make. DO NOT EDIT. --// GENERATED FILE DO NOT EDIT -- --package lexbase -- --const IDENT = 57346 --const UIDENT = 57347 --const FCONST = 57348 --const SCONST = 57349 --const USCONST = 57350 --const BCONST = 57351 --const XCONST = 57352 --const ICONST = 57354 --const PARAM = 57355 --const TYPECAST = 57356 --const DOT_DOT = 57357 --const COLON_EQUALS = 57358 --const EQUALS_GREATER = 57359 --const LESS_EQUALS = 57360 --const GREATER_EQUALS = 57361 --const NOT_EQUALS = 57362 --const LESS_LESS = 57363 --const GREATER_GREATER = 57364 --const ABSOLUTE = 57365 --const ALIAS = 57366 --const ALL = 57367 --const AND = 57368 --const ARRAY = 57369 --const ASSERT = 57370 --const BACKWARD = 57371 --const BEGIN = 57372 --const BY = 57373 --const CALL = 57374 --const CASE = 57375 --const CHAIN = 57376 --const CLOSE = 57377 --const COLLATE = 57378 --const COLUMN = 57379 --const COLUMN_NAME = 57380 --const COMMIT = 57381 --const CONSTANT = 57382 --const CONSTRAINT = 57383 --const CONSTRAINT_NAME = 57384 --const CONTINUE = 57385 --const CURRENT = 57386 --const CURSOR = 57387 --const DATATYPE = 57388 --const DEBUG = 57389 --const DECLARE = 57390 --const DEFAULT = 57391 --const DETAIL = 57392 --const DIAGNOSTICS = 57393 --const DO = 57394 --const DUMP = 57395 --const ELSE = 57396 --const ELSIF = 57397 --const END = 57398 --const END_CASE = 57399 --const END_IF = 57400 --const ERRCODE = 57401 --const ERROR = 57402 --const EXCEPTION = 57403 --const EXECUTE = 57404 --const EXIT = 57405 --const FETCH = 57406 --const FIRST = 57407 --const FOR = 57408 --const FOREACH = 57409 --const FORWARD = 57410 --const FROM = 57411 --const GET = 57412 --const HINT = 57413 --const IF = 57414 --const IMPORT = 57415 --const IN = 57416 --const INFO = 57417 --const INSERT = 57418 --const INTO = 57419 --const IS = 57420 --const LAST = 57421 --const LOG = 57422 --const LOOP = 57423 --const MERGE = 57424 --const MESSAGE = 57425 --const MESSAGE_TEXT = 57426 --const MOVE = 57427 --const NEXT = 57428 --const NO = 57429 --const NO_SCROLL = 57430 --const NOT = 57431 --const NOTICE = 57432 --const NULL = 57433 --const OPEN = 57434 --const OPTION = 57435 --const OR = 57436 --const PERFORM = 57437 --const PG_CONTEXT = 57438 --const PG_DATATYPE_NAME = 57439 --const PG_EXCEPTION_CONTEXT = 57440 --const PG_EXCEPTION_DETAIL = 57441 --const PG_EXCEPTION_HINT = 57442 --const PRINT_STRICT_PARAMS = 57443 --const PRIOR = 57444 --const QUERY = 57445 --const RAISE = 57446 --const RELATIVE = 57447 --const RETURN = 57448 --const RETURN_NEXT = 57449 --const RETURN_QUERY = 57450 --const RETURNED_SQLSTATE = 57451 --const REVERSE = 57452 --const ROLLBACK = 57453 --const ROW_COUNT = 57454 --const ROWTYPE = 57455 --const SCHEMA = 57456 --const SCHEMA_NAME = 57457 --const SCROLL = 57458 --const SLICE = 57459 --const SQLSTATE = 57460 --const STACKED = 57461 --const STRICT = 57462 --const TABLE = 57463 --const TABLE_NAME = 57464 --const THEN = 57465 --const TO = 57466 --const TYPE = 57467 --const UPSERT = 57468 --const USE_COLUMN = 57469 --const USE_VARIABLE = 57470 --const USING = 57471 --const VARIABLE_CONFLICT = 57472 --const WARNING = 57473 --const WHEN = 57474 --const WHILE = 57475 -diff --git a/pkg/sql/plpgsql/parser/lexbase/utils.go b/pkg/sql/plpgsql/parser/lexbase/utils.go -deleted file mode 100644 -index 66596bf..0000000 ---- a/pkg/sql/plpgsql/parser/lexbase/utils.go -+++ /dev/null -@@ -1,12 +0,0 @@ --// Copyright 2023 The Cockroach Authors. --// --// Use of this software is governed by the Business Source License --// included in the file licenses/BSL.txt. --// --// As of the Change Date specified in that file, in accordance with --// the Business Source License, use of this software will be governed --// by the Apache License, Version 2.0, included in the file --// licenses/APL.txt. -- --// Package lexbase contains utilities for lexing plpgsql. --package lexbase -diff --git a/pkg/sql/plpgsql/parser/lexer.go b/pkg/sql/plpgsql/parser/lexer.go -deleted file mode 100644 -index 9201b03..0000000 ---- a/pkg/sql/plpgsql/parser/lexer.go -+++ /dev/null -@@ -1,501 +0,0 @@ --// Copyright 2023 The Cockroach Authors. --// --// Use of this software is governed by the Business Source License --// included in the file licenses/BSL.txt. --// --// As of the Change Date specified in that file, in accordance with --// the Business Source License, use of this software will be governed --// by the Apache License, Version 2.0, included in the file --// licenses/APL.txt. -- --package parser -- --import ( -- "strings" -- -- "github.com/cockroachdb/cockroachdb-parser/pkg/sql/parser" -- "github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode" -- "github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror" -- "github.com/cockroachdb/cockroachdb-parser/pkg/sql/sem/plpgsqltree" -- "github.com/cockroachdb/cockroachdb-parser/pkg/sql/sem/tree" -- "github.com/cockroachdb/cockroachdb-parser/pkg/sql/types" -- unimp "github.com/cockroachdb/cockroachdb-parser/pkg/util/errorutil/unimplemented" -- "github.com/cockroachdb/errors" --) -- --type lexer struct { -- in string -- // tokens contains tokens generated by the scanner. -- tokens []plpgsqlSymType -- -- // The type that should be used when an INT or SERIAL is encountered. -- nakedIntType *types.T -- -- // lastPos is the position into the tokens slice of the last -- // token returned by Lex(). -- lastPos int -- -- stmt *plpgsqltree.Block -- -- // numPlaceholders is 1 + the highest placeholder index encountered. -- numPlaceholders int -- numAnnotations tree.AnnotationIdx -- -- lastError error -- -- parser plpgsqlParser --} -- --func (l *lexer) init(sql string, tokens []plpgsqlSymType, nakedIntType *types.T, p plpgsqlParser) { -- l.in = sql -- l.tokens = tokens -- l.lastPos = -1 -- l.stmt = nil -- l.numPlaceholders = 0 -- l.numAnnotations = 0 -- l.lastError = nil -- l.nakedIntType = nakedIntType -- l.parser = p --} -- --// cleanup is used to avoid holding on to memory unnecessarily (for the cases --// where we reuse a scanner). --func (l *lexer) cleanup() { -- l.tokens = nil -- l.stmt = nil -- l.lastError = nil --} -- --// Lex lexes a token from input. --// to push the tokens back (move l.pos back). --func (l *lexer) Lex(lval *plpgsqlSymType) int { -- l.lastPos++ -- // The core lexing takes place in the scanner. Here we do a small bit of post -- // processing of the lexical tokens so that the grammar only requires -- // one-token lookahead despite SQL requiring multi-token lookahead in some -- // cases. These special cases are handled below and the returned tokens are -- // adjusted to reflect the lookahead (LA) that occurred. -- if l.lastPos >= len(l.tokens) { -- lval.id = 0 -- lval.pos = int32(len(l.in)) -- lval.str = "EOF" -- return 0 -- } -- *lval = l.tokens[l.lastPos] -- -- switch lval.id { -- case RETURN: -- nextToken := plpgsqlSymType{} -- if l.lastPos+1 < len(l.tokens) { -- nextToken = l.tokens[l.lastPos+1] -- } -- switch nextToken.id { -- case NEXT: -- lval.id = RETURN_NEXT -- case QUERY: -- lval.id = RETURN_QUERY -- } -- case END: -- nextToken := plpgsqlSymType{} -- if l.lastPos+1 < len(l.tokens) { -- nextToken = l.tokens[l.lastPos+1] -- } -- switch nextToken.id { -- case IF: -- lval.id = END_IF -- case CASE: -- lval.id = END_CASE -- } -- case NO: -- nextToken := plpgsqlSymType{} -- if l.lastPos+1 < len(l.tokens) { -- nextToken = l.tokens[l.lastPos+1] -- } -- switch nextToken.id { -- case SCROLL: -- lval.id = NO_SCROLL -- } -- } -- -- return int(lval.id) --} -- --// MakeExecSqlStmt makes an Execute node. --func (l *lexer) MakeExecSqlStmt() (*plpgsqltree.Execute, error) { -- if l.parser.Lookahead() != -1 { -- // Push back the lookahead token so that it can be included. -- l.PushBack(1) -- } -- // Push back the first token so that it's included in the SQL string. -- l.PushBack(1) -- startPos, endPos, _, err := l.readSQLConstruct(false /* isExpr */, ';') -- if err != nil { -- return nil, err -- } -- // Move past the semicolon. -- l.lastPos++ -- -- var haveInto, haveStrict bool -- var intoStartPos, intoEndPos int -- var target []plpgsqltree.Variable -- firstTok := l.tokens[startPos] -- tok := firstTok -- for pos := startPos; pos < endPos; pos++ { -- prevTok := tok -- tok = l.tokens[pos] -- if tok.id == INTO { -- if prevTok.id == INSERT || prevTok.id == UPSERT || -- prevTok.id == MERGE || firstTok.id == IMPORT { -- // INSERT INTO, UPSERT INTO, MERGE INTO, and IMPORT ... INTO are not -- // INTO-targets. -- continue -- } -- if haveInto { -- return nil, errors.New("INTO specified more than once") -- } -- haveInto = true -- intoStartPos = pos -- pos++ -- if pos+1 < endPos && l.tokens[pos].id == STRICT { -- haveStrict = true -- pos++ -- } -- // Read in one or more comma-separated variables as the INTO target. -- for ; pos < endPos; pos += 2 { -- tok = l.tokens[pos] -- if tok.id != IDENT { -- return nil, errors.Newf("\"%s\" is not a scalar variable", tok.str) -- } -- variable := plpgsqltree.Variable(strings.TrimSpace(l.getStr(pos, pos+1))) -- target = append(target, variable) -- if pos+1 == endPos || l.tokens[pos+1].id != ',' { -- // This is the end of the target list. -- break -- } -- } -- intoEndPos = pos + 1 -- } -- } -- -- var sql string -- if haveInto { -- sql = l.getStr(startPos, intoStartPos) + l.getStr(intoEndPos, endPos) -- } else { -- sql = l.getStr(startPos, endPos) -- } -- sqlStmt, err := parser.ParseOne(sql) -- if err != nil { -- return nil, err -- } -- -- // Note: PG disallows directly writing SQL statements that return rows, like -- // a SELECT or a mutation with RETURNING. It is difficult to determine this -- // for all possible statements, and execution is able to handle it, so we -- // allow SQL statements that return rows. -- if target != nil && sqlStmt.AST.StatementReturnType() != tree.Rows { -- return nil, pgerror.New(pgcode.Syntax, "INTO used with a command that cannot return data") -- } -- return &plpgsqltree.Execute{ -- SqlStmt: sqlStmt.AST, -- Strict: haveStrict, -- Target: target, -- }, nil --} -- --func (l *lexer) MakeDynamicExecuteStmt() (*plpgsqltree.DynamicExecute, error) { -- cmdStr, _, err := l.ReadSqlStatement(INTO, USING, ';') -- if err != nil { -- return nil, err -- } -- ret := &plpgsqltree.DynamicExecute{ -- Query: cmdStr, -- } -- -- var lval plpgsqlSymType -- l.Lex(&lval) -- for { -- if lval.id == INTO { -- if ret.Into { -- return nil, errors.New("multiple INTO keywords") -- } -- ret.Into = true -- nextTok := l.Peek() -- if nextTok.id == int32(STRICT) { -- l.Lex(&lval) -- ret.Strict = true -- } -- // TODO we need to read each "INTO" variable name instead of just a -- // string. -- _, _, err = l.ReadSqlExpr(USING, ';') -- if err != nil { -- return nil, err -- } -- l.Lex(&lval) -- } else if lval.id == USING { -- if ret.Params != nil { -- return nil, errors.New("multiple USING keywords") -- } -- ret.Params = make([]plpgsqltree.Expr, 0) -- for { -- _, _, err = l.ReadSqlExpr(',', ';', INTO) -- if err != nil { -- return nil, err -- } -- ret.Params = append(ret.Params, nil) -- l.Lex(&lval) -- if lval.id == ';' { -- break -- } -- } -- } else if lval.id == ';' { -- break -- } else { -- return nil, errors.Newf("unexpected token: %s", lval.id) -- } -- } -- -- return ret, nil --} -- --func (l *lexer) readSQLConstruct( -- isExpr bool, terminator1 int, terminators ...int, --) (startPos, endPos, terminatorMet int, err error) { -- if l.parser.Lookahead() != -1 { -- // Push back the lookahead token so that it can be included. -- l.PushBack(1) -- } -- parenLevel := 0 -- startPos = l.lastPos + 1 -- for l.lastPos < len(l.tokens) { -- tok := l.Peek() -- if int(tok.id) == terminator1 && parenLevel == 0 { -- terminatorMet = terminator1 -- break -- } -- for _, term := range terminators { -- if int(tok.id) == term && parenLevel == 0 { -- terminatorMet = term -- } -- } -- if terminatorMet != 0 { -- break -- } -- if tok.id == '(' || tok.id == '[' { -- parenLevel++ -- } else if tok.id == ')' || tok.id == ']' { -- parenLevel-- -- if parenLevel < 0 { -- return 0, 0, 0, errors.New("mismatched parentheses") -- } -- } -- l.lastPos++ -- } -- if parenLevel != 0 { -- return 0, 0, 0, errors.New("mismatched parentheses") -- } -- endPos = l.lastPos + 1 -- if endPos > len(l.tokens) { -- endPos = len(l.tokens) -- } -- if endPos <= startPos { -- if isExpr { -- return 0, 0, 0, errors.New("missing expression") -- } else { -- return 0, 0, 0, errors.New("missing SQL statement") -- } -- } -- return startPos, endPos, terminatorMet, nil --} -- --func (l *lexer) MakeFetchOrMoveStmt(isMove bool) (plpgsqltree.Statement, error) { -- if l.parser.Lookahead() != -1 { -- // Push back the lookahead token so that it can be included. -- l.PushBack(1) -- } -- prefix := "FETCH " -- if isMove { -- prefix = "MOVE " -- } -- sqlStr, terminator, err := l.ReadSqlStatement(INTO, ';') -- if err != nil { -- return nil, err -- } -- sqlStr = prefix + sqlStr -- sqlStmt, err := parser.ParseOne(sqlStr) -- if err != nil { -- return nil, err -- } -- var cursor tree.CursorStmt -- switch t := sqlStmt.AST.(type) { -- case *tree.FetchCursor: -- cursor = t.CursorStmt -- case *tree.MoveCursor: -- cursor = t.CursorStmt -- default: -- return nil, errors.Newf("invalid FETCH or MOVE syntax") -- } -- var target []plpgsqltree.Variable -- if !isMove { -- if terminator != INTO { -- return nil, errors.Newf("invalid syntax for FETCH") -- } -- // Read past the INTO. -- l.lastPos++ -- startPos, endPos, _, err := l.readSQLConstruct(true /* isExpr */, ';') -- if err != nil { -- return nil, err -- } -- for pos := startPos; pos < endPos; pos += 2 { -- tok := l.tokens[pos] -- if tok.id != IDENT { -- return nil, errors.Newf("\"%s\" is not a scalar variable", tok.str) -- } -- if pos+1 != endPos && l.tokens[pos+1].id != ',' { -- return nil, errors.Newf("expected INTO target to be a comma-separated list") -- } -- variable := plpgsqltree.Variable(strings.TrimSpace(l.getStr(pos, pos+1))) -- target = append(target, variable) -- } -- if len(target) == 0 { -- return nil, errors.Newf("expected INTO target") -- } -- } -- // Move past the semicolon. -- l.lastPos++ -- return &plpgsqltree.Fetch{ -- Cursor: cursor, -- Target: target, -- IsMove: isMove, -- }, nil --} -- --func (l *lexer) ReadSqlExpr( -- terminator1 int, terminators ...int, --) (sqlStr string, terminatorMet int, err error) { -- var startPos, endPos int -- startPos, endPos, terminatorMet, err = l.readSQLConstruct( -- true /* isExpr */, terminator1, terminators..., -- ) -- return l.getStr(startPos, endPos), terminatorMet, err --} -- --func (l *lexer) ReadSqlStatement( -- terminator1 int, terminators ...int, --) (sqlStr string, terminatorMet int, err error) { -- var startPos, endPos int -- startPos, endPos, terminatorMet, err = l.readSQLConstruct( -- false /* isExpr */, terminator1, terminators..., -- ) -- return l.getStr(startPos, endPos), terminatorMet, err --} -- --func (l *lexer) getStr(startPos, endPos int) string { -- if endPos <= startPos { -- return "" -- } -- end := len(l.in) -- if endPos < len(l.tokens) { -- end = int(l.tokens[endPos].Pos()) -- } -- start := int(l.tokens[startPos].Pos()) -- return l.in[start:end] --} -- --// Peek peeks --func (l *lexer) Peek() plpgsqlSymType { -- if l.lastPos+1 < len(l.tokens) { -- return l.tokens[l.lastPos+1] -- } -- return plpgsqlSymType{} --} -- --// PushBack rewinds the lexer by n tokens. --func (l *lexer) PushBack(n int) { -- if n < 0 { -- panic(errors.AssertionFailedf("negative n provided to PushBack")) -- } -- l.lastPos -= n -- if l.lastPos < -1 { -- // Return to the initialized state. -- l.lastPos = -1 -- } -- if n >= 1 { -- // Invalidate the parser lookahead token. -- l.parser.(*plpgsqlParserImpl).char = -1 -- } --} -- --func (l *lexer) lastToken() plpgsqlSymType { -- if l.lastPos < 0 { -- return plpgsqlSymType{} -- } -- -- if l.lastPos >= len(l.tokens) { -- return plpgsqlSymType{ -- id: 0, -- pos: int32(len(l.in)), -- str: "EOF", -- } -- } -- return l.tokens[l.lastPos] --} -- --// SetStmt is called from the parser when the statement is constructed. --func (l *lexer) SetStmt(stmt plpgsqltree.Statement) { -- l.stmt = stmt.(*plpgsqltree.Block) --} -- --// setErr is called from parsing action rules to register an error observed --// while running the action. That error becomes the actual "cause" of the --// syntax error. --func (l *lexer) setErr(err error) { -- err = pgerror.WithCandidateCode(err, pgcode.Syntax) -- l.lastError = err -- lastTok := l.lastToken() -- l.lastError = parser.PopulateErrorDetails(lastTok.id, lastTok.str, lastTok.pos, l.lastError, l.in) --} -- --func (l *lexer) Error(e string) { -- e = strings.TrimPrefix(e, "syntax error: ") // we'll add it again below. -- err := pgerror.WithCandidateCode(errors.Newf("%s", e), pgcode.Syntax) -- lastTok := l.lastToken() -- l.lastError = parser.PopulateErrorDetails(lastTok.id, lastTok.str, lastTok.pos, err, l.in) --} -- --// Unimplemented wraps Error, setting lastUnimplementedError. --func (l *lexer) Unimplemented(feature string) { -- l.lastError = unimp.New(feature, "this syntax") -- lastTok := l.lastToken() -- l.lastError = parser.PopulateErrorDetails(lastTok.id, lastTok.str, lastTok.pos, l.lastError, l.in) -- l.lastError = &tree.UnsupportedError{ -- Err: l.lastError, -- FeatureName: feature, -- } --} -- --func (l *lexer) GetTypeFromValidSQLSyntax(sqlStr string) (tree.ResolvableTypeReference, error) { -- return parser.GetTypeFromValidSQLSyntax(sqlStr) --} -- --func (l *lexer) ParseExpr(sqlStr string) (plpgsqltree.Expr, error) { -- // Use ParseExprs instead of ParseExpr in order to correctly handle the case -- // when multiple expressions are incorrectly passed. -- exprs, err := parser.ParseExprs([]string{sqlStr}) -- if err != nil { -- return nil, err -- } -- if len(exprs) != 1 { -- return nil, pgerror.Newf(pgcode.Syntax, "query returned %d columns", len(exprs)) -- } -- return exprs[0], nil --} -- --func checkLoopLabels(start, end string) error { -- if start == "" && end != "" { -- return errors.Newf("end label \"%s\" specified for unlabeled block", end) -- } -- if end != "" && start != end { -- return errors.Newf("end label \"%s\" differs from block's label \"%s\"", end, start) -- } -- return nil --} -diff --git a/pkg/sql/plpgsql/parser/parse.go b/pkg/sql/plpgsql/parser/parse.go -deleted file mode 100644 -index 520830a..0000000 ---- a/pkg/sql/plpgsql/parser/parse.go -+++ /dev/null -@@ -1,136 +0,0 @@ --// Copyright 2023 The Cockroach Authors. --// --// Use of this software is governed by the Business Source License --// included in the file licenses/BSL.txt. --// --// As of the Change Date specified in that file, in accordance with --// the Business Source License, use of this software will be governed --// by the Apache License, Version 2.0, included in the file --// licenses/APL.txt. -- --// Package parser exposes a parser for plpgsql. --package parser -- --import ( -- "go/constant" -- -- "github.com/cockroachdb/cockroachdb-parser/pkg/sql/parser/statements" -- "github.com/cockroachdb/cockroachdb-parser/pkg/sql/scanner" -- "github.com/cockroachdb/cockroachdb-parser/pkg/sql/sem/tree" -- "github.com/cockroachdb/cockroachdb-parser/pkg/sql/types" -- "github.com/cockroachdb/errors" --) -- --func init() { -- scanner.NewNumValFn = func(a constant.Value, s string, b bool) interface{} { return tree.NewNumVal(a, s, b) } -- scanner.NewPlaceholderFn = func(s string) (interface{}, error) { return tree.NewPlaceholder(s) } --} -- --// Parser wraps a scanner, parser and other utilities present in the parser --// package. --type Parser struct { -- scanner scanner.PLpgSQLScanner -- lexer lexer -- parserImpl plpgsqlParserImpl -- tokBuf [8]plpgsqlSymType --} -- --// INT8 is the historical interpretation of INT. This should be left --// alone in the future, since there are many sql fragments stored --// in various descriptors. Any user input that was created after --// INT := INT4 will simply use INT4 in any resulting code. --var defaultNakedIntType = types.Int -- --// Parse parses the sql and returns a list of statements. --func (p *Parser) Parse(sql string) (statements.PLpgStatement, error) { -- return p.parseWithDepth(1, sql, defaultNakedIntType) --} -- --func (p *Parser) scanFnBlock() (sql string, tokens []plpgsqlSymType, done bool) { -- var lval plpgsqlSymType -- tokens = p.tokBuf[:0] -- -- // Scan the first token. -- p.scanner.Scan(&lval) -- if lval.id == 0 { -- return "", nil, true -- } -- -- startPos := lval.pos -- // We make the resulting token positions match the returned string. -- lval.pos = 0 -- tokens = append(tokens, lval) -- for { -- if lval.id == ERROR { -- return p.scanner.In()[startPos:], tokens, true -- } -- // Reset the plpgsqlSymType struct before scanning. -- lval = plpgsqlSymType{} -- posBeforeScan := p.scanner.Pos() -- p.scanner.Scan(&lval) -- if lval.id == 0 { -- return p.scanner.In()[startPos:posBeforeScan], tokens, (lval.id == 0) -- } -- lval.pos -= startPos -- tokens = append(tokens, lval) -- } --} -- --func (p *Parser) parseWithDepth( -- depth int, plpgsql string, nakedIntType *types.T, --) (statements.PLpgStatement, error) { -- p.scanner.Init(plpgsql) -- defer p.scanner.Cleanup() -- sql, tokens, done := p.scanFnBlock() -- stmt, err := p.parse(depth+1, sql, tokens, nakedIntType) -- if err != nil { -- return statements.PLpgStatement{}, err -- } -- if !done { -- return statements.PLpgStatement{}, errors.AssertionFailedf("invalid plpgsql function: %s", plpgsql) -- } -- return stmt, nil --} -- --// parse parses a statement from the given scanned tokens. --func (p *Parser) parse( -- depth int, sql string, tokens []plpgsqlSymType, nakedIntType *types.T, --) (statements.PLpgStatement, error) { -- p.lexer.init(sql, tokens, nakedIntType, &p.parserImpl) -- defer p.lexer.cleanup() -- if p.parserImpl.Parse(&p.lexer) != 0 { -- if p.lexer.lastError == nil { -- // This should never happen -- there should be an error object -- // every time Parse() returns nonzero. We're just playing safe -- // here. -- p.lexer.Error("syntax error") -- } -- err := p.lexer.lastError -- -- // Compatibility with 19.1 telemetry: prefix the telemetry keys -- // with the "syntax." prefix. -- // TODO(knz): move the auto-prefixing of feature names to a -- // higher level in the call stack. -- tkeys := errors.GetTelemetryKeys(err) -- if len(tkeys) > 0 { -- for i := range tkeys { -- tkeys[i] = "syntax." + tkeys[i] -- } -- err = errors.WithTelemetry(err, tkeys...) -- } -- -- return statements.PLpgStatement{}, err -- } -- return statements.PLpgStatement{ -- AST: p.lexer.stmt, -- SQL: sql, -- NumPlaceholders: p.lexer.numPlaceholders, -- NumAnnotations: p.lexer.numAnnotations, -- }, nil --} -- --// Parse parses a sql statement string and returns a list of Statements. --func Parse(sql string) (statements.PLpgStatement, error) { -- var p Parser -- return p.parseWithDepth(1, sql, defaultNakedIntType) --} -diff --git a/pkg/sql/plpgsql/parser/plpgsql.y b/pkg/sql/plpgsql/parser/plpgsql.y -deleted file mode 100644 -index 8ee4069..0000000 ---- a/pkg/sql/plpgsql/parser/plpgsql.y -+++ /dev/null -@@ -1,1647 +0,0 @@ --%{ --package parser -- --import ( -- "github.com/cockroachdb/cockroach/pkg/sql/parser" -- "github.com/cockroachdb/cockroach/pkg/sql/scanner" -- "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" -- "github.com/cockroachdb/cockroach/pkg/sql/sem/plpgsqltree" -- "github.com/cockroachdb/errors" -- "github.com/cockroachdb/redact" --) --%} -- --%{ --func setErr(plpgsqllex plpgsqlLexer, err error) int { -- plpgsqllex.(*lexer).setErr(err) -- return 1 --} -- --func unimplemented(plpgsqllex plpgsqlLexer, feature string) int { -- plpgsqllex.(*lexer).Unimplemented(feature) -- return 1 --} -- --//functions to cast plpgsqlSymType/sqlSymUnion to other types. --var _ scanner.ScanSymType = &plpgsqlSymType{} -- --func (s *plpgsqlSymType) ID() int32 { -- return s.id --} -- --func (s *plpgsqlSymType) SetID(id int32) { -- s.id = id --} -- --func (s *plpgsqlSymType) Pos() int32 { -- return s.pos --} -- --func (s *plpgsqlSymType) SetPos(pos int32) { -- s.pos = pos --} -- --func (s *plpgsqlSymType) Str() string { -- return s.str --} -- --func (s *plpgsqlSymType) SetStr(str string) { -- s.str = str --} -- --func (s *plpgsqlSymType) UnionVal() interface{} { -- return s.union.val --} -- --func (s *plpgsqlSymType) SetUnionVal(val interface{}) { -- s.union.val = val --} -- --func (s *plpgsqlSymType) plpgsqlScanSymType() {} -- --type plpgsqlSymUnion struct { -- val interface{} --} -- --func (u *plpgsqlSymUnion) block() *plpgsqltree.Block { -- return u.val.(*plpgsqltree.Block) --} -- --func (u *plpgsqlSymUnion) caseWhen() *plpgsqltree.CaseWhen { -- return u.val.(*plpgsqltree.CaseWhen) --} -- --func (u *plpgsqlSymUnion) caseWhens() []*plpgsqltree.CaseWhen { -- return u.val.([]*plpgsqltree.CaseWhen) --} -- --func (u *plpgsqlSymUnion) statement() plpgsqltree.Statement { -- return u.val.(plpgsqltree.Statement) --} -- --func (u *plpgsqlSymUnion) statements() []plpgsqltree.Statement { -- return u.val.([]plpgsqltree.Statement) --} -- --func (u *plpgsqlSymUnion) int32() int32 { -- return u.val.(int32) --} -- --func (u *plpgsqlSymUnion) uint32() uint32 { -- return u.val.(uint32) --} -- --func (u *plpgsqlSymUnion) bool() bool { -- return u.val.(bool) --} -- --func (u *plpgsqlSymUnion) numVal() *tree.NumVal { -- return u.val.(*tree.NumVal) --} -- --func (u *plpgsqlSymUnion) typ() tree.ResolvableTypeReference { -- return u.val.(tree.ResolvableTypeReference) --} -- --func (u *plpgsqlSymUnion) getDiagnosticsKind() plpgsqltree.GetDiagnosticsKind { -- return u.val.(plpgsqltree.GetDiagnosticsKind) --} -- --func (u *plpgsqlSymUnion) getDiagnosticsItem() *plpgsqltree.GetDiagnosticsItem { -- return u.val.(*plpgsqltree.GetDiagnosticsItem) --} -- --func (u *plpgsqlSymUnion) getDiagnosticsItemList() plpgsqltree.GetDiagnosticsItemList { -- return u.val.(plpgsqltree.GetDiagnosticsItemList) --} -- --func (u *plpgsqlSymUnion) elseIf() []plpgsqltree.ElseIf { -- return u.val.([]plpgsqltree.ElseIf) --} -- --func (u *plpgsqlSymUnion) open() *plpgsqltree.Open { -- return u.val.(*plpgsqltree.Open) --} -- --func (u *plpgsqlSymUnion) expr() plpgsqltree.Expr { -- if u.val == nil { -- return nil -- } -- return u.val.(plpgsqltree.Expr) --} -- --func (u *plpgsqlSymUnion) exprs() []plpgsqltree.Expr { -- return u.val.([]plpgsqltree.Expr) --} -- --func (u *plpgsqlSymUnion) raiseOption() *plpgsqltree.RaiseOption { -- return u.val.(*plpgsqltree.RaiseOption) --} -- --func (u *plpgsqlSymUnion) raiseOptions() []plpgsqltree.RaiseOption { -- return u.val.([]plpgsqltree.RaiseOption) --} -- -- --func (u *plpgsqlSymUnion) exception() *plpgsqltree.Exception { -- return u.val.(*plpgsqltree.Exception) --} -- --func (u *plpgsqlSymUnion) exceptions() []plpgsqltree.Exception { -- return u.val.([]plpgsqltree.Exception) --} -- --func (u *plpgsqlSymUnion) condition() *plpgsqltree.Condition { -- return u.val.(*plpgsqltree.Condition) --} -- --func (u *plpgsqlSymUnion) conditions() []plpgsqltree.Condition { -- return u.val.([]plpgsqltree.Condition) --} -- --func (u *plpgsqlSymUnion) cursorScrollOption() tree.CursorScrollOption { -- return u.val.(tree.CursorScrollOption) --} -- --func (u *plpgsqlSymUnion) sqlStatement() tree.Statement { -- return u.val.(tree.Statement) --} -- --%} --/* -- * Basic non-keyword token types. These are hard-wired into the core lexer. -- * They must be listed first so that their numeric codes do not depend on -- * the set of keywords. Keep this list in sync with backend/parser/gram.y! -- * -- * Some of these are not directly referenced in this file, but they must be -- * here anyway. -- */ --%token IDENT UIDENT FCONST SCONST USCONST BCONST XCONST Op --%token <*tree.NumVal> ICONST PARAM --%token TYPECAST DOT_DOT COLON_EQUALS EQUALS_GREATER --%token LESS_EQUALS GREATER_EQUALS NOT_EQUALS -- --/* -- * Other tokens recognized by plpgsql's lexer interface layer (pl_scanner.c). -- */ --%token LESS_LESS GREATER_GREATER -- --/* -- * Keyword tokens. Some of these are reserved and some are not; -- * see pl_scanner.c for info. Be sure unreserved keywords are listed -- * in the "unreserved_keyword" production below. -- */ --%token ABSOLUTE --%token ALIAS --%token ALL --%token AND --%token ARRAY --%token ASSERT --%token BACKWARD --%token BEGIN --%token BY --%token CALL --%token CASE --%token CHAIN --%token CLOSE --%token COLLATE --%token COLUMN --%token COLUMN_NAME --%token COMMIT --%token CONSTANT --%token CONSTRAINT --%token CONSTRAINT_NAME --%token CONTINUE --%token CURRENT --%token CURSOR --%token DATATYPE --%token DEBUG --%token DECLARE --%token DEFAULT --%token DETAIL --%token DIAGNOSTICS --%token DO --%token DUMP --%token ELSE --%token ELSIF --%token END --%token END_CASE --%token END_IF --%token ERRCODE --%token ERROR --%token EXCEPTION --%token EXECUTE --%token EXIT --%token FETCH --%token FIRST --%token FOR --%token FOREACH --%token FORWARD --%token FROM --%token GET --%token HINT --%token IF --%token IMPORT --%token IN --%token INFO --%token INSERT --%token INTO --%token IS --%token LAST --%token LOG --%token LOOP --%token MERGE --%token MESSAGE --%token MESSAGE_TEXT --%token MOVE --%token NEXT --%token NO --%token NO_SCROLL --%token NOT --%token NOTICE --%token NULL --%token OPEN --%token OPTION --%token OR --%token PERFORM --%token PG_CONTEXT --%token PG_DATATYPE_NAME --%token PG_EXCEPTION_CONTEXT --%token PG_EXCEPTION_DETAIL --%token PG_EXCEPTION_HINT --%token PRINT_STRICT_PARAMS --%token PRIOR --%token QUERY --%token RAISE --%token RELATIVE --%token RETURN --%token RETURN_NEXT --%token RETURN_QUERY --%token RETURNED_SQLSTATE --%token REVERSE --%token ROLLBACK --%token ROW_COUNT --%token ROWTYPE --%token SCHEMA --%token SCHEMA_NAME --%token SCROLL --%token SLICE --%token SQLSTATE --%token STACKED --%token STRICT --%token TABLE --%token TABLE_NAME --%token THEN --%token TO --%token TYPE --%token UPSERT --%token USE_COLUMN --%token USE_VARIABLE --%token USING --%token VARIABLE_CONFLICT --%token WARNING --%token WHEN --%token WHILE -- -- --%union { -- id int32 -- pos int32 -- str string -- union plpgsqlSymUnion --} -- --%type decl_varname decl_defkey --%type decl_const decl_notnull --%type decl_defval decl_cursor_query --%type decl_datatype --%type decl_collate -- --%type expr_until_semi expr_until_paren stmt_until_semi --%type expr_until_then expr_until_loop opt_expr_until_when --%type opt_exitcond -- --%type for_variable --%type return_variable --%type <*tree.NumVal> foreach_slice --%type for_control -- --%type any_identifier opt_block_label opt_loop_label opt_label query_options --%type opt_error_level option_type -- --%type <[]plpgsqltree.Statement> proc_sect --%type <[]plpgsqltree.ElseIf> stmt_elsifs --%type <[]plpgsqltree.Statement> stmt_else loop_body // TODO is this a list of statement? --%type pl_block --%type proc_stmt --%type stmt_assign stmt_if stmt_loop stmt_while stmt_exit stmt_continue --%type stmt_return stmt_raise stmt_assert stmt_execsql --%type stmt_dynexecute stmt_for stmt_perform stmt_call stmt_getdiag --%type stmt_open stmt_fetch stmt_move stmt_close stmt_null --%type stmt_commit stmt_rollback --%type stmt_case stmt_foreach_a -- --%type decl_stmt decl_statement --%type <[]plpgsqltree.Statement> decl_sect opt_decl_stmts decl_stmts -- --%type <[]plpgsqltree.Exception> exception_sect proc_exceptions --%type <*plpgsqltree.Exception> proc_exception --%type <[]plpgsqltree.Condition> proc_conditions --%type <*plpgsqltree.Condition> proc_condition -- --%type <*plpgsqltree.CaseWhen> case_when --%type <[]*plpgsqltree.CaseWhen> case_when_list --%type <[]plpgsqltree.Statement> opt_case_else -- --%type getdiag_area_opt --%type getdiag_list // TODO don't know what this is --%type <*plpgsqltree.GetDiagnosticsItem> getdiag_list_item // TODO don't know what this is --%type getdiag_item -- --%type <*plpgsqltree.RaiseOption> option_expr --%type <[]plpgsqltree.RaiseOption> option_exprs opt_option_exprs --%type format_expr --%type <[]plpgsqltree.Expr> opt_format_exprs format_exprs -- --%type opt_scrollable -- --%type <*tree.NumVal> opt_transaction_chain -- --%type unreserved_keyword --%% -- --pl_function: -- pl_block opt_semi -- { -- plpgsqllex.(*lexer).SetStmt($1.statement()) -- } -- --opt_semi: --| ';' --; -- --pl_block: opt_block_label decl_sect BEGIN proc_sect exception_sect END opt_label -- { -- $$.val = &plpgsqltree.Block{ -- Label: $1, -- Decls: $2.statements(), -- Body: $4.statements(), -- Exceptions: $5.exceptions(), -- } -- } --; -- --decl_sect: DECLARE opt_decl_stmts -- { -- $$.val = $2.statements() -- } --| /* EMPTY */ -- { -- // Use a nil slice to indicate DECLARE was not used. -- $$.val = []plpgsqltree.Statement(nil) -- } --; -- --opt_decl_stmts: decl_stmts -- { -- $$.val = $1.statements() -- } --| /* EMPTY */ -- { -- $$.val = []plpgsqltree.Statement{} -- } --; -- --decl_stmts: decl_stmts decl_stmt -- { -- decs := $1.statements() -- dec := $2.statement() -- $$.val = append(decs, dec) -- } --| decl_stmt -- { -- dec := $1.statement() -- $$.val = []plpgsqltree.Statement{dec} -- } --; -- --decl_stmt : decl_statement -- { -- $$.val = $1.statement() -- } --| DECLARE -- { -- // This is to allow useless extra "DECLARE" keywords in the declare section. -- $$.val = (plpgsqltree.Statement)(nil) -- } --// TODO(chengxiong): turn this block on and throw useful error if user --// tries to put the block label just before BEGIN instead of before --// DECLARE. --//| LESS_LESS any_identifier GREATER_GREATER --// { --// } --; -- --decl_statement: decl_varname decl_const decl_datatype decl_collate decl_notnull decl_defval -- { -- $$.val = &plpgsqltree.Declaration{ -- Var: plpgsqltree.Variable($1), -- Constant: $2.bool(), -- Typ: $3.typ(), -- Collate: $4, -- NotNull: $5.bool(), -- Expr: $6.expr(), -- } -- } --| decl_varname ALIAS FOR decl_aliasitem ';' -- { -- return unimplemented(plpgsqllex, "alias for") -- } --| decl_varname opt_scrollable CURSOR decl_cursor_args decl_is_for decl_cursor_query -- { -- $$.val = &plpgsqltree.CursorDeclaration{ -- Name: plpgsqltree.Variable($1), -- Scroll: $2.cursorScrollOption(), -- Query: $6.sqlStatement(), -- } -- } --; -- --opt_scrollable: -- { -- $$.val = tree.UnspecifiedScroll -- } --| NO_SCROLL SCROLL -- { -- $$.val = tree.NoScroll -- } --| SCROLL -- { -- $$.val = tree.Scroll -- } --; -- --decl_cursor_query: stmt_until_semi ';' -- { -- stmts, err := parser.Parse($1) -- if err != nil { -- return setErr(plpgsqllex, err) -- } -- if len(stmts) != 1 { -- return setErr(plpgsqllex, errors.New("expected exactly one SQL statement for cursor")) -- } -- $$.val = stmts[0].AST -- } --; -- --decl_cursor_args: '(' -- { -- return unimplemented(plpgsqllex, "cursor arguments") -- } --| /* EMPTY */ -- { -- } --; -- --decl_cursor_arglist: decl_cursor_arg -- { -- } --| decl_cursor_arglist ',' decl_cursor_arg -- { -- } --; -- --decl_cursor_arg: decl_varname decl_datatype -- { -- } --; -- --decl_is_for: -- IS /* Oracle */ --| FOR /* SQL standard */ -- --decl_aliasitem: IDENT -- { -- } --| unreserved_keyword -- { -- } --; -- --decl_varname: IDENT --| unreserved_keyword --; -- --decl_const: -- { -- $$.val = false -- } --| CONSTANT -- { -- $$.val = true -- } --; -- --decl_datatype: -- { -- // Read until reaching one of the tokens that can follow a declaration -- // data type. -- sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr( -- ';', COLLATE, NOT, '=', COLON_EQUALS, DECLARE, -- ) -- if err != nil { -- return setErr(plpgsqllex, err) -- } -- typ, err := plpgsqllex.(*lexer).GetTypeFromValidSQLSyntax(sqlStr) -- if err != nil { -- return setErr(plpgsqllex, err) -- } -- $$.val = typ -- } --; -- --decl_collate: -- { -- $$ = "" -- } --| COLLATE IDENT -- { -- $$ = $2 -- } --| COLLATE unreserved_keyword -- { -- $$ = $2 -- } --; -- --decl_notnull: -- { -- $$.val = false -- } --| NOT NULL -- { -- $$.val = true -- } --; -- --decl_defval: ';' -- { -- $$.val = (plpgsqltree.Expr)(nil) -- } --| decl_defkey ';' -- { -- expr, err := plpgsqllex.(*lexer).ParseExpr($1) -- if err != nil { -- return setErr(plpgsqllex, err) -- } -- $$.val = expr -- } --; -- --decl_defkey: assign_operator -- { -- sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(';') -- if err != nil { -- return setErr(plpgsqllex, err) -- } -- $$ = sqlStr -- } --| DEFAULT -- { -- sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(';') -- if err != nil { -- return setErr(plpgsqllex, err) -- } -- $$ = sqlStr -- } --; -- --/* -- * Ada-based PL/SQL uses := for assignment and variable defaults, while -- * the SQL standard uses equals for these cases and for GET -- * DIAGNOSTICS, so we support both. FOR and OPEN only support :=. -- */ --assign_operator: '=' --| COLON_EQUALS --; -- --proc_sect: -- { -- $$.val = []plpgsqltree.Statement{} -- } --| proc_sect proc_stmt -- { -- stmts := $1.statements() -- stmts = append(stmts, $2.statement()) -- $$.val = stmts -- } --; -- --proc_stmt:pl_block ';' -- { -- $$.val = $1.block() -- } --| stmt_assign -- { -- $$.val = $1.statement() -- } --| stmt_if -- { -- $$.val = $1.statement() -- } --| stmt_case -- { -- $$.val = $1.statement() -- } --| stmt_loop -- { -- $$.val = $1.statement() -- } --| stmt_while -- { } --| stmt_for -- { } --| stmt_foreach_a -- { } --| stmt_exit -- { -- $$.val = $1.statement() -- } --| stmt_continue -- { -- $$.val = $1.statement() -- } --| stmt_return -- { -- $$.val = $1.statement() -- } --| stmt_raise -- { -- $$.val = $1.statement() -- } --| stmt_assert -- { -- $$.val = $1.statement() -- } --| stmt_execsql -- { -- $$.val = $1.statement() -- } --| stmt_dynexecute -- { -- $$.val = $1.statement() -- } --| stmt_perform -- { } --| stmt_call -- { -- $$.val = $1.statement() -- } --| stmt_getdiag -- { } --| stmt_open -- { -- $$.val = $1.statement() -- } --| stmt_fetch -- { -- $$.val = $1.statement() -- } --| stmt_move -- { -- $$.val = $1.statement() -- } --| stmt_close -- { -- $$.val = $1.statement() -- } --| stmt_null -- { } --| stmt_commit -- { } --| stmt_rollback -- { } --; -- --stmt_perform: PERFORM stmt_until_semi ';' -- { -- return unimplemented(plpgsqllex, "perform") -- } --; -- --stmt_call: CALL call_cmd ';' -- { -- $$.val = &plpgsqltree.Call{IsCall: true} -- } --| DO call_cmd ';' -- { -- $$.val = &plpgsqltree.Call{IsCall: false} -- } --; -- --call_cmd: -- { -- _, _, err := plpgsqllex.(*lexer).ReadSqlExpr(';') -- if err != nil { -- return setErr(plpgsqllex, err) -- } -- } --; -- --stmt_assign: IDENT assign_operator expr_until_semi ';' -- { -- expr, err := plpgsqllex.(*lexer).ParseExpr($3) -- if err != nil { -- return setErr(plpgsqllex, err) -- } -- $$.val = &plpgsqltree.Assignment{ -- Var: plpgsqltree.Variable($1), -- Value: expr, -- } -- } --; -- --stmt_getdiag: GET getdiag_area_opt DIAGNOSTICS getdiag_list ';' -- { -- $$.val = &plpgsqltree.GetDiagnostics{ -- IsStacked: $2.bool(), -- DiagItems: $4.getDiagnosticsItemList(), -- } -- // TODO(jane): Check information items are valid for area option. -- } --; -- --getdiag_area_opt: -- { -- $$.val = false -- } --| CURRENT -- { -- $$.val = false -- } --| STACKED -- { -- $$.val = true -- } --; -- --getdiag_list: getdiag_list ',' getdiag_list_item -- { -- $$.val = append($1.getDiagnosticsItemList(), $3.getDiagnosticsItem()) -- } --| getdiag_list_item -- { -- $$.val = plpgsqltree.GetDiagnosticsItemList{$1.getDiagnosticsItem()} -- } --; -- --getdiag_list_item: IDENT assign_operator getdiag_item -- { -- $$.val = &plpgsqltree.GetDiagnosticsItem{ -- Kind : $3.getDiagnosticsKind(), -- TargetName: $1, -- // TODO(jane): set the target from $1. -- } -- } --; -- --getdiag_item: unreserved_keyword { -- switch $1 { -- case "row_count": -- $$.val = plpgsqltree.GetDiagnosticsRowCount; -- case "pg_context": -- $$.val = plpgsqltree.GetDiagnosticsContext; -- case "pg_exception_detail": -- $$.val = plpgsqltree.GetDiagnosticsErrorDetail; -- case "pg_exception_hint": -- $$.val = plpgsqltree.GetDiagnosticsErrorHint; -- case "pg_exception_context": -- $$.val = plpgsqltree.GetDiagnosticsErrorContext; -- case "column_name": -- $$.val = plpgsqltree.GetDiagnosticsColumnName; -- case "constraint_name": -- $$.val = plpgsqltree.GetDiagnosticsConstraintName; -- case "pg_datatype_name": -- $$.val = plpgsqltree.GetDiagnosticsDatatypeName; -- case "message_text": -- $$.val = plpgsqltree.GetDiagnosticsMessageText; -- case "table_name": -- $$.val = plpgsqltree.GetDiagnosticsTableName; -- case "schema_name": -- $$.val = plpgsqltree.GetDiagnosticsSchemaName; -- case "returned_sqlstate": -- $$.val = plpgsqltree.GetDiagnosticsReturnedSQLState; -- default: -- // TODO(jane): Should this use an unimplemented error instead? -- return setErr(plpgsqllex, errors.Newf("unrecognized GET DIAGNOSTICS item: %s", redact.Safe($1))) -- } --} --; -- --getdiag_target: --// TODO(jane): remove ident. --IDENT -- { -- } --; -- --stmt_if: IF expr_until_then THEN proc_sect stmt_elsifs stmt_else END_IF IF ';' -- { -- cond, err := plpgsqllex.(*lexer).ParseExpr($2) -- if err != nil { -- return setErr(plpgsqllex, err) -- } -- $$.val = &plpgsqltree.If{ -- Condition: cond, -- ThenBody: $4.statements(), -- ElseIfList: $5.elseIf(), -- ElseBody: $6.statements(), -- } -- } --; -- --stmt_elsifs: -- { -- $$.val = []plpgsqltree.ElseIf{}; -- } --| stmt_elsifs ELSIF expr_until_then THEN proc_sect -- { -- cond, err := plpgsqllex.(*lexer).ParseExpr($3) -- if err != nil { -- return setErr(plpgsqllex, err) -- } -- newStmt := plpgsqltree.ElseIf{ -- Condition: cond, -- Stmts: $5.statements(), -- } -- $$.val = append($1.elseIf() , newStmt) -- } --; -- --stmt_else: -- { -- $$.val = []plpgsqltree.Statement{}; -- } --| ELSE proc_sect -- { -- $$.val = $2.statements(); -- } --; -- --stmt_case: CASE opt_expr_until_when case_when_list opt_case_else END_CASE CASE ';' -- { -- expr := &plpgsqltree.Case { -- TestExpr: $2, -- CaseWhenList: $3.caseWhens(), -- } -- if $4.val != nil { -- expr.HaveElse = true -- expr.ElseStmts = $4.statements() -- } -- $$.val = expr -- } --; -- --opt_expr_until_when: -- { -- if plpgsqllex.(*lexer).Peek().id != WHEN { -- sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(WHEN) -- if err != nil { -- return setErr(plpgsqllex, err) -- } -- $$ = sqlStr -- } else { -- $$ = "" -- } -- } --; -- --case_when_list: case_when_list case_when -- { -- stmts := $1.caseWhens() -- stmts = append(stmts, $2.caseWhen()) -- $$.val = stmts -- } --| case_when -- { -- stmts := []*plpgsqltree.CaseWhen{} -- stmts = append(stmts, $1.caseWhen()) -- $$.val = stmts -- } --; -- --case_when: WHEN expr_until_then THEN proc_sect -- { -- expr := &plpgsqltree.CaseWhen{ -- Expr: $2, -- Stmts: $4.statements(), -- } -- $$.val = expr -- } --; -- --opt_case_else: -- { -- $$.val = nil -- } --| ELSE proc_sect -- { -- $$.val = $2.statements() -- } --; -- --stmt_loop: opt_loop_label LOOP loop_body opt_label ';' -- { -- loopLabel, loopEndLabel := $1, $4 -- if err := checkLoopLabels(loopLabel, loopEndLabel); err != nil { -- return setErr(plpgsqllex, err) -- } -- $$.val = &plpgsqltree.Loop{ -- Label: $1, -- Body: $3.statements(), -- } -- } --; -- --stmt_while: opt_loop_label WHILE expr_until_loop LOOP loop_body opt_label ';' -- { -- loopLabel, loopEndLabel := $1, $6 -- if err := checkLoopLabels(loopLabel, loopEndLabel); err != nil { -- return setErr(plpgsqllex, err) -- } -- cond, err := plpgsqllex.(*lexer).ParseExpr($3) -- if err != nil { -- return setErr(plpgsqllex, err) -- } -- $$.val = &plpgsqltree.While{ -- Label: $1, -- Condition: cond, -- Body: $5.statements(), -- } -- } --; -- --stmt_for: opt_loop_label FOR for_control loop_body -- { -- return unimplemented(plpgsqllex, "for loop") -- } --; -- --for_control: for_variable IN -- // TODO need to parse the sql expression here. -- { -- return unimplemented(plpgsqllex, "for loop") -- } --; -- --/* -- * Processing the for_variable is tricky because we don't yet know if the -- * FOR is an integer FOR loop or a loop over query results. In the former -- * case, the variable is just a name that we must instantiate as a loop -- * local variable, regardless of any other definition it might have. -- * Therefore, we always save the actual identifier into $$.name where it -- * can be used for that case. We also save the outer-variable definition, -- * if any, because that's what we need for the loop-over-query case. Note -- * that we must NOT apply check_assignable() or any other semantic check -- * until we know what's what. -- * -- * However, if we see a comma-separated list of names, we know that it -- * can't be an integer FOR loop and so it's OK to check the variables -- * immediately. In particular, for T_WORD followed by comma, we should -- * complain that the name is not known rather than say it's a syntax error. -- * Note that the non-error result of this case sets *both* $$.scalar and -- * $$.row; see the for_control production. -- */ --for_variable: any_identifier -- { -- return unimplemented(plpgsqllex, "for loop") -- } --; -- --stmt_foreach_a: opt_loop_label FOREACH for_variable foreach_slice IN ARRAY expr_until_loop loop_body -- { -- return unimplemented(plpgsqllex, "for each loop") -- } --; -- --foreach_slice: -- { -- } --| SLICE ICONST -- { -- } --; -- --stmt_exit: EXIT opt_label opt_exitcond -- { -- $$.val = &plpgsqltree.Exit{ -- Label: $2, -- Condition: $3.expr(), -- } -- } --; -- --stmt_continue: CONTINUE opt_label opt_exitcond -- { -- $$.val = &plpgsqltree.Continue{ -- Label: $2, -- Condition: $3.expr(), -- } -- } --; -- -- // TODO handle variable names -- // 1. verify if the first token is a variable (this means that we need to track variable scope during parsing) -- // 2. if yes, check next token is ';' -- // 3. if no, expecting a sql expression "read_sql_expression" -- // we can just read until a ';', then do the sql expression validation during compile time. -- --stmt_return: RETURN return_variable ';' -- { -- $$.val = &plpgsqltree.Return{ -- Expr: $2.expr(), -- } -- } --| RETURN_NEXT NEXT -- { -- return unimplemented(plpgsqllex, "return next") -- } --| RETURN_QUERY QUERY -- { -- return unimplemented (plpgsqllex, "return query") -- } --; -- -- --query_options: -- { -- _, terminator, err := plpgsqllex.(*lexer).ReadSqlExpr(EXECUTE, ';') -- if err != nil { -- return setErr(plpgsqllex, err) -- } -- if terminator == EXECUTE { -- return unimplemented (plpgsqllex, "return dynamic sql query") -- } -- _, _, err = plpgsqllex.(*lexer).ReadSqlExpr(';') -- if err != nil { -- return setErr(plpgsqllex, err) -- } -- } --; -- -- --return_variable: expr_until_semi -- { -- expr, err := plpgsqllex.(*lexer).ParseExpr($1) -- if err != nil { -- return setErr(plpgsqllex, err) -- } -- $$.val = expr -- } --; -- --stmt_raise: -- RAISE ';' -- { -- return unimplemented(plpgsqllex, "empty RAISE statement") -- } --| RAISE opt_error_level SCONST opt_format_exprs opt_option_exprs ';' -- { -- $$.val = &plpgsqltree.Raise{ -- LogLevel: $2, -- Message: $3, -- Params: $4.exprs(), -- Options: $5.raiseOptions(), -- } -- } --| RAISE opt_error_level IDENT opt_option_exprs ';' -- { -- $$.val = &plpgsqltree.Raise{ -- LogLevel: $2, -- CodeName: $3, -- Options: $4.raiseOptions(), -- } -- } --| RAISE opt_error_level SQLSTATE SCONST opt_option_exprs ';' -- { -- $$.val = &plpgsqltree.Raise{ -- LogLevel: $2, -- Code: $4, -- Options: $5.raiseOptions(), -- } -- } --| RAISE opt_error_level USING option_exprs ';' -- { -- $$.val = &plpgsqltree.Raise{ -- LogLevel: $2, -- Options: $4.raiseOptions(), -- } -- } --; -- --opt_error_level: -- DEBUG --| LOG --| INFO --| NOTICE --| WARNING --| EXCEPTION --| /* EMPTY */ -- { -- $$ = "" -- } --; -- --opt_option_exprs: -- USING option_exprs -- { -- $$.val = $2.raiseOptions() -- } --| /* EMPTY */ -- { -- $$.val = []plpgsqltree.RaiseOption{} -- } --; -- --option_exprs: -- option_exprs ',' option_expr -- { -- option := $3.raiseOption() -- $$.val = append($1.raiseOptions(), *option) -- } --| option_expr -- { -- option := $1.raiseOption() -- $$.val = []plpgsqltree.RaiseOption{*option} -- } --; -- --option_expr: -- option_type assign_operator -- { -- // Read until reaching one of the tokens that can follow a raise option. -- sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(',', ';') -- if err != nil { -- return setErr(plpgsqllex, err) -- } -- optionExpr, err := plpgsqllex.(*lexer).ParseExpr(sqlStr) -- if err != nil { -- return setErr(plpgsqllex, err) -- } -- $$.val = &plpgsqltree.RaiseOption{ -- OptType: $1, -- Expr: optionExpr, -- } -- } --; -- --option_type: -- MESSAGE --| DETAIL --| HINT --| ERRCODE --| COLUMN --| CONSTRAINT --| DATATYPE --| TABLE --| SCHEMA --; -- --opt_format_exprs: -- format_exprs -- { -- $$.val = $1.exprs() -- } -- | /* EMPTY */ -- { -- $$.val = []plpgsqltree.Expr{} -- } --; -- --format_exprs: -- format_expr -- { -- $$.val = []plpgsqltree.Expr{$1.expr()} -- } --| format_exprs format_expr -- { -- $$.val = append($1.exprs(), $2.expr()) -- } --; -- --format_expr: ',' -- { -- // Read until reaching a token that can follow a raise format parameter. -- sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(',', ';', USING) -- if err != nil { -- return setErr(plpgsqllex, err) -- } -- param, err := plpgsqllex.(*lexer).ParseExpr(sqlStr) -- if err != nil { -- return setErr(plpgsqllex, err) -- } -- $$.val = param -- } --; -- --stmt_assert: ASSERT assert_cond ';' -- { -- $$.val = &plpgsqltree.Assert{} -- } --; -- --assert_cond: -- { -- _, terminator, err := plpgsqllex.(*lexer).ReadSqlExpr(',', ';') -- if err != nil { -- return setErr(plpgsqllex, err) -- } -- if terminator == ',' { -- _, _, err = plpgsqllex.(*lexer).ReadSqlExpr(';') -- if err != nil { -- return setErr(plpgsqllex, err) -- } -- } -- } --; -- --loop_body: proc_sect END LOOP -- { -- $$.val = $1.statements() -- } --; -- --stmt_execsql: stmt_execsql_start -- { -- stmt, err := plpgsqllex.(*lexer).MakeExecSqlStmt() -- if err != nil { -- return setErr(plpgsqllex, err) -- } -- $$.val = stmt -- } --; -- --stmt_execsql_start: -- IMPORT --| INSERT --| UPSERT --| MERGE --| IDENT --; -- --stmt_dynexecute: EXECUTE -- { -- stmt, err := plpgsqllex.(*lexer).MakeDynamicExecuteStmt() -- if err != nil { -- return setErr(plpgsqllex, err) -- } -- $$.val = stmt -- } --; -- --stmt_open: OPEN IDENT ';' -- { -- $$.val = &plpgsqltree.Open{CurVar: plpgsqltree.Variable($2)} -- } --| OPEN IDENT opt_scrollable FOR EXECUTE -- { -- return unimplemented(plpgsqllex, "cursor for execute") -- } --| OPEN IDENT opt_scrollable FOR stmt_until_semi ';' -- { -- stmts, err := parser.Parse($5) -- if err != nil { -- return setErr(plpgsqllex, err) -- } -- if len(stmts) != 1 { -- return setErr(plpgsqllex, errors.New("expected exactly one SQL statement for cursor")) -- } -- $$.val = &plpgsqltree.Open{ -- CurVar: plpgsqltree.Variable($2), -- Scroll: $3.cursorScrollOption(), -- Query: stmts[0].AST, -- } -- } --; -- --stmt_fetch: FETCH -- { -- fetch, err := plpgsqllex.(*lexer).MakeFetchOrMoveStmt(false) -- if err != nil { -- return setErr(plpgsqllex, err) -- } -- $$.val = fetch -- } --; -- --stmt_move: MOVE -- { -- move, err := plpgsqllex.(*lexer).MakeFetchOrMoveStmt(true) -- if err != nil { -- return setErr(plpgsqllex, err) -- } -- $$.val = move -- } --; -- --stmt_close: CLOSE IDENT ';' -- { -- $$.val = &plpgsqltree.Close{CurVar: plpgsqltree.Variable($2)} -- } --; -- --stmt_null: NULL ';' -- { -- $$.val = &plpgsqltree.Null{}; -- } --; -- --stmt_commit: COMMIT opt_transaction_chain ';' -- { -- return unimplemented(plpgsqllex, "commit") -- } --; -- --stmt_rollback: ROLLBACK opt_transaction_chain ';' -- { -- return unimplemented(plpgsqllex, "rollback") -- } --; -- --opt_transaction_chain: --AND CHAIN -- { } --| AND NO CHAIN -- { } --| /* EMPTY */ -- { } -- --exception_sect: /* EMPTY */ -- { -- $$.val = []plpgsqltree.Exception(nil) -- } --| EXCEPTION proc_exceptions -- { -- $$.val = $2.exceptions() -- } --; -- --proc_exceptions: proc_exceptions proc_exception -- { -- e := $2.exception() -- $$.val = append($1.exceptions(), *e) -- } --| proc_exception -- { -- e := $1.exception() -- $$.val = []plpgsqltree.Exception{*e} -- } --; -- --proc_exception: WHEN proc_conditions THEN proc_sect -- { -- $$.val = &plpgsqltree.Exception{ -- Conditions: $2.conditions(), -- Action: $4.statements(), -- } -- } --; -- --proc_conditions: proc_conditions OR proc_condition -- { -- c := $3.condition() -- $$.val = append($1.conditions(), *c) -- } --| proc_condition -- { -- c := $1.condition() -- $$.val = []plpgsqltree.Condition{*c} -- } --; -- --proc_condition: any_identifier -- { -- $$.val = &plpgsqltree.Condition{SqlErrName: $1} -- } --| SQLSTATE SCONST -- { -- $$.val = &plpgsqltree.Condition{SqlErrState: $2} -- } --; -- --expr_until_semi: -- { -- sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(';') -- if err != nil { -- return setErr(plpgsqllex, err) -- } -- $$ = sqlStr -- } --; -- --stmt_until_semi: -- { -- sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlStatement(';') -- if err != nil { -- return setErr(plpgsqllex, err) -- } -- $$ = sqlStr -- } --; -- --expr_until_then: -- { -- sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(THEN) -- if err != nil { -- return setErr(plpgsqllex, err) -- } -- $$ = sqlStr -- } --; -- --expr_until_loop: -- { -- sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(LOOP) -- if err != nil { -- return setErr(plpgsqllex, err) -- } -- $$ = sqlStr -- } --; -- --expr_until_paren : -- { -- sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(')') -- if err != nil { -- return setErr(plpgsqllex, err) -- } -- $$ = sqlStr -- } --; -- --opt_block_label : -- { -- $$ = "" -- } --| LESS_LESS any_identifier GREATER_GREATER -- { -- $$ = $2 -- } --; -- --opt_loop_label: -- { -- $$ = "" -- } --| LESS_LESS any_identifier GREATER_GREATER -- { -- $$ = $2 -- } --; -- --opt_label: -- { -- $$ = "" -- } --| any_identifier -- { -- $$ = $1 -- } --; -- --opt_exitcond: ';' -- { } --| WHEN expr_until_semi ';' -- { -- expr, err := plpgsqllex.(*lexer).ParseExpr($2) -- if err != nil { -- return setErr(plpgsqllex, err) -- } -- $$.val = expr -- } --; -- --/* -- * need to allow DATUM because scanner will have tried to resolve as variable -- */ --any_identifier: --IDENT --| unreserved_keyword --; -- --unreserved_keyword: -- ABSOLUTE --| ALIAS --| AND --| ARRAY --| ASSERT --| BACKWARD --| CALL --| CHAIN --| CLOSE --| COLLATE --| COLUMN --| COLUMN_NAME --| COMMIT --| CONSTANT --| CONSTRAINT --| CONSTRAINT_NAME --| CONTINUE --| CURRENT --| CURSOR --| DATATYPE --| DEBUG --| DEFAULT --| DETAIL --| DIAGNOSTICS --| DO --| DUMP --| ELSIF --| ERRCODE --| ERROR --| EXCEPTION --| EXIT --| FETCH --| FIRST --| FORWARD --| GET --| HINT --| IMPORT --| INFO --| INSERT --| IS --| LAST --| LOG --| MERGE --| MESSAGE --| MESSAGE_TEXT --| MOVE --| NEXT --| NO --| NO_SCROLL --| NOTICE --| OPEN --| OPTION --| PERFORM --| PG_CONTEXT --| PG_DATATYPE_NAME --| PG_EXCEPTION_CONTEXT --| PG_EXCEPTION_DETAIL --| PG_EXCEPTION_HINT --| PRINT_STRICT_PARAMS --| PRIOR --| QUERY --| RAISE --| RELATIVE --| RETURN --| RETURN_NEXT --| RETURN_QUERY --| RETURNED_SQLSTATE --| REVERSE --| ROLLBACK --| ROW_COUNT --| ROWTYPE --| SCHEMA --| SCHEMA_NAME --| SCROLL --| SLICE --| SQLSTATE --| STACKED --| TABLE --| TABLE_NAME --| TYPE --| UPSERT --| USE_COLUMN --| USE_VARIABLE --| VARIABLE_CONFLICT --| WARNING -- --reserved_keyword: -- ALL --| BEGIN --| BY --| CASE --| DECLARE --| ELSE --| END --| END_CASE --| END_IF --| EXECUTE --| FOR --| FOREACH --| FROM --| IF --| IN --| INTO --| LOOP --| NOT --| NULL --| OR --| STRICT --| THEN --| TO --| USING --| WHEN --| WHILE -- --%% -diff --git a/pkg/sql/scanner/plpgsql_scan.go b/pkg/sql/scanner/plpgsql_scan.go -deleted file mode 100644 -index 3dc5500..0000000 ---- a/pkg/sql/scanner/plpgsql_scan.go -+++ /dev/null -@@ -1,246 +0,0 @@ --// Copyright 2023 The Cockroach Authors. --// --// Use of this software is governed by the Business Source License --// included in the file licenses/BSL.txt. --// --// As of the Change Date specified in that file, in accordance with --// the Business Source License, use of this software will be governed --// by the Apache License, Version 2.0, included in the file --// licenses/APL.txt. -- --package scanner -- --import ( -- "fmt" -- "go/constant" -- "go/token" -- -- sqllex "github.com/cockroachdb/cockroachdb-parser/pkg/sql/lexbase" -- "github.com/cockroachdb/cockroachdb-parser/pkg/sql/plpgsql/parser/lexbase" --) -- --// PLpgSQLScanner is a scanner with a PLPGSQL specific scan function --type PLpgSQLScanner struct { -- Scanner --} -- --// Scan scans the next token and populates its information into lval. --// This scan function contains rules for plpgsql. --func (s *PLpgSQLScanner) Scan(lval ScanSymType) { -- ch, skipWhiteSpace := s.scanSetup(lval) -- -- if skipWhiteSpace { -- return -- } -- -- switch ch { -- case '$': -- if s.scanDollarQuotedString(lval) { -- lval.SetID(lexbase.SCONST) -- return -- } -- return -- -- case identQuote: -- // "[^"]" -- if s.scanString(lval, identQuote, false /* allowEscapes */, true /* requireUTF8 */) { -- lval.SetID(lexbase.IDENT) -- } -- return -- -- case singleQuote: -- // '[^']' -- if s.scanString(lval, ch, false /* allowEscapes */, true /* requireUTF8 */) { -- lval.SetID(lexbase.SCONST) -- } -- return -- -- case 'b': -- // Bytes? -- if s.peek() == singleQuote { -- // b'[^']' -- s.pos++ -- if s.scanString(lval, singleQuote, true /* allowEscapes */, false /* requireUTF8 */) { -- lval.SetID(lexbase.BCONST) -- } -- return -- } -- s.scanIdent(lval) -- return -- -- case '.': -- switch t := s.peek(); { -- case t == '.': // .. -- s.pos++ -- lval.SetID(lexbase.DOT_DOT) -- return -- case sqllex.IsDigit(t): -- s.scanNumber(lval, ch) -- return -- } -- return -- -- case '!': -- switch s.peek() { -- case '=': // != -- s.pos++ -- lval.SetID(lexbase.NOT_EQUALS) -- return -- } -- return -- -- case '<': -- switch s.peek() { -- case '<': // << -- s.pos++ -- lval.SetID(lexbase.LESS_LESS) -- return -- case '=': // <= -- s.pos++ -- lval.SetID(lexbase.LESS_EQUALS) -- return -- } -- return -- -- case '>': -- switch s.peek() { -- case '>': // >> -- s.pos++ -- lval.SetID(lexbase.GREATER_GREATER) -- return -- case '=': // >= -- s.pos++ -- lval.SetID(lexbase.GREATER_EQUALS) -- return -- } -- return -- -- case ':': -- switch s.peek() { -- case ':': -- s.pos++ -- lval.SetID(lexbase.TYPECAST) -- return -- case '=': -- s.pos++ -- lval.SetID(lexbase.COLON_EQUALS) -- return -- } -- return -- -- default: -- if sqllex.IsDigit(ch) { -- s.scanNumber(lval, ch) -- return -- } -- if sqllex.IsIdentStart(ch) { -- s.scanIdent(lval) -- return -- } -- } -- // Everything else is a single character token which we already initialized -- // lval for above. --} -- --func (s *PLpgSQLScanner) scanNumber(lval ScanSymType, ch int) { -- start := s.pos - 1 -- isHex := false -- hasDecimal := ch == '.' -- hasExponent := false -- -- for { -- ch := s.peek() -- if (isHex && sqllex.IsHexDigit(ch)) || sqllex.IsDigit(ch) { -- s.pos++ -- continue -- } -- if ch == 'x' || ch == 'X' { -- if isHex || s.in[start] != '0' || s.pos != start+1 { -- lval.SetID(lexbase.ERROR) -- lval.SetStr(errInvalidHexNumeric) -- return -- } -- s.pos++ -- isHex = true -- continue -- } -- if isHex { -- break -- } -- if ch == '.' { -- if hasDecimal || hasExponent { -- break -- } -- s.pos++ -- if s.peek() == '.' { -- // Found ".." while scanning a number: back up to the end of the -- // integer. -- s.pos-- -- break -- } -- hasDecimal = true -- continue -- } -- if ch == 'e' || ch == 'E' { -- if hasExponent { -- break -- } -- hasExponent = true -- s.pos++ -- ch = s.peek() -- if ch == '-' || ch == '+' { -- s.pos++ -- } -- ch = s.peek() -- if !sqllex.IsDigit(ch) { -- lval.SetID(lexbase.ERROR) -- lval.SetStr("invalid floating point literal") -- return -- } -- continue -- } -- break -- } -- -- lval.SetStr(s.in[start:s.pos]) -- if hasDecimal || hasExponent { -- lval.SetID(lexbase.FCONST) -- floatConst := constant.MakeFromLiteral(lval.Str(), token.FLOAT, 0) -- if floatConst.Kind() == constant.Unknown { -- lval.SetID(lexbase.ERROR) -- lval.SetStr(fmt.Sprintf("could not make constant float from literal %q", lval.Str())) -- return -- } -- lval.SetUnionVal(NewNumValFn(floatConst, lval.Str(), false /* negative */)) -- } else { -- if isHex && s.pos == start+2 { -- lval.SetID(lexbase.ERROR) -- lval.SetStr(errInvalidHexNumeric) -- return -- } -- -- // Strip off leading zeros from non-hex (decimal) literals so that -- // constant.MakeFromLiteral doesn't inappropriately interpret the -- // string as an octal literal. Note: we can't use strings.TrimLeft -- // here, because it will truncate '0' to ''. -- if !isHex { -- for len(lval.Str()) > 1 && lval.Str()[0] == '0' { -- lval.SetStr(lval.Str()[1:]) -- } -- } -- -- lval.SetID(lexbase.ICONST) -- intConst := constant.MakeFromLiteral(lval.Str(), token.INT, 0) -- if intConst.Kind() == constant.Unknown { -- lval.SetID(lexbase.ERROR) -- lval.SetStr(fmt.Sprintf("could not make constant int from literal %q", lval.Str())) -- return -- } -- lval.SetUnionVal(NewNumValFn(intConst, lval.Str(), false /* negative */)) -- } --} -- --func (s *PLpgSQLScanner) scanIdent(lval ScanSymType) { -- s.lowerCaseAndNormalizeIdent(lval) -- lval.SetID(lexbase.GetKeywordID(lval.Str())) --} --- -2.38.1 - diff --git a/pkg/build/bazel/bazel.go b/pkg/build/bazel/bazel.go index 2504468..5988dc0 100644 --- a/pkg/build/bazel/bazel.go +++ b/pkg/build/bazel/bazel.go @@ -1,15 +1,9 @@ // Copyright 2015 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. //go:build bazel -// +build bazel package bazel diff --git a/pkg/build/bazel/non_bazel.go b/pkg/build/bazel/non_bazel.go index 17833fb..91ac847 100644 --- a/pkg/build/bazel/non_bazel.go +++ b/pkg/build/bazel/non_bazel.go @@ -1,15 +1,9 @@ // Copyright 2015 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. //go:build !bazel -// +build !bazel package bazel diff --git a/pkg/build/bazel/util/tinystringer/main.go b/pkg/build/bazel/util/tinystringer/main.go index b0b260a..ec63f54 100644 --- a/pkg/build/bazel/util/tinystringer/main.go +++ b/pkg/build/bazel/util/tinystringer/main.go @@ -1,16 +1,12 @@ // Copyright 2023 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main import ( + "cmp" "errors" "flag" "fmt" @@ -19,7 +15,7 @@ import ( "go/token" "os" "path/filepath" - "sort" + "slices" "strconv" "strings" ) @@ -126,7 +122,12 @@ func (s tinyStringer) stringify() error { defer func() { _ = outputFile.Close() }() - fmt.Fprintf(outputFile, `// Code generated by "stringer"; DO NOT EDIT. + fmt.Fprintf(outputFile, `// Copyright 2023 The Cockroach Authors. +// +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. + +// Code generated by "stringer"; DO NOT EDIT. package %s @@ -221,8 +222,8 @@ var %s = []%s{ seen[nameToInt[constName]] = struct{}{} } } - sort.Slice(inLexicographicOrder, func(i, j int) bool { - return nameToPrinted[inLexicographicOrder[i]] < nameToPrinted[inLexicographicOrder[j]] + slices.SortFunc(inLexicographicOrder, func(a, b string) int { + return cmp.Compare(nameToPrinted[a], nameToPrinted[b]) }) seen = make(map[int]struct{}) for _, constName := range inLexicographicOrder { diff --git a/pkg/build/cgo_compiler.go b/pkg/build/cgo_compiler.go index 09bc565..2411e36 100644 --- a/pkg/build/cgo_compiler.go +++ b/pkg/build/cgo_compiler.go @@ -1,12 +1,7 @@ // Copyright 2015 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package build diff --git a/pkg/build/cgo_compiler_nocgo.go b/pkg/build/cgo_compiler_nocgo.go index a11bb78..2fe9f92 100644 --- a/pkg/build/cgo_compiler_nocgo.go +++ b/pkg/build/cgo_compiler_nocgo.go @@ -1,15 +1,9 @@ // Copyright 2018 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. //go:build !cgo -// +build !cgo package build diff --git a/pkg/build/info.go b/pkg/build/info.go index b1e7c5c..ec7ede1 100644 --- a/pkg/build/info.go +++ b/pkg/build/info.go @@ -1,12 +1,7 @@ // Copyright 2015 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package build @@ -21,31 +16,42 @@ import ( "github.com/cockroachdb/cockroachdb-parser/pkg/util/buildutil" "github.com/cockroachdb/cockroachdb-parser/pkg/util/envutil" - "github.com/cockroachdb/cockroachdb-parser/pkg/util/version" + "github.com/cockroachdb/redact" + "github.com/cockroachdb/version" ) // TimeFormat is the reference format for build.Time. Make sure it stays in sync // with the string passed to the linker in the root Makefile. const TimeFormat = "2006/01/02 15:04:05" +// These variables are initialized by Bazel via the linker -X flag +// when compiling release binaries. var ( - // These variables are initialized by Bazel via the linker -X flag - // when compiling release binaries. utcTime string // Build time in UTC (year/month/day hour:min:sec) rev string // SHA-1 of this build (git rev-parse) buildTagOverride string - cgoCompiler = cgoVersion() cgoTargetTriple string - platform = fmt.Sprintf("%s %s", runtime.GOOS, runtime.GOARCH) - // Distribution is changed by the CCL init-time hook in non-APL builds. - Distribution = "OSS" - typ string // Type of this build: , "development", or "release" - channel string + typ string // Type of this build: , "development", or "release" + channel string +) + +// Distribution is changed by the CCL init-time hook in non-APL builds. +var Distribution = "OSS" + +var ( + cgoCompiler = cgoVersion() + platform = fmt.Sprintf("%s %s", runtime.GOOS, runtime.GOARCH) envChannel = envutil.EnvOrDefaultString("COCKROACH_CHANNEL", "unknown") enabledAssertions = buildutil.CrdbTestBuild +) + +var ( //go:embed version.txt - cockroachVersion string - binaryVersion = computeBinaryVersion(cockroachVersion, rev) + versionTxt string + parsedVersionTxt *version.Version = parseCockroachVersion(versionTxt) + binaryVersion string = computeBinaryVersion(buildTagOverride, parsedVersionTxt, rev) + // binaryVersionTestingOverride is modified by TestingOverrideVersion. + binaryVersionTestingOverride string ) const ( @@ -64,36 +70,63 @@ func SeemsOfficial() bool { return channel == DefaultTelemetryChannel || channel == FIPSTelemetryChannel } -func computeBinaryVersion(versionTxt, revision string) string { - if buildTagOverride != "" { - return buildTagOverride - } +func parseCockroachVersion(versionTxt string) *version.Version { txt := strings.TrimSuffix(versionTxt, "\n") v, err := version.Parse(txt) if err != nil { panic(fmt.Errorf("could not parse version.txt: %w", err)) } + return &v +} + +func computeBinaryVersion( + buildTagOverride string, parsedVersionTxt *version.Version, revision string, +) string { + if buildTagOverride != "" { + return buildTagOverride + } if IsRelease() { - return v.String() + return parsedVersionTxt.String() } if revision != "" { - return fmt.Sprintf("%s-dev-%s", v.String(), revision) + return fmt.Sprintf("%s-dev-%s", parsedVersionTxt.String(), revision) } - return fmt.Sprintf("%s-dev", v.String()) + return fmt.Sprintf("%s-dev", parsedVersionTxt.String()) } -// BinaryVersion returns the version prefix, patch number and metadata of the current build. +// BinaryVersion returns the version prefix, patch number and metadata of the +// current build. func BinaryVersion() string { + if binaryVersionTestingOverride != "" { + return binaryVersionTestingOverride + } return binaryVersion } -// BinaryVersionPrefix returns the version prefix of the current build. -func BinaryVersionPrefix() string { - v, err := version.Parse(binaryVersion) - if err != nil { +// VersionForURLs is used to determine the version to use in public-facing doc URLs. +// It returns "vX.Y" for all release versions, and all prerelease versions >= "alpha.1". +// X and Y are the major and minor, respectively, of the version specified in version.txt. +// For all other prerelease versions, it returns "dev". +// N.B. new public-facing doc URLs are expected to be up beginning with the "alpha.1" prerelease. Otherwise, "dev" will +// cause the url mapper to redirect to the latest stable release. +func VersionForURLs() string { + if parsedVersionTxt.IsPrerelease() { + phaseAndOrdinal := parsedVersionTxt.Format("%P.%o") + // builds prior to "alpha.1" use 'dev' in their URLs + if phaseAndOrdinal < "alpha.1" { + return "dev" + } + } else if parsedVersionTxt.IsCustomOrNightlyBuild() { return "dev" } - return fmt.Sprintf("v%d.%d", v.Major(), v.Minor()) + return parsedVersionTxt.Major().String() +} + +// BranchReleaseSeries returns tha major and minor in version.txt, without +// allowing for any overrides. +func BranchReleaseSeries() (year, ordinal int) { + major := parsedVersionTxt.Major() + return major.Year, major.Ordinal } func init() { @@ -105,13 +138,18 @@ func init() { } // Short returns a pretty printed build and version summary. -func (b Info) Short() string { +func (b Info) Short() redact.RedactableString { plat := b.Platform if b.CgoTargetTriple != "" { plat = b.CgoTargetTriple } - return fmt.Sprintf("CockroachDB %s %s (%s, built %s, %s)", - b.Distribution, b.Tag, plat, b.Time, b.GoVersion) + return redact.Sprintf("CockroachDB %s %s (%s, built %s, %s)", + redact.SafeString(b.Distribution), + redact.SafeString(b.Tag), + redact.SafeString(plat), + redact.SafeString(b.Time), + redact.SafeString(b.GoVersion), + ) } // Long returns a pretty printed build summary @@ -161,7 +199,7 @@ func GetInfo() Info { } return Info{ GoVersion: runtime.Version(), - Tag: binaryVersion, + Tag: BinaryVersion(), Time: utcTime, Revision: rev, CgoCompiler: cgoCompiler, @@ -178,12 +216,17 @@ func GetInfo() Info { // TestingOverrideVersion allows tests to override the binary version // reported by cockroach. func TestingOverrideVersion(v string) func() { - prevBinaryVersion := binaryVersion - binaryVersion = v - return func() { binaryVersion = prevBinaryVersion } + prevOverride := binaryVersionTestingOverride + binaryVersionTestingOverride = v + return func() { binaryVersionTestingOverride = prevOverride } } // MakeIssueURL produces a URL to a CockroachDB issue. func MakeIssueURL(issue int) string { - return fmt.Sprintf("https://go.crdb.dev/issue-v/%d/%s", issue, BinaryVersionPrefix()) + return fmt.Sprintf("https://go.crdb.dev/issue-v/%d/%s", issue, VersionForURLs()) +} + +// ParsedVersion returns the parsed version.txt. +func ParsedVersion() *version.Version { + return parsedVersionTxt } diff --git a/pkg/build/info.pb.go b/pkg/build/info.pb.go index fe5e53d..79a0de2 100644 --- a/pkg/build/info.pb.go +++ b/pkg/build/info.pb.go @@ -270,7 +270,7 @@ func (m *Info) Size() (n int) { } func sovInfo(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 + return int((uint32(math_bits.Len64(x|1)+6) * 37) >> 8) } func sozInfo(x uint64) (n int) { return sovInfo(uint64((x << 1) ^ uint64((int64(x) >> 63)))) diff --git a/pkg/build/info.proto b/pkg/build/info.proto index 8e3e18a..8a2e988 100644 --- a/pkg/build/info.proto +++ b/pkg/build/info.proto @@ -1,12 +1,7 @@ // Copyright 2016 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. syntax = "proto2"; package cockroach.build; diff --git a/pkg/build/version.txt b/pkg/build/version.txt index ae39fab..4367f90 100644 --- a/pkg/build/version.txt +++ b/pkg/build/version.txt @@ -1 +1 @@ -v0.0.0 +v1.2.3 diff --git a/pkg/cli/exit/codes.go b/pkg/cli/exit/codes.go index 0fd9368..6734aab 100644 --- a/pkg/cli/exit/codes.go +++ b/pkg/cli/exit/codes.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package exit diff --git a/pkg/cli/exit/doc.go b/pkg/cli/exit/doc.go index c76a112..b9f072f 100644 --- a/pkg/cli/exit/doc.go +++ b/pkg/cli/exit/doc.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. // Package exit encapsulates calls to os.Exit to control the // production of process exit status codes. diff --git a/pkg/cli/exit/exit.go b/pkg/cli/exit/exit.go index bc2ad11..d2252e9 100644 --- a/pkg/cli/exit/exit.go +++ b/pkg/cli/exit/exit.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package exit diff --git a/pkg/col/coldata/batch.go b/pkg/col/coldata/batch.go index 03e0b4a..9ad01cc 100644 --- a/pkg/col/coldata/batch.go +++ b/pkg/col/coldata/batch.go @@ -1,12 +1,7 @@ // Copyright 2018 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package coldata @@ -16,8 +11,9 @@ import ( "strings" "sync/atomic" + "github.com/cockroachdb/cockroachdb-parser/pkg/col/typeconv" "github.com/cockroachdb/cockroachdb-parser/pkg/sql/types" - "github.com/cockroachdb/cockroachdb-parser/pkg/util" + "github.com/cockroachdb/cockroachdb-parser/pkg/util/metamorphic" "github.com/cockroachdb/errors" ) @@ -40,23 +36,24 @@ type Batch interface { // Width returns the number of columns in the batch. Width() int // ColVec returns the ith Vec in this batch. - ColVec(i int) Vec + ColVec(i int) *Vec // ColVecs returns all of the underlying Vecs in this batch. - ColVecs() []Vec - // Selection, if not nil, returns the selection vector on this batch: a + ColVecs() []*Vec + // Selection - if not nil - returns the selection vector on this batch: a // densely-packed list of the *increasing* indices in each column that have // not been filtered out by a previous step. // TODO(yuzefovich): consider ensuring that the length of the returned slice // equals the length of the batch. + // TODO(yuzefovich): consider using []int16 to reduce memory footprint. Selection() []int // SetSelection sets whether this batch is using its selection vector or not. SetSelection(bool) // AppendCol appends the given Vec to this batch. - AppendCol(Vec) + AppendCol(*Vec) // ReplaceCol replaces the current Vec at the provided index with the // provided Vec. The original and the replacement vectors *must* be of the // same type. - ReplaceCol(Vec, int) + ReplaceCol(*Vec, int) // Reset modifies the caller in-place to have the given length and columns // with the given types. If it's possible, Reset will reuse the existing // columns and allocations, invalidating existing references to the Batch or @@ -86,7 +83,7 @@ const DefaultColdataBatchSize = 1024 // confirmed to be very good using tpchvec/bench benchmark on TPC-H queries // (the best number according to that benchmark was 1280, but it was negligibly // better, so we decided to keep 1024 as it is a power of 2). -var defaultBatchSize = int64(util.ConstantWithMetamorphicTestRange( +var defaultBatchSize = int64(metamorphic.ConstantWithTestRange( "coldata-batch-size", DefaultColdataBatchSize, /* defaultValue */ // min is set to 3 to match colexec's minBatchSize setting. @@ -120,29 +117,173 @@ func NewMemBatch(typs []*types.T, factory ColumnFactory) Batch { return NewMemBatchWithCapacity(typs, BatchSize(), factory) } +const ( + boolAllocIdx int = iota + bytesAllocIdx + int16AllocIdx + int32AllocIdx + int64AllocIdx + float64AllocIdx + decimalAllocIdx + timeAllocIdx + intervalAllocIdx + jsonAllocIdx + datumAllocIdx + numCanonicalTypes +) + +//gcassert:inline +func toAllocIdx(canonicalTypeFamily types.Family, width int32) int { + switch canonicalTypeFamily { + case types.BoolFamily: + return boolAllocIdx + case types.BytesFamily: + return bytesAllocIdx + case types.IntFamily: + switch width { + case 16: + return int16AllocIdx + case 32: + return int32AllocIdx + case 0, 64: + return int64AllocIdx + default: + return -1 + } + case types.FloatFamily: + return float64AllocIdx + case types.DecimalFamily: + return decimalAllocIdx + case types.TimestampTZFamily: + return timeAllocIdx + case types.IntervalFamily: + return intervalAllocIdx + case types.JsonFamily: + return jsonAllocIdx + case typeconv.DatumVecCanonicalTypeFamily: + return datumAllocIdx + default: + // Return negative number which will cause index out of bounds error if + // a new natively-supported type is added and this switch is not + // updated. + return -1 + } +} + +var ( + unexpectedAllocIdxErr = errors.New("unexpected allocIdx") + datumBackedType = types.TSQuery +) + +func init() { + if typeconv.TypeFamilyToCanonicalTypeFamily(datumBackedType.Family()) != typeconv.DatumVecCanonicalTypeFamily { + panic("update datumBackedType to be actually datum-backed") + } +} + +//gcassert:inline +func toCanonicalType(allocIdx int) *types.T { + switch allocIdx { + case boolAllocIdx: + return types.Bool + case bytesAllocIdx: + return types.Bytes + case int16AllocIdx: + return types.Int2 + case int32AllocIdx: + return types.Int4 + case int64AllocIdx: + return types.Int + case float64AllocIdx: + return types.Float + case decimalAllocIdx: + return types.Decimal + case timeAllocIdx: + return types.TimestampTZ + case intervalAllocIdx: + return types.Interval + case jsonAllocIdx: + return types.Json + case datumAllocIdx: + return datumBackedType + default: + panic(unexpectedAllocIdxErr) + } +} + // NewMemBatchWithCapacity allocates a new in-memory Batch with the given // column size. Use for operators that have a precisely-sized output batch. func NewMemBatchWithCapacity(typs []*types.T, capacity int, factory ColumnFactory) Batch { b := NewMemBatchNoCols(typs, capacity).(*MemBatch) - cols := make([]memColumn, len(typs)) + vecs := make([]Vec, len(typs)) + // numForCanonicalType will track how many times a particular canonical type + // family appears in typs. + // + //gcassert:noescape + var numForCanonicalType [numCanonicalTypes]int for i, t := range typs { - col := &cols[i] - col.init(t, capacity, factory) - b.b[i] = col + vecs[i].t = t + vecs[i].canonicalTypeFamily = typeconv.TypeFamilyToCanonicalTypeFamily(t.Family()) + b.b[i] = &vecs[i] + allocIdx := toAllocIdx(vecs[i].canonicalTypeFamily, vecs[i].t.Width()) + numForCanonicalType[allocIdx]++ + } + var maxSame int + for _, numColumns := range numForCanonicalType { + maxSame = max(maxSame, numColumns) + } + // First, initialize columns that can be batch-allocated together for the + // same canonical type. + if maxSame > 1 { + scratchColumns := make([]Column, maxSame) + for allocIdx, numColumns := range numForCanonicalType { + if numColumns > 1 { + scratch := scratchColumns[:numColumns] + t := toCanonicalType(allocIdx) + factory.MakeColumns(scratch, t, capacity) + for i := range vecs { + if toAllocIdx(vecs[i].canonicalTypeFamily, vecs[i].t.Width()) == allocIdx { + vecs[i].col = scratch[0] + scratch = scratch[1:] + } + } + } + } + if numForCanonicalType[datumAllocIdx] > 1 { + // We need to set the correct type on each datum-backed vector. + for i := range vecs { + if vecs[i].canonicalTypeFamily == typeconv.DatumVecCanonicalTypeFamily { + vecs[i].Datum().SetType(vecs[i].t) + } + } + } + } + // Initialize all remaining columns while also initializing all Nulls + // bitmaps. + nullsCap := nullsStorageCap(capacity) + nullsAlloc := make([]byte, len(typs)*nullsCap) + for i := range vecs { + if vecs[i].col == nil { + vecs[i].col = factory.MakeColumn(vecs[i].t, capacity) + } + vecs[i].nulls = newNulls(nullsAlloc[:nullsCap:nullsCap]) + nullsAlloc = nullsAlloc[nullsCap:] } return b } +var batchCapacityTooLargeErr = errors.New("batches cannot have capacity larger than max uint16") + // NewMemBatchNoCols creates a "skeleton" of new in-memory Batch. It allocates // memory for the selection vector but does *not* allocate any memory for the // column vectors - those will have to be added separately. func NewMemBatchNoCols(typs []*types.T, capacity int) Batch { - if max := math.MaxUint16; capacity > max { - panic(fmt.Sprintf(`batches cannot have capacity larger than %d; requested %d`, max, capacity)) + if capacity > math.MaxUint16 { + panic(batchCapacityTooLargeErr) } b := &MemBatch{} b.capacity = capacity - b.b = make([]Vec, len(typs)) + b.b = make([]*Vec, len(typs)) b.sel = make([]int, capacity) return b } @@ -178,11 +319,11 @@ func (b *zeroBatch) SetSelection(bool) { panic("selection should not be changed on zero batch") } -func (b *zeroBatch) AppendCol(Vec) { +func (b *zeroBatch) AppendCol(*Vec) { panic("no columns should be appended to zero batch") } -func (b *zeroBatch) ReplaceCol(Vec, int) { +func (b *zeroBatch) ReplaceCol(*Vec, int) { panic("no columns should be replaced in zero batch") } @@ -198,7 +339,7 @@ type MemBatch struct { // MemBatch. capacity int // b is the slice of columns in this batch. - b []Vec + b []*Vec useSel bool // sel is - if useSel is true - a selection vector from upstream. A // selection vector is a list of selected tuple indices in this memBatch's @@ -223,12 +364,12 @@ func (m *MemBatch) Width() int { } // ColVec implements the Batch interface. -func (m *MemBatch) ColVec(i int) Vec { +func (m *MemBatch) ColVec(i int) *Vec { return m.b[i] } // ColVecs implements the Batch interface. -func (m *MemBatch) ColVecs() []Vec { +func (m *MemBatch) ColVecs() []*Vec { return m.b } @@ -251,13 +392,13 @@ func (m *MemBatch) SetLength(length int) { } // AppendCol implements the Batch interface. -func (m *MemBatch) AppendCol(col Vec) { +func (m *MemBatch) AppendCol(col *Vec) { m.b = append(m.b, col) } // ReplaceCol implements the Batch interface. -func (m *MemBatch) ReplaceCol(col Vec, colIdx int) { - if m.b[colIdx] != nil && !m.b[colIdx].Type().Identical(col.Type()) { +func (m *MemBatch) ReplaceCol(col *Vec, colIdx int) { + if m.b[colIdx] != nil && m.b[colIdx].t != nil && !m.b[colIdx].Type().Identical(col.Type()) { panic(fmt.Sprintf("unexpected replacement: original vector is %s "+ "whereas the replacement is %s", m.b[colIdx].Type(), col.Type())) } @@ -272,7 +413,7 @@ func (m *MemBatch) Reset(typs []*types.T, length int, factory ColumnFactory) { // TODO(yuzefovich): requiring that types are "identical" might be an // overkill - the vectors could have the same physical representation // but non-identical types. Think through this more. - if !m.ColVec(i).Type().Identical(typs[i]) { + if v := m.ColVec(i); !v.Type().Identical(typs[i]) { cannotReuse = true break } @@ -324,7 +465,7 @@ func (m *MemBatch) String() string { // // The implementation lives in colconv package and is injected during the // initialization. -var VecsToStringWithRowPrefix func(vecs []Vec, length int, sel []int, prefix string) []string +var VecsToStringWithRowPrefix func(vecs []*Vec, length int, sel []int, prefix string) []string // GetBatchMemSize returns the total memory footprint of the batch. // diff --git a/pkg/col/coldata/bytes.go b/pkg/col/coldata/bytes.go index 03a5cb3..a67854a 100644 --- a/pkg/col/coldata/bytes.go +++ b/pkg/col/coldata/bytes.go @@ -1,12 +1,7 @@ // Copyright 2019 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package coldata @@ -276,7 +271,8 @@ func (b *Bytes) copyElements(srcElementsToCopy []element, src *Bytes, destIdx in // append the new value to b.buffer. *e = element{} //gcassert:bce - e.setNonInlined(srcElementsToCopy[i].getNonInlined(src), b) + srcElement := srcElementsToCopy[i] + e.setNonInlined(srcElement.getNonInlined(src), b) } } } @@ -645,7 +641,7 @@ func (b *Bytes) Deserialize(data []byte, offsets []int32) { // ProportionalSize calls the method of the same name on bytes-like vectors, // panicking if not bytes-like. -func ProportionalSize(v Vec, length int64) int64 { +func ProportionalSize(v *Vec, length int64) int64 { family := v.CanonicalTypeFamily() switch family { case types.BytesFamily: @@ -659,7 +655,7 @@ func ProportionalSize(v Vec, length int64) int64 { } // ResetIfBytesLike calls Reset on v if it is bytes-like, noop otherwise. -func ResetIfBytesLike(v Vec) { +func ResetIfBytesLike(v *Vec) { switch v.CanonicalTypeFamily() { case types.BytesFamily: v.Bytes().Reset() diff --git a/pkg/col/coldata/datum_vec.go b/pkg/col/coldata/datum_vec.go index 6ca9ea5..cc02b8a 100644 --- a/pkg/col/coldata/datum_vec.go +++ b/pkg/col/coldata/datum_vec.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package coldata @@ -57,4 +52,6 @@ type DatumVec interface { Size(startIdx int) int64 // SetEvalCtx updates the vector with the provided *eval.Context. SetEvalCtx(evalCtx interface{}) + // SetType updates the vector with its type. + SetType(t interface{}) } diff --git a/pkg/col/coldata/json.go b/pkg/col/coldata/json.go index 54263ff..4cdd855 100644 --- a/pkg/col/coldata/json.go +++ b/pkg/col/coldata/json.go @@ -1,12 +1,7 @@ // Copyright 2021 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package coldata diff --git a/pkg/col/coldata/native_types.go b/pkg/col/coldata/native_types.go index 4bac49c..e61bc34 100644 --- a/pkg/col/coldata/native_types.go +++ b/pkg/col/coldata/native_types.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package coldata @@ -215,7 +210,7 @@ func (c Float64s) CopySlice(src Float64s, destIdx, srcStartIdx, srcEndIdx int) { // destIdx. // // Note that this method is usually inlined, but it isn't in case of the -// memColumn.Copy generated code (probably because of the size of that +// Vec.Copy generated code (probably because of the size of that // function), so we don't assert the inlining with the GCAssert linter. func (c Decimals) CopySlice(src Decimals, destIdx, srcStartIdx, srcEndIdx int) { srcSlice := src[srcStartIdx:srcEndIdx] diff --git a/pkg/col/coldata/nulls.go b/pkg/col/coldata/nulls.go index 417bd7b..061a1b3 100644 --- a/pkg/col/coldata/nulls.go +++ b/pkg/col/coldata/nulls.go @@ -1,12 +1,7 @@ // Copyright 2018 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package coldata @@ -47,16 +42,25 @@ type Nulls struct { // NewNulls returns a new nulls vector, initialized with a length. func NewNulls(len int) Nulls { - if len > 0 { - n := Nulls{ - nulls: make([]byte, (len-1)/8+1), - } - n.UnsetNulls() - return n - } - return Nulls{ - nulls: make([]byte, 0), + return newNulls(make([]byte, nullsStorageCap(len))) +} + +//gcassert:inline +func newNulls(nulls []byte) Nulls { + n := Nulls{nulls: nulls} + n.UnsetNulls() + return n +} + +// nullsStorageCap returns the length of the byte slice that is needed to +// maintain the Nulls bitmap for n elements. +// +//gcassert:inline +func nullsStorageCap(n int) int { + if n <= 0 { + return 0 } + return (n-1)/8 + 1 } // MaybeHasNulls returns true if the column possibly has any null values, and diff --git a/pkg/col/coldata/testutils.go b/pkg/col/coldata/testutils.go index 595a66f..f0e8143 100644 --- a/pkg/col/coldata/testutils.go +++ b/pkg/col/coldata/testutils.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package coldata @@ -65,9 +60,6 @@ func AssertEquivalentBatches(t testingT, expected, actual Batch) { expectedNulls := expectedVec.Nulls() actualNulls := actualVec.Nulls() oldExpMaybeHasNulls, oldActMaybeHasNulls := expectedNulls.maybeHasNulls, actualNulls.maybeHasNulls - defer func() { - expectedNulls.maybeHasNulls, actualNulls.maybeHasNulls = oldExpMaybeHasNulls, oldActMaybeHasNulls - }() expectedNulls.maybeHasNulls = expectedNulls.maybeHasNulls || actualNulls.maybeHasNulls actualNulls.maybeHasNulls = expectedNulls.maybeHasNulls || actualNulls.maybeHasNulls require.Equal(t, expectedNulls.Slice(0, expected.Length()), actualNulls.Slice(0, actual.Length())) @@ -152,5 +144,6 @@ func AssertEquivalentBatches(t testingT, expected, actual Batch) { actualVec.Window(0, actual.Length()), ) } + expectedNulls.maybeHasNulls, actualNulls.maybeHasNulls = oldExpMaybeHasNulls, oldActMaybeHasNulls } } diff --git a/pkg/col/coldata/vec.eg.go b/pkg/col/coldata/vec.eg.go index 478160d..d25095f 100644 --- a/pkg/col/coldata/vec.eg.go +++ b/pkg/col/coldata/vec.eg.go @@ -1,13 +1,8 @@ // Code generated by execgen; DO NOT EDIT. // Copyright 2018 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package coldata @@ -41,7 +36,7 @@ var ( // they are working with can then access the typed column directly, avoiding // expensive type casts. type TypedVecs struct { - Vecs []Vec + Vecs []*Vec Nulls []*Nulls // Fields below need to be accessed by an index mapped via ColsMap. @@ -212,14 +207,22 @@ func (v *TypedVecs) Reset() { } } -func (m *memColumn) Append(args SliceArgs) { - switch m.CanonicalTypeFamily() { +// Append uses SliceArgs to append elements of a source Vec into this Vec. +// It is logically equivalent to: +// destVec = append(destVec[:args.DestIdx], args.Src[args.SrcStartIdx:args.SrcEndIdx]) +// An optional Sel slice can also be provided to apply a filter on the source +// Vec. +// Refer to the SliceArgs comment for specifics and TestAppend for examples. +// +// Note: Append()'ing from a Vector into itself is not supported. +func (v *Vec) Append(args SliceArgs) { + switch v.CanonicalTypeFamily() { case types.BoolFamily: - switch m.t.Width() { + switch v.t.Width() { case -1: default: fromCol := args.Src.Bool() - toCol := m.Bool() + toCol := v.Bool() // NOTE: it is unfortunate that we always append whole slice without paying // attention to whether the values are NULL. However, if we do start paying // attention, the performance suffers dramatically, so we choose to copy @@ -234,15 +237,15 @@ func (m *memColumn) Append(args SliceArgs) { toCol = append(toCol, val) } } - m.nulls.set(args) - m.col = toCol + v.nulls.set(args) + v.col = toCol } case types.BytesFamily: - switch m.t.Width() { + switch v.t.Width() { case -1: default: fromCol := args.Src.Bytes() - toCol := m.Bytes() + toCol := v.Bytes() // NOTE: it is unfortunate that we always append whole slice without paying // attention to whether the values are NULL. However, if we do start paying // attention, the performance suffers dramatically, so we choose to copy @@ -253,15 +256,15 @@ func (m *memColumn) Append(args SliceArgs) { sel := args.Sel[args.SrcStartIdx:args.SrcEndIdx] toCol.appendSliceWithSel(fromCol, args.DestIdx, sel) } - m.nulls.set(args) - m.col = toCol + v.nulls.set(args) + v.col = toCol } case types.DecimalFamily: - switch m.t.Width() { + switch v.t.Width() { case -1: default: fromCol := args.Src.Decimal() - toCol := m.Decimal() + toCol := v.Decimal() // NOTE: it is unfortunate that we always append whole slice without paying // attention to whether the values are NULL. However, if we do start paying // attention, the performance suffers dramatically, so we choose to copy @@ -298,14 +301,14 @@ func (m *memColumn) Append(args SliceArgs) { toCol[len(toCol)-1].Set(&val) } } - m.nulls.set(args) - m.col = toCol + v.nulls.set(args) + v.col = toCol } case types.IntFamily: - switch m.t.Width() { + switch v.t.Width() { case 16: fromCol := args.Src.Int16() - toCol := m.Int16() + toCol := v.Int16() // NOTE: it is unfortunate that we always append whole slice without paying // attention to whether the values are NULL. However, if we do start paying // attention, the performance suffers dramatically, so we choose to copy @@ -320,11 +323,11 @@ func (m *memColumn) Append(args SliceArgs) { toCol = append(toCol, val) } } - m.nulls.set(args) - m.col = toCol + v.nulls.set(args) + v.col = toCol case 32: fromCol := args.Src.Int32() - toCol := m.Int32() + toCol := v.Int32() // NOTE: it is unfortunate that we always append whole slice without paying // attention to whether the values are NULL. However, if we do start paying // attention, the performance suffers dramatically, so we choose to copy @@ -339,12 +342,12 @@ func (m *memColumn) Append(args SliceArgs) { toCol = append(toCol, val) } } - m.nulls.set(args) - m.col = toCol + v.nulls.set(args) + v.col = toCol case -1: default: fromCol := args.Src.Int64() - toCol := m.Int64() + toCol := v.Int64() // NOTE: it is unfortunate that we always append whole slice without paying // attention to whether the values are NULL. However, if we do start paying // attention, the performance suffers dramatically, so we choose to copy @@ -359,15 +362,15 @@ func (m *memColumn) Append(args SliceArgs) { toCol = append(toCol, val) } } - m.nulls.set(args) - m.col = toCol + v.nulls.set(args) + v.col = toCol } case types.FloatFamily: - switch m.t.Width() { + switch v.t.Width() { case -1: default: fromCol := args.Src.Float64() - toCol := m.Float64() + toCol := v.Float64() // NOTE: it is unfortunate that we always append whole slice without paying // attention to whether the values are NULL. However, if we do start paying // attention, the performance suffers dramatically, so we choose to copy @@ -382,15 +385,15 @@ func (m *memColumn) Append(args SliceArgs) { toCol = append(toCol, val) } } - m.nulls.set(args) - m.col = toCol + v.nulls.set(args) + v.col = toCol } case types.TimestampTZFamily: - switch m.t.Width() { + switch v.t.Width() { case -1: default: fromCol := args.Src.Timestamp() - toCol := m.Timestamp() + toCol := v.Timestamp() // NOTE: it is unfortunate that we always append whole slice without paying // attention to whether the values are NULL. However, if we do start paying // attention, the performance suffers dramatically, so we choose to copy @@ -405,15 +408,15 @@ func (m *memColumn) Append(args SliceArgs) { toCol = append(toCol, val) } } - m.nulls.set(args) - m.col = toCol + v.nulls.set(args) + v.col = toCol } case types.IntervalFamily: - switch m.t.Width() { + switch v.t.Width() { case -1: default: fromCol := args.Src.Interval() - toCol := m.Interval() + toCol := v.Interval() // NOTE: it is unfortunate that we always append whole slice without paying // attention to whether the values are NULL. However, if we do start paying // attention, the performance suffers dramatically, so we choose to copy @@ -428,15 +431,15 @@ func (m *memColumn) Append(args SliceArgs) { toCol = append(toCol, val) } } - m.nulls.set(args) - m.col = toCol + v.nulls.set(args) + v.col = toCol } case types.JsonFamily: - switch m.t.Width() { + switch v.t.Width() { case -1: default: fromCol := args.Src.JSON() - toCol := m.JSON() + toCol := v.JSON() // NOTE: it is unfortunate that we always append whole slice without paying // attention to whether the values are NULL. However, if we do start paying // attention, the performance suffers dramatically, so we choose to copy @@ -447,15 +450,15 @@ func (m *memColumn) Append(args SliceArgs) { sel := args.Sel[args.SrcStartIdx:args.SrcEndIdx] toCol.appendSliceWithSel(fromCol, args.DestIdx, sel) } - m.nulls.set(args) - m.col = toCol + v.nulls.set(args) + v.col = toCol } case typeconv.DatumVecCanonicalTypeFamily: - switch m.t.Width() { + switch v.t.Width() { case -1: default: fromCol := args.Src.Datum() - toCol := m.Datum() + toCol := v.Datum() // NOTE: it is unfortunate that we always append whole slice without paying // attention to whether the values are NULL. However, if we do start paying // attention, the performance suffers dramatically, so we choose to copy @@ -470,31 +473,37 @@ func (m *memColumn) Append(args SliceArgs) { toCol.AppendVal(val) } } - m.nulls.set(args) - m.col = toCol + v.nulls.set(args) + v.col = toCol } default: - panic(fmt.Sprintf("unhandled type %s", m.t)) + panic(fmt.Sprintf("unhandled type %s", v.t)) } } -func (m *memColumn) Copy(args SliceArgs) { +// Copy uses SliceArgs to copy elements of a source Vec into this Vec. It is +// logically equivalent to: +// copy(destVec[args.DestIdx:], args.Src[args.SrcStartIdx:args.SrcEndIdx]) +// An optional Sel slice can also be provided to apply a filter on the source +// Vec. +// Refer to the SliceArgs comment for specifics and TestCopy for examples. +func (v *Vec) Copy(args SliceArgs) { if args.SrcStartIdx == args.SrcEndIdx { // Nothing to copy, so return early. return } - if m.Nulls().MaybeHasNulls() { + if v.Nulls().MaybeHasNulls() { // We're about to overwrite this entire range, so unset all the nulls. - m.Nulls().UnsetNullRange(args.DestIdx, args.DestIdx+(args.SrcEndIdx-args.SrcStartIdx)) + v.Nulls().UnsetNullRange(args.DestIdx, args.DestIdx+(args.SrcEndIdx-args.SrcStartIdx)) } - switch m.CanonicalTypeFamily() { + switch v.CanonicalTypeFamily() { case types.BoolFamily: - switch m.t.Width() { + switch v.t.Width() { case -1: default: fromCol := args.Src.Bool() - toCol := m.Bool() + toCol := v.Bool() if args.Sel != nil { sel := args.Sel[args.SrcStartIdx:args.SrcEndIdx] n := len(sel) @@ -506,7 +515,7 @@ func (m *memColumn) Copy(args SliceArgs) { //gcassert:bce selIdx := sel[i] if nulls.NullAt(selIdx) { - m.nulls.SetNull(i + args.DestIdx) + v.nulls.SetNull(i + args.DestIdx) } else { v := fromCol.Get(selIdx) //gcassert:bce @@ -527,14 +536,14 @@ func (m *memColumn) Copy(args SliceArgs) { } // No Sel. toCol.CopySlice(fromCol, args.DestIdx, args.SrcStartIdx, args.SrcEndIdx) - m.nulls.set(args) + v.nulls.set(args) } case types.BytesFamily: - switch m.t.Width() { + switch v.t.Width() { case -1: default: fromCol := args.Src.Bytes() - toCol := m.Bytes() + toCol := v.Bytes() if args.Sel != nil { sel := args.Sel[args.SrcStartIdx:args.SrcEndIdx] n := len(sel) @@ -544,7 +553,7 @@ func (m *memColumn) Copy(args SliceArgs) { //gcassert:bce selIdx := sel[i] if nulls.NullAt(selIdx) { - m.nulls.SetNull(i + args.DestIdx) + v.nulls.SetNull(i + args.DestIdx) } else { toCol.Copy(fromCol, i+args.DestIdx, selIdx) } @@ -561,14 +570,14 @@ func (m *memColumn) Copy(args SliceArgs) { } // No Sel. toCol.CopySlice(fromCol, args.DestIdx, args.SrcStartIdx, args.SrcEndIdx) - m.nulls.set(args) + v.nulls.set(args) } case types.DecimalFamily: - switch m.t.Width() { + switch v.t.Width() { case -1: default: fromCol := args.Src.Decimal() - toCol := m.Decimal() + toCol := v.Decimal() if args.Sel != nil { sel := args.Sel[args.SrcStartIdx:args.SrcEndIdx] n := len(sel) @@ -580,7 +589,7 @@ func (m *memColumn) Copy(args SliceArgs) { //gcassert:bce selIdx := sel[i] if nulls.NullAt(selIdx) { - m.nulls.SetNull(i + args.DestIdx) + v.nulls.SetNull(i + args.DestIdx) } else { v := fromCol.Get(selIdx) //gcassert:bce @@ -601,13 +610,13 @@ func (m *memColumn) Copy(args SliceArgs) { } // No Sel. toCol.CopySlice(fromCol, args.DestIdx, args.SrcStartIdx, args.SrcEndIdx) - m.nulls.set(args) + v.nulls.set(args) } case types.IntFamily: - switch m.t.Width() { + switch v.t.Width() { case 16: fromCol := args.Src.Int16() - toCol := m.Int16() + toCol := v.Int16() if args.Sel != nil { sel := args.Sel[args.SrcStartIdx:args.SrcEndIdx] n := len(sel) @@ -619,7 +628,7 @@ func (m *memColumn) Copy(args SliceArgs) { //gcassert:bce selIdx := sel[i] if nulls.NullAt(selIdx) { - m.nulls.SetNull(i + args.DestIdx) + v.nulls.SetNull(i + args.DestIdx) } else { v := fromCol.Get(selIdx) //gcassert:bce @@ -640,10 +649,10 @@ func (m *memColumn) Copy(args SliceArgs) { } // No Sel. toCol.CopySlice(fromCol, args.DestIdx, args.SrcStartIdx, args.SrcEndIdx) - m.nulls.set(args) + v.nulls.set(args) case 32: fromCol := args.Src.Int32() - toCol := m.Int32() + toCol := v.Int32() if args.Sel != nil { sel := args.Sel[args.SrcStartIdx:args.SrcEndIdx] n := len(sel) @@ -655,7 +664,7 @@ func (m *memColumn) Copy(args SliceArgs) { //gcassert:bce selIdx := sel[i] if nulls.NullAt(selIdx) { - m.nulls.SetNull(i + args.DestIdx) + v.nulls.SetNull(i + args.DestIdx) } else { v := fromCol.Get(selIdx) //gcassert:bce @@ -676,11 +685,11 @@ func (m *memColumn) Copy(args SliceArgs) { } // No Sel. toCol.CopySlice(fromCol, args.DestIdx, args.SrcStartIdx, args.SrcEndIdx) - m.nulls.set(args) + v.nulls.set(args) case -1: default: fromCol := args.Src.Int64() - toCol := m.Int64() + toCol := v.Int64() if args.Sel != nil { sel := args.Sel[args.SrcStartIdx:args.SrcEndIdx] n := len(sel) @@ -692,7 +701,7 @@ func (m *memColumn) Copy(args SliceArgs) { //gcassert:bce selIdx := sel[i] if nulls.NullAt(selIdx) { - m.nulls.SetNull(i + args.DestIdx) + v.nulls.SetNull(i + args.DestIdx) } else { v := fromCol.Get(selIdx) //gcassert:bce @@ -713,14 +722,14 @@ func (m *memColumn) Copy(args SliceArgs) { } // No Sel. toCol.CopySlice(fromCol, args.DestIdx, args.SrcStartIdx, args.SrcEndIdx) - m.nulls.set(args) + v.nulls.set(args) } case types.FloatFamily: - switch m.t.Width() { + switch v.t.Width() { case -1: default: fromCol := args.Src.Float64() - toCol := m.Float64() + toCol := v.Float64() if args.Sel != nil { sel := args.Sel[args.SrcStartIdx:args.SrcEndIdx] n := len(sel) @@ -732,7 +741,7 @@ func (m *memColumn) Copy(args SliceArgs) { //gcassert:bce selIdx := sel[i] if nulls.NullAt(selIdx) { - m.nulls.SetNull(i + args.DestIdx) + v.nulls.SetNull(i + args.DestIdx) } else { v := fromCol.Get(selIdx) //gcassert:bce @@ -753,14 +762,14 @@ func (m *memColumn) Copy(args SliceArgs) { } // No Sel. toCol.CopySlice(fromCol, args.DestIdx, args.SrcStartIdx, args.SrcEndIdx) - m.nulls.set(args) + v.nulls.set(args) } case types.TimestampTZFamily: - switch m.t.Width() { + switch v.t.Width() { case -1: default: fromCol := args.Src.Timestamp() - toCol := m.Timestamp() + toCol := v.Timestamp() if args.Sel != nil { sel := args.Sel[args.SrcStartIdx:args.SrcEndIdx] n := len(sel) @@ -772,7 +781,7 @@ func (m *memColumn) Copy(args SliceArgs) { //gcassert:bce selIdx := sel[i] if nulls.NullAt(selIdx) { - m.nulls.SetNull(i + args.DestIdx) + v.nulls.SetNull(i + args.DestIdx) } else { v := fromCol.Get(selIdx) //gcassert:bce @@ -793,14 +802,14 @@ func (m *memColumn) Copy(args SliceArgs) { } // No Sel. toCol.CopySlice(fromCol, args.DestIdx, args.SrcStartIdx, args.SrcEndIdx) - m.nulls.set(args) + v.nulls.set(args) } case types.IntervalFamily: - switch m.t.Width() { + switch v.t.Width() { case -1: default: fromCol := args.Src.Interval() - toCol := m.Interval() + toCol := v.Interval() if args.Sel != nil { sel := args.Sel[args.SrcStartIdx:args.SrcEndIdx] n := len(sel) @@ -812,7 +821,7 @@ func (m *memColumn) Copy(args SliceArgs) { //gcassert:bce selIdx := sel[i] if nulls.NullAt(selIdx) { - m.nulls.SetNull(i + args.DestIdx) + v.nulls.SetNull(i + args.DestIdx) } else { v := fromCol.Get(selIdx) //gcassert:bce @@ -833,14 +842,14 @@ func (m *memColumn) Copy(args SliceArgs) { } // No Sel. toCol.CopySlice(fromCol, args.DestIdx, args.SrcStartIdx, args.SrcEndIdx) - m.nulls.set(args) + v.nulls.set(args) } case types.JsonFamily: - switch m.t.Width() { + switch v.t.Width() { case -1: default: fromCol := args.Src.JSON() - toCol := m.JSON() + toCol := v.JSON() if args.Sel != nil { sel := args.Sel[args.SrcStartIdx:args.SrcEndIdx] n := len(sel) @@ -850,7 +859,7 @@ func (m *memColumn) Copy(args SliceArgs) { //gcassert:bce selIdx := sel[i] if nulls.NullAt(selIdx) { - m.nulls.SetNull(i + args.DestIdx) + v.nulls.SetNull(i + args.DestIdx) } else { toCol.Copy(fromCol, i+args.DestIdx, selIdx) } @@ -867,14 +876,14 @@ func (m *memColumn) Copy(args SliceArgs) { } // No Sel. toCol.CopySlice(fromCol, args.DestIdx, args.SrcStartIdx, args.SrcEndIdx) - m.nulls.set(args) + v.nulls.set(args) } case typeconv.DatumVecCanonicalTypeFamily: - switch m.t.Width() { + switch v.t.Width() { case -1: default: fromCol := args.Src.Datum() - toCol := m.Datum() + toCol := v.Datum() if args.Sel != nil { sel := args.Sel[args.SrcStartIdx:args.SrcEndIdx] n := len(sel) @@ -884,7 +893,7 @@ func (m *memColumn) Copy(args SliceArgs) { //gcassert:bce selIdx := sel[i] if nulls.NullAt(selIdx) { - m.nulls.SetNull(i + args.DestIdx) + v.nulls.SetNull(i + args.DestIdx) } else { v := fromCol.Get(selIdx) toCol.Set(i+args.DestIdx, v) @@ -903,27 +912,31 @@ func (m *memColumn) Copy(args SliceArgs) { } // No Sel. toCol.CopySlice(fromCol, args.DestIdx, args.SrcStartIdx, args.SrcEndIdx) - m.nulls.set(args) + v.nulls.set(args) } default: - panic(fmt.Sprintf("unhandled type %s", m.t)) + panic(fmt.Sprintf("unhandled type %s", v.t)) } } -func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) { +// CopyWithReorderedSource copies a value at position order[sel[i]] in src +// into the receiver at position sel[i]. len(sel) elements are copied. +// Resulting values of elements not mentioned in sel are undefined after +// this function. +func (v *Vec) CopyWithReorderedSource(src *Vec, sel, order []int) { if len(sel) == 0 { return } - if m.nulls.MaybeHasNulls() { - m.nulls.UnsetNulls() + if v.nulls.MaybeHasNulls() { + v.nulls.UnsetNulls() } - switch m.CanonicalTypeFamily() { + switch v.CanonicalTypeFamily() { case types.BoolFamily: - switch m.t.Width() { + switch v.t.Width() { case -1: default: fromCol := src.Bool() - toCol := m.Bool() + toCol := v.Bool() n := len(sel) _ = sel[n-1] if src.MaybeHasNulls() { @@ -933,7 +946,7 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) { destIdx := sel[i] srcIdx := order[destIdx] if nulls.NullAt(srcIdx) { - m.nulls.SetNull(destIdx) + v.nulls.SetNull(destIdx) } else { v := fromCol.Get(srcIdx) toCol.Set(destIdx, v) @@ -952,11 +965,11 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) { } } case types.BytesFamily: - switch m.t.Width() { + switch v.t.Width() { case -1: default: fromCol := src.Bytes() - toCol := m.Bytes() + toCol := v.Bytes() n := len(sel) _ = sel[n-1] if src.MaybeHasNulls() { @@ -966,7 +979,7 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) { destIdx := sel[i] srcIdx := order[destIdx] if nulls.NullAt(srcIdx) { - m.nulls.SetNull(destIdx) + v.nulls.SetNull(destIdx) } else { toCol.Copy(fromCol, destIdx, srcIdx) } @@ -983,11 +996,11 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) { } } case types.DecimalFamily: - switch m.t.Width() { + switch v.t.Width() { case -1: default: fromCol := src.Decimal() - toCol := m.Decimal() + toCol := v.Decimal() n := len(sel) _ = sel[n-1] if src.MaybeHasNulls() { @@ -997,7 +1010,7 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) { destIdx := sel[i] srcIdx := order[destIdx] if nulls.NullAt(srcIdx) { - m.nulls.SetNull(destIdx) + v.nulls.SetNull(destIdx) } else { v := fromCol.Get(srcIdx) toCol.Set(destIdx, v) @@ -1016,10 +1029,10 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) { } } case types.IntFamily: - switch m.t.Width() { + switch v.t.Width() { case 16: fromCol := src.Int16() - toCol := m.Int16() + toCol := v.Int16() n := len(sel) _ = sel[n-1] if src.MaybeHasNulls() { @@ -1029,7 +1042,7 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) { destIdx := sel[i] srcIdx := order[destIdx] if nulls.NullAt(srcIdx) { - m.nulls.SetNull(destIdx) + v.nulls.SetNull(destIdx) } else { v := fromCol.Get(srcIdx) toCol.Set(destIdx, v) @@ -1048,7 +1061,7 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) { } case 32: fromCol := src.Int32() - toCol := m.Int32() + toCol := v.Int32() n := len(sel) _ = sel[n-1] if src.MaybeHasNulls() { @@ -1058,7 +1071,7 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) { destIdx := sel[i] srcIdx := order[destIdx] if nulls.NullAt(srcIdx) { - m.nulls.SetNull(destIdx) + v.nulls.SetNull(destIdx) } else { v := fromCol.Get(srcIdx) toCol.Set(destIdx, v) @@ -1078,7 +1091,7 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) { case -1: default: fromCol := src.Int64() - toCol := m.Int64() + toCol := v.Int64() n := len(sel) _ = sel[n-1] if src.MaybeHasNulls() { @@ -1088,7 +1101,7 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) { destIdx := sel[i] srcIdx := order[destIdx] if nulls.NullAt(srcIdx) { - m.nulls.SetNull(destIdx) + v.nulls.SetNull(destIdx) } else { v := fromCol.Get(srcIdx) toCol.Set(destIdx, v) @@ -1107,11 +1120,11 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) { } } case types.FloatFamily: - switch m.t.Width() { + switch v.t.Width() { case -1: default: fromCol := src.Float64() - toCol := m.Float64() + toCol := v.Float64() n := len(sel) _ = sel[n-1] if src.MaybeHasNulls() { @@ -1121,7 +1134,7 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) { destIdx := sel[i] srcIdx := order[destIdx] if nulls.NullAt(srcIdx) { - m.nulls.SetNull(destIdx) + v.nulls.SetNull(destIdx) } else { v := fromCol.Get(srcIdx) toCol.Set(destIdx, v) @@ -1140,11 +1153,11 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) { } } case types.TimestampTZFamily: - switch m.t.Width() { + switch v.t.Width() { case -1: default: fromCol := src.Timestamp() - toCol := m.Timestamp() + toCol := v.Timestamp() n := len(sel) _ = sel[n-1] if src.MaybeHasNulls() { @@ -1154,7 +1167,7 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) { destIdx := sel[i] srcIdx := order[destIdx] if nulls.NullAt(srcIdx) { - m.nulls.SetNull(destIdx) + v.nulls.SetNull(destIdx) } else { v := fromCol.Get(srcIdx) toCol.Set(destIdx, v) @@ -1173,11 +1186,11 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) { } } case types.IntervalFamily: - switch m.t.Width() { + switch v.t.Width() { case -1: default: fromCol := src.Interval() - toCol := m.Interval() + toCol := v.Interval() n := len(sel) _ = sel[n-1] if src.MaybeHasNulls() { @@ -1187,7 +1200,7 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) { destIdx := sel[i] srcIdx := order[destIdx] if nulls.NullAt(srcIdx) { - m.nulls.SetNull(destIdx) + v.nulls.SetNull(destIdx) } else { v := fromCol.Get(srcIdx) toCol.Set(destIdx, v) @@ -1206,11 +1219,11 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) { } } case types.JsonFamily: - switch m.t.Width() { + switch v.t.Width() { case -1: default: fromCol := src.JSON() - toCol := m.JSON() + toCol := v.JSON() n := len(sel) _ = sel[n-1] if src.MaybeHasNulls() { @@ -1220,7 +1233,7 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) { destIdx := sel[i] srcIdx := order[destIdx] if nulls.NullAt(srcIdx) { - m.nulls.SetNull(destIdx) + v.nulls.SetNull(destIdx) } else { toCol.Copy(fromCol, destIdx, srcIdx) } @@ -1237,11 +1250,11 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) { } } case typeconv.DatumVecCanonicalTypeFamily: - switch m.t.Width() { + switch v.t.Width() { case -1: default: fromCol := src.Datum() - toCol := m.Datum() + toCol := v.Datum() n := len(sel) _ = sel[n-1] if src.MaybeHasNulls() { @@ -1251,7 +1264,7 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) { destIdx := sel[i] srcIdx := order[destIdx] if nulls.NullAt(srcIdx) { - m.nulls.SetNull(destIdx) + v.nulls.SetNull(destIdx) } else { v := fromCol.Get(srcIdx) toCol.Set(destIdx, v) @@ -1270,143 +1283,147 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) { } } default: - panic(fmt.Sprintf("unhandled type %s", m.t)) + panic(fmt.Sprintf("unhandled type %s", v.t)) } } -func (m *memColumn) Window(start int, end int) Vec { - switch m.CanonicalTypeFamily() { +// Window returns a "window" into the Vec. A "window" is similar to Golang's +// slice of the current Vec from [start, end), but the returned object is NOT +// allowed to be modified (the modification might result in an undefined +// behavior). +func (v *Vec) Window(start int, end int) *Vec { + switch v.CanonicalTypeFamily() { case types.BoolFamily: - switch m.t.Width() { + switch v.t.Width() { case -1: default: - col := m.Bool() - return &memColumn{ - t: m.t, - canonicalTypeFamily: m.canonicalTypeFamily, + col := v.Bool() + return &Vec{ + t: v.t, + canonicalTypeFamily: v.canonicalTypeFamily, col: col.Window(start, end), - nulls: m.nulls.Slice(start, end), + nulls: v.nulls.Slice(start, end), } } case types.BytesFamily: - switch m.t.Width() { + switch v.t.Width() { case -1: default: - col := m.Bytes() - return &memColumn{ - t: m.t, - canonicalTypeFamily: m.canonicalTypeFamily, + col := v.Bytes() + return &Vec{ + t: v.t, + canonicalTypeFamily: v.canonicalTypeFamily, col: col.Window(start, end), - nulls: m.nulls.Slice(start, end), + nulls: v.nulls.Slice(start, end), } } case types.DecimalFamily: - switch m.t.Width() { + switch v.t.Width() { case -1: default: - col := m.Decimal() - return &memColumn{ - t: m.t, - canonicalTypeFamily: m.canonicalTypeFamily, + col := v.Decimal() + return &Vec{ + t: v.t, + canonicalTypeFamily: v.canonicalTypeFamily, col: col.Window(start, end), - nulls: m.nulls.Slice(start, end), + nulls: v.nulls.Slice(start, end), } } case types.IntFamily: - switch m.t.Width() { + switch v.t.Width() { case 16: - col := m.Int16() - return &memColumn{ - t: m.t, - canonicalTypeFamily: m.canonicalTypeFamily, + col := v.Int16() + return &Vec{ + t: v.t, + canonicalTypeFamily: v.canonicalTypeFamily, col: col.Window(start, end), - nulls: m.nulls.Slice(start, end), + nulls: v.nulls.Slice(start, end), } case 32: - col := m.Int32() - return &memColumn{ - t: m.t, - canonicalTypeFamily: m.canonicalTypeFamily, + col := v.Int32() + return &Vec{ + t: v.t, + canonicalTypeFamily: v.canonicalTypeFamily, col: col.Window(start, end), - nulls: m.nulls.Slice(start, end), + nulls: v.nulls.Slice(start, end), } case -1: default: - col := m.Int64() - return &memColumn{ - t: m.t, - canonicalTypeFamily: m.canonicalTypeFamily, + col := v.Int64() + return &Vec{ + t: v.t, + canonicalTypeFamily: v.canonicalTypeFamily, col: col.Window(start, end), - nulls: m.nulls.Slice(start, end), + nulls: v.nulls.Slice(start, end), } } case types.FloatFamily: - switch m.t.Width() { + switch v.t.Width() { case -1: default: - col := m.Float64() - return &memColumn{ - t: m.t, - canonicalTypeFamily: m.canonicalTypeFamily, + col := v.Float64() + return &Vec{ + t: v.t, + canonicalTypeFamily: v.canonicalTypeFamily, col: col.Window(start, end), - nulls: m.nulls.Slice(start, end), + nulls: v.nulls.Slice(start, end), } } case types.TimestampTZFamily: - switch m.t.Width() { + switch v.t.Width() { case -1: default: - col := m.Timestamp() - return &memColumn{ - t: m.t, - canonicalTypeFamily: m.canonicalTypeFamily, + col := v.Timestamp() + return &Vec{ + t: v.t, + canonicalTypeFamily: v.canonicalTypeFamily, col: col.Window(start, end), - nulls: m.nulls.Slice(start, end), + nulls: v.nulls.Slice(start, end), } } case types.IntervalFamily: - switch m.t.Width() { + switch v.t.Width() { case -1: default: - col := m.Interval() - return &memColumn{ - t: m.t, - canonicalTypeFamily: m.canonicalTypeFamily, + col := v.Interval() + return &Vec{ + t: v.t, + canonicalTypeFamily: v.canonicalTypeFamily, col: col.Window(start, end), - nulls: m.nulls.Slice(start, end), + nulls: v.nulls.Slice(start, end), } } case types.JsonFamily: - switch m.t.Width() { + switch v.t.Width() { case -1: default: - col := m.JSON() - return &memColumn{ - t: m.t, - canonicalTypeFamily: m.canonicalTypeFamily, + col := v.JSON() + return &Vec{ + t: v.t, + canonicalTypeFamily: v.canonicalTypeFamily, col: col.Window(start, end), - nulls: m.nulls.Slice(start, end), + nulls: v.nulls.Slice(start, end), } } case typeconv.DatumVecCanonicalTypeFamily: - switch m.t.Width() { + switch v.t.Width() { case -1: default: - col := m.Datum() - return &memColumn{ - t: m.t, - canonicalTypeFamily: m.canonicalTypeFamily, + col := v.Datum() + return &Vec{ + t: v.t, + canonicalTypeFamily: v.canonicalTypeFamily, col: col.Window(start, end), - nulls: m.nulls.Slice(start, end), + nulls: v.nulls.Slice(start, end), } } } - panic(fmt.Sprintf("unhandled type %s", m.t)) + panic(fmt.Sprintf("unhandled type %s", v.t)) } // SetValueAt is an inefficient helper to set the value in a Vec when the type // is unknown. -func SetValueAt(v Vec, elem interface{}, rowIdx int) { +func SetValueAt(v *Vec, elem interface{}, rowIdx int) { switch t := v.Type(); v.CanonicalTypeFamily() { case types.BoolFamily: switch t.Width() { @@ -1495,7 +1512,7 @@ func SetValueAt(v Vec, elem interface{}, rowIdx int) { // GetValueAt is an inefficient helper to get the value in a Vec when the type // is unknown. -func GetValueAt(v Vec, rowIdx int) interface{} { +func GetValueAt(v *Vec, rowIdx int) interface{} { if v.Nulls().NullAt(rowIdx) { return nil } diff --git a/pkg/col/coldata/vec.go b/pkg/col/coldata/vec.go index 25d0aab..3e21f45 100644 --- a/pkg/col/coldata/vec.go +++ b/pkg/col/coldata/vec.go @@ -1,12 +1,7 @@ // Copyright 2018 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. // Package coldata exposes utilities for handling columnarized data. package coldata @@ -27,7 +22,7 @@ type Column interface { // SliceArgs represents the arguments passed in to Vec.Append and Nulls.set. type SliceArgs struct { // Src is the data being appended. - Src Vec + Src *Vec // Sel is an optional slice specifying indices to append to the destination // slice. Note that Src{Start,End}Idx apply to Sel. Sel []int @@ -42,103 +37,10 @@ type SliceArgs struct { SrcEndIdx int } -// Vec is an interface that represents a column vector that's accessible by -// Go native types. -type Vec interface { - // Type returns the type of data stored in this Vec. Consider whether - // CanonicalTypeFamily() should be used instead. - Type() *types.T - // CanonicalTypeFamily returns the canonical type family of data stored in - // this Vec. - CanonicalTypeFamily() types.Family - - // Bool returns a bool list. - Bool() Bools - // Int16 returns an int16 slice. - Int16() Int16s - // Int32 returns an int32 slice. - Int32() Int32s - // Int64 returns an int64 slice. - Int64() Int64s - // Float64 returns a float64 slice. - Float64() Float64s - // Bytes returns a flat Bytes representation. - Bytes() *Bytes - // Decimal returns an apd.Decimal slice. - Decimal() Decimals - // Timestamp returns a time.Time slice. - Timestamp() Times - // Interval returns a duration.Duration slice. - Interval() Durations - // JSON returns a vector of JSONs. - JSON() *JSONs - // Datum returns a vector of Datums. - Datum() DatumVec - - // Col returns the raw, typeless backing storage for this Vec. - Col() Column - - // SetCol sets the member column (in the case of mutable columns). - SetCol(Column) - - // TemplateType returns an []interface{} and is used for operator templates. - // Do not call this from normal code - it'll always panic. - TemplateType() []interface{} - - // Append uses SliceArgs to append elements of a source Vec into this Vec. - // It is logically equivalent to: - // destVec = append(destVec[:args.DestIdx], args.Src[args.SrcStartIdx:args.SrcEndIdx]) - // An optional Sel slice can also be provided to apply a filter on the source - // Vec. - // Refer to the SliceArgs comment for specifics and TestAppend for examples. - // - // Note: Append()'ing from a Vector into itself is not supported. - Append(SliceArgs) - - // Copy uses SliceArgs to copy elements of a source Vec into this Vec. It is - // logically equivalent to: - // copy(destVec[args.DestIdx:], args.Src[args.SrcStartIdx:args.SrcEndIdx]) - // An optional Sel slice can also be provided to apply a filter on the source - // Vec. - // Refer to the SliceArgs comment for specifics and TestCopy for examples. - Copy(SliceArgs) - - // CopyWithReorderedSource copies a value at position order[sel[i]] in src - // into the receiver at position sel[i]. len(sel) elements are copied. - // Resulting values of elements not mentioned in sel are undefined after - // this function. - CopyWithReorderedSource(src Vec, sel, order []int) - - // Window returns a "window" into the Vec. A "window" is similar to Golang's - // slice of the current Vec from [start, end), but the returned object is NOT - // allowed to be modified (the modification might result in an undefined - // behavior). - Window(start int, end int) Vec - - // MaybeHasNulls returns true if the column possibly has any null values, and - // returns false if the column definitely has no null values. - MaybeHasNulls() bool - - // Nulls returns the nulls vector for the column. - Nulls() *Nulls - - // SetNulls sets the nulls vector for this column. - SetNulls(Nulls) - - // Length returns the length of the slice that is underlying this Vec. - Length() int - - // Capacity returns the capacity of the Golang's slice that is underlying - // this Vec. Note that if there is no "slice" (like in case of flat bytes), - // then "capacity" of such object is equal to the number of elements. - Capacity() int -} - -var _ Vec = &memColumn{} - -// memColumn is a simple pass-through implementation of Vec that just casts -// a generic interface{} to the proper type when requested. -type memColumn struct { +// Vec is a column vector that's accessible by Go native types. +// TODO(yuzefovich): consider storing / passing vectors by value rather than +// pointer. +type Vec struct { t *types.T canonicalTypeFamily types.Family col Column @@ -148,6 +50,10 @@ type memColumn struct { // ColumnFactory is an interface that can construct columns for Batches. type ColumnFactory interface { MakeColumn(t *types.T, length int) Column + // MakeColumns batch-allocates columns of the given type and the given + // length. Note that datum-backed vectors will be incomplete - the caller + // must set the correct type on each one. + MakeColumns(columns []Column, t *types.T, length int) } type defaultColumnFactory struct{} @@ -188,17 +94,87 @@ func (cf *defaultColumnFactory) MakeColumn(t *types.T, length int) Column { } } -// NewMemColumn returns a new memColumn, initialized with a length using the -// given column factory. -func NewMemColumn(t *types.T, length int, factory ColumnFactory) Vec { - var m memColumn - m.init(t, length, factory) - return &m +func (cf *defaultColumnFactory) MakeColumns(columns []Column, t *types.T, length int) { + allocLength := len(columns) * length + switch canonicalTypeFamily := typeconv.TypeFamilyToCanonicalTypeFamily(t.Family()); canonicalTypeFamily { + case types.BoolFamily: + alloc := make(Bools, allocLength) + for i := range columns { + columns[i] = alloc[:length:length] + alloc = alloc[length:] + } + case types.BytesFamily: + alloc := make([]element, allocLength) + wrapperAlloc := make([]Bytes, len(columns)) + for i := range columns { + wrapperAlloc[i].elements = alloc[:length:length] + columns[i] = &wrapperAlloc[i] + alloc = alloc[length:] + } + case types.IntFamily: + switch t.Width() { + case 16: + alloc := make(Int16s, allocLength) + for i := range columns { + columns[i] = alloc[:length:length] + alloc = alloc[length:] + } + case 32: + alloc := make(Int32s, allocLength) + for i := range columns { + columns[i] = alloc[:length:length] + alloc = alloc[length:] + } + case 0, 64: + alloc := make(Int64s, allocLength) + for i := range columns { + columns[i] = alloc[:length:length] + alloc = alloc[length:] + } + default: + panic(fmt.Sprintf("unexpected integer width: %d", t.Width())) + } + case types.FloatFamily: + alloc := make(Float64s, allocLength) + for i := range columns { + columns[i] = alloc[:length:length] + alloc = alloc[length:] + } + case types.DecimalFamily: + alloc := make(Decimals, allocLength) + for i := range columns { + columns[i] = alloc[:length:length] + alloc = alloc[length:] + } + case types.TimestampTZFamily: + alloc := make(Times, allocLength) + for i := range columns { + columns[i] = alloc[:length:length] + alloc = alloc[length:] + } + case types.IntervalFamily: + alloc := make(Durations, allocLength) + for i := range columns { + columns[i] = alloc[:length:length] + alloc = alloc[length:] + } + case types.JsonFamily: + alloc := make([]element, allocLength) + wrapperAlloc := make([]JSONs, len(columns)) + for i := range columns { + wrapperAlloc[i].elements = alloc[:length:length] + columns[i] = &wrapperAlloc[i] + alloc = alloc[length:] + } + default: + panic(fmt.Sprintf("StandardColumnFactory doesn't support %s", t)) + } } -// init initializes the receiver with a length using the given column factory. -func (m *memColumn) init(t *types.T, length int, factory ColumnFactory) { - *m = memColumn{ +// NewVec returns a new Vec, initialized with a length using the given column +// factory. +func NewVec(t *types.T, length int, factory ColumnFactory) *Vec { + return &Vec{ t: t, canonicalTypeFamily: typeconv.TypeFamilyToCanonicalTypeFamily(t.Family()), col: factory.MakeColumn(t, length), @@ -206,116 +182,143 @@ func (m *memColumn) init(t *types.T, length int, factory ColumnFactory) { } } -func (m *memColumn) Type() *types.T { - return m.t +// Type returns the type of data stored in this Vec. Consider whether +// CanonicalTypeFamily() should be used instead. +func (v *Vec) Type() *types.T { + return v.t } -func (m *memColumn) CanonicalTypeFamily() types.Family { - return m.canonicalTypeFamily +// CanonicalTypeFamily returns the canonical type family of data stored in this +// Vec. +func (v *Vec) CanonicalTypeFamily() types.Family { + return v.canonicalTypeFamily } -func (m *memColumn) SetCol(col Column) { - m.col = col +// SetCol sets the member column (in the case of mutable columns). +func (v *Vec) SetCol(col Column) { + v.col = col } -func (m *memColumn) Bool() Bools { - return m.col.(Bools) +// Bool returns a bool list. +func (v *Vec) Bool() Bools { + return v.col.(Bools) } -func (m *memColumn) Int16() Int16s { - return m.col.(Int16s) +// Int16 returns an int16 slice. +func (v *Vec) Int16() Int16s { + return v.col.(Int16s) } -func (m *memColumn) Int32() Int32s { - return m.col.(Int32s) +// Int32 returns an int32 slice. +func (v *Vec) Int32() Int32s { + return v.col.(Int32s) } -func (m *memColumn) Int64() Int64s { - return m.col.(Int64s) +// Int64 returns an int64 slice. +func (v *Vec) Int64() Int64s { + return v.col.(Int64s) } -func (m *memColumn) Float64() Float64s { - return m.col.(Float64s) +// Float64 returns a float64 slice. +func (v *Vec) Float64() Float64s { + return v.col.(Float64s) } -func (m *memColumn) Bytes() *Bytes { - return m.col.(*Bytes) +// Bytes returns a flat Bytes representation. +func (v *Vec) Bytes() *Bytes { + return v.col.(*Bytes) } -func (m *memColumn) Decimal() Decimals { - return m.col.(Decimals) +// Decimal returns an apd.Decimal slice. +func (v *Vec) Decimal() Decimals { + return v.col.(Decimals) } -func (m *memColumn) Timestamp() Times { - return m.col.(Times) +// Timestamp returns a time.Time slice. +func (v *Vec) Timestamp() Times { + return v.col.(Times) } -func (m *memColumn) Interval() Durations { - return m.col.(Durations) +// Interval returns a duration.Duration slice. +func (v *Vec) Interval() Durations { + return v.col.(Durations) } -func (m *memColumn) JSON() *JSONs { - return m.col.(*JSONs) +// JSON returns a vector of JSONs. +func (v *Vec) JSON() *JSONs { + return v.col.(*JSONs) } -func (m *memColumn) Datum() DatumVec { - return m.col.(DatumVec) +// Datum returns a vector of Datums. +func (v *Vec) Datum() DatumVec { + return v.col.(DatumVec) } -func (m *memColumn) Col() Column { - return m.col +// Col returns the raw, typeless backing storage for this Vec. +func (v *Vec) Col() Column { + return v.col } -func (m *memColumn) TemplateType() []interface{} { +// TemplateType returns an []interface{} and is used for operator templates. +// Do not call this from normal code - it'll always panic. +func (v *Vec) TemplateType() []interface{} { panic("don't call this from non template code") } -func (m *memColumn) MaybeHasNulls() bool { - return m.nulls.maybeHasNulls +// MaybeHasNulls returns true if the column possibly has any null values, and +// returns false if the column definitely has no null values. +func (v *Vec) MaybeHasNulls() bool { + return v.nulls.maybeHasNulls } -func (m *memColumn) Nulls() *Nulls { - return &m.nulls +// Nulls returns the nulls vector for the column. +func (v *Vec) Nulls() *Nulls { + return &v.nulls } -func (m *memColumn) SetNulls(n Nulls) { - m.nulls = n +// SetNulls sets the nulls vector for this column. +func (v *Vec) SetNulls(n Nulls) { + v.nulls = n } -func (m *memColumn) Length() int { - return m.col.Len() +// Length returns the length of the slice that is underlying this Vec. +func (v *Vec) Length() int { + return v.col.Len() } -func (m *memColumn) Capacity() int { - switch m.CanonicalTypeFamily() { +// Capacity returns the capacity of the Golang's slice that is underlying +// this Vec. Note that if there is no "slice" (like in case of flat bytes), +// then "capacity" of such object is equal to the number of elements. +func (v *Vec) Capacity() int { + switch v.CanonicalTypeFamily() { case types.BoolFamily: - return cap(m.col.(Bools)) + return cap(v.col.(Bools)) case types.BytesFamily: - return m.Bytes().Len() + return v.Bytes().Len() case types.IntFamily: - switch m.t.Width() { + switch v.t.Width() { case 16: - return cap(m.col.(Int16s)) + return cap(v.col.(Int16s)) case 32: - return cap(m.col.(Int32s)) + return cap(v.col.(Int32s)) case 0, 64: - return cap(m.col.(Int64s)) + return cap(v.col.(Int64s)) default: - panic(fmt.Sprintf("unexpected int width: %d", m.t.Width())) + panic(fmt.Sprintf("unexpected int width: %d", v.t.Width())) } case types.FloatFamily: - return cap(m.col.(Float64s)) + return cap(v.col.(Float64s)) case types.DecimalFamily: - return cap(m.col.(Decimals)) + return cap(v.col.(Decimals)) case types.TimestampTZFamily: - return cap(m.col.(Times)) + return cap(v.col.(Times)) case types.IntervalFamily: - return cap(m.col.(Durations)) + return cap(v.col.(Durations)) case types.JsonFamily: - return m.JSON().Len() + return v.JSON().Len() case typeconv.DatumVecCanonicalTypeFamily: - return m.col.(DatumVec).Cap() + return v.col.(DatumVec).Cap() default: - panic(fmt.Sprintf("unhandled type %s", m.t)) + panic(fmt.Sprintf("unhandled type %s", v.t)) } } diff --git a/pkg/col/coldata/vec_tmpl.go b/pkg/col/coldata/vec_tmpl.go index 23c9f41..9f2a72f 100644 --- a/pkg/col/coldata/vec_tmpl.go +++ b/pkg/col/coldata/vec_tmpl.go @@ -1,16 +1,10 @@ // Copyright 2018 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. // {{/* //go:build execgen_template -// +build execgen_template // // This file is the execgen template for vec.eg.go. It's formatted in a @@ -64,7 +58,7 @@ const _TYPE_WIDTH = 0 // they are working with can then access the typed column directly, avoiding // expensive type casts. type TypedVecs struct { - Vecs []Vec + Vecs []*Vec Nulls []*Nulls // Fields below need to be accessed by an index mapped via ColsMap. @@ -138,15 +132,23 @@ func (v *TypedVecs) Reset() { // {{end}} } -func (m *memColumn) Append(args SliceArgs) { - switch m.CanonicalTypeFamily() { +// Append uses SliceArgs to append elements of a source Vec into this Vec. +// It is logically equivalent to: +// destVec = append(destVec[:args.DestIdx], args.Src[args.SrcStartIdx:args.SrcEndIdx]) +// An optional Sel slice can also be provided to apply a filter on the source +// Vec. +// Refer to the SliceArgs comment for specifics and TestAppend for examples. +// +// Note: Append()'ing from a Vector into itself is not supported. +func (v *Vec) Append(args SliceArgs) { + switch v.CanonicalTypeFamily() { // {{range .}} case _CANONICAL_TYPE_FAMILY: - switch m.t.Width() { + switch v.t.Width() { // {{range .WidthOverloads}} case _TYPE_WIDTH: fromCol := args.Src.TemplateType() - toCol := m.TemplateType() + toCol := v.TemplateType() // NOTE: it is unfortunate that we always append whole slice without paying // attention to whether the values are NULL. However, if we do start paying // attention, the performance suffers dramatically, so we choose to copy @@ -166,34 +168,40 @@ func (m *memColumn) Append(args SliceArgs) { } // {{end}} } - m.nulls.set(args) - m.col = toCol + v.nulls.set(args) + v.col = toCol // {{end}} } // {{end}} default: - panic(fmt.Sprintf("unhandled type %s", m.t)) + panic(fmt.Sprintf("unhandled type %s", v.t)) } } -func (m *memColumn) Copy(args SliceArgs) { +// Copy uses SliceArgs to copy elements of a source Vec into this Vec. It is +// logically equivalent to: +// copy(destVec[args.DestIdx:], args.Src[args.SrcStartIdx:args.SrcEndIdx]) +// An optional Sel slice can also be provided to apply a filter on the source +// Vec. +// Refer to the SliceArgs comment for specifics and TestCopy for examples. +func (v *Vec) Copy(args SliceArgs) { if args.SrcStartIdx == args.SrcEndIdx { // Nothing to copy, so return early. return } - if m.Nulls().MaybeHasNulls() { + if v.Nulls().MaybeHasNulls() { // We're about to overwrite this entire range, so unset all the nulls. - m.Nulls().UnsetNullRange(args.DestIdx, args.DestIdx+(args.SrcEndIdx-args.SrcStartIdx)) + v.Nulls().UnsetNullRange(args.DestIdx, args.DestIdx+(args.SrcEndIdx-args.SrcStartIdx)) } - switch m.CanonicalTypeFamily() { + switch v.CanonicalTypeFamily() { // {{range .}} case _CANONICAL_TYPE_FAMILY: - switch m.t.Width() { + switch v.t.Width() { // {{range .WidthOverloads}} case _TYPE_WIDTH: fromCol := args.Src.TemplateType() - toCol := m.TemplateType() + toCol := v.TemplateType() if args.Sel != nil { sel := args.Sel[args.SrcStartIdx:args.SrcEndIdx] n := len(sel) @@ -207,7 +215,7 @@ func (m *memColumn) Copy(args SliceArgs) { //gcassert:bce selIdx := sel[i] if nulls.NullAt(selIdx) { - m.nulls.SetNull(i + args.DestIdx) + v.nulls.SetNull(i + args.DestIdx) } else { // {{if .IsBytesLike}} toCol.Copy(fromCol, i+args.DestIdx, selIdx) @@ -262,12 +270,12 @@ func (m *memColumn) Copy(args SliceArgs) { } // No Sel. toCol.CopySlice(fromCol, args.DestIdx, args.SrcStartIdx, args.SrcEndIdx) - m.nulls.set(args) + v.nulls.set(args) // {{end}} } // {{end}} default: - panic(fmt.Sprintf("unhandled type %s", m.t)) + panic(fmt.Sprintf("unhandled type %s", v.t)) } } @@ -280,7 +288,7 @@ func _COPY_WITH_REORDERED_SOURCE(_SRC_HAS_NULLS bool) { // */}} srcIdx := order[destIdx] // {{if .SrcHasNulls}} if nulls.NullAt(srcIdx) { - m.nulls.SetNull(destIdx) + v.nulls.SetNull(destIdx) } else // {{end}} { @@ -298,21 +306,25 @@ func _COPY_WITH_REORDERED_SOURCE(_SRC_HAS_NULLS bool) { // */}} // */}} -func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) { +// CopyWithReorderedSource copies a value at position order[sel[i]] in src +// into the receiver at position sel[i]. len(sel) elements are copied. +// Resulting values of elements not mentioned in sel are undefined after +// this function. +func (v *Vec) CopyWithReorderedSource(src *Vec, sel, order []int) { if len(sel) == 0 { return } - if m.nulls.MaybeHasNulls() { - m.nulls.UnsetNulls() + if v.nulls.MaybeHasNulls() { + v.nulls.UnsetNulls() } - switch m.CanonicalTypeFamily() { + switch v.CanonicalTypeFamily() { // {{range .}} case _CANONICAL_TYPE_FAMILY: - switch m.t.Width() { + switch v.t.Width() { // {{range .WidthOverloads}} case _TYPE_WIDTH: fromCol := src.TemplateType() - toCol := m.TemplateType() + toCol := v.TemplateType() n := len(sel) _ = sel[n-1] if src.MaybeHasNulls() { @@ -325,34 +337,38 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) { } // {{end}} default: - panic(fmt.Sprintf("unhandled type %s", m.t)) + panic(fmt.Sprintf("unhandled type %s", v.t)) } } -func (m *memColumn) Window(start int, end int) Vec { - switch m.CanonicalTypeFamily() { +// Window returns a "window" into the Vec. A "window" is similar to Golang's +// slice of the current Vec from [start, end), but the returned object is NOT +// allowed to be modified (the modification might result in an undefined +// behavior). +func (v *Vec) Window(start int, end int) *Vec { + switch v.CanonicalTypeFamily() { // {{range .}} case _CANONICAL_TYPE_FAMILY: - switch m.t.Width() { + switch v.t.Width() { // {{range .WidthOverloads}} case _TYPE_WIDTH: - col := m.TemplateType() - return &memColumn{ - t: m.t, - canonicalTypeFamily: m.canonicalTypeFamily, + col := v.TemplateType() + return &Vec{ + t: v.t, + canonicalTypeFamily: v.canonicalTypeFamily, col: col.Window(start, end), - nulls: m.nulls.Slice(start, end), + nulls: v.nulls.Slice(start, end), } // {{end}} } // {{end}} } - panic(fmt.Sprintf("unhandled type %s", m.t)) + panic(fmt.Sprintf("unhandled type %s", v.t)) } // SetValueAt is an inefficient helper to set the value in a Vec when the type // is unknown. -func SetValueAt(v Vec, elem interface{}, rowIdx int) { +func SetValueAt(v *Vec, elem interface{}, rowIdx int) { switch t := v.Type(); v.CanonicalTypeFamily() { // {{range .}} case _CANONICAL_TYPE_FAMILY: @@ -372,7 +388,7 @@ func SetValueAt(v Vec, elem interface{}, rowIdx int) { // GetValueAt is an inefficient helper to get the value in a Vec when the type // is unknown. -func GetValueAt(v Vec, rowIdx int) interface{} { +func GetValueAt(v *Vec, rowIdx int) interface{} { if v.Nulls().NullAt(rowIdx) { return nil } diff --git a/pkg/col/typeconv/typeconv.go b/pkg/col/typeconv/typeconv.go index 7900d3c..2ecf195 100644 --- a/pkg/col/typeconv/typeconv.go +++ b/pkg/col/typeconv/typeconv.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package typeconv diff --git a/pkg/docs/docs.go b/pkg/docs/docs.go index da30f60..e719bf6 100644 --- a/pkg/docs/docs.go +++ b/pkg/docs/docs.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package docs @@ -18,12 +13,12 @@ import ( // URLBase is the root URL for the version of the docs associated with this // binary. -var URLBase = "https://www.cockroachlabs.com/docs/" + build.BinaryVersionPrefix() +var URLBase = "https://www.cockroachlabs.com/docs/" + build.VersionForURLs() // URLReleaseNotesBase is the root URL for the release notes for the .0 patch // release associated with this binary. var URLReleaseNotesBase = fmt.Sprintf("https://www.cockroachlabs.com/docs/releases/%s.0.html", - build.BinaryVersionPrefix()) + build.VersionForURLs()) // URL generates the URL to pageName in the version of the docs associated // with this binary. diff --git a/pkg/geo/bbox.go b/pkg/geo/bbox.go index 8719018..e3bf48b 100644 --- a/pkg/geo/bbox.go +++ b/pkg/geo/bbox.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package geo diff --git a/pkg/geo/encode.go b/pkg/geo/encode.go index 6f6a2f1..e328f06 100644 --- a/pkg/geo/encode.go +++ b/pkg/geo/encode.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package geo @@ -32,8 +27,10 @@ import ( "github.com/twpayne/go-geom/encoding/wkt" ) -// DefaultGeoJSONDecimalDigits is the default number of digits coordinates in GeoJSON. -const DefaultGeoJSONDecimalDigits = 9 +// FullPrecisionGeoJSON, when used in place of max decimal digits in +// GeoJSON functions, indicates to GeoJSON that it should use full +// precision when encoding JSON. +const FullPrecisionGeoJSON = -1 // SpatialObjectToWKT transforms a given SpatialObject to WKT. func SpatialObjectToWKT(so geopb.SpatialObject, maxDecimalDigits int) (geopb.WKT, error) { diff --git a/pkg/geo/errors.go b/pkg/geo/errors.go index b0f73f6..0c1b1b2 100644 --- a/pkg/geo/errors.go +++ b/pkg/geo/errors.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package geo diff --git a/pkg/geo/geo.go b/pkg/geo/geo.go index ececb73..b548eac 100644 --- a/pkg/geo/geo.go +++ b/pkg/geo/geo.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. // Package geo contains the base types for spatial data type operations. package geo diff --git a/pkg/geo/geopb/config.go b/pkg/geo/geopb/config.go new file mode 100644 index 0000000..8a280ed --- /dev/null +++ b/pkg/geo/geopb/config.go @@ -0,0 +1,24 @@ +// Copyright 2022 The Cockroach Authors. +// +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. + +package geopb + +// IsEmpty returns whether the config contains a geospatial index +// configuration. +func (cfg Config) IsEmpty() bool { + return cfg.S2Geography == nil && cfg.S2Geometry == nil +} + +// IsGeography returns whether the config is a geography geospatial index +// configuration. +func (cfg Config) IsGeography() bool { + return cfg.S2Geography != nil +} + +// IsGeometry returns whether the config is a geometry geospatial index +// configuration. +func (cfg Config) IsGeometry() bool { + return cfg.S2Geometry != nil +} diff --git a/pkg/geo/geopb/config.pb.go b/pkg/geo/geopb/config.pb.go new file mode 100644 index 0000000..fe25911 --- /dev/null +++ b/pkg/geo/geopb/config.pb.go @@ -0,0 +1,1191 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: geo/geopb/config.proto + +package geopb + +import ( + encoding_binary "encoding/binary" + fmt "fmt" + _ "github.com/gogo/protobuf/gogoproto" + proto "github.com/gogo/protobuf/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// Config is the information used to tune one instance of a geospatial index. +// Each SQL index will have its own config. +// +// At the moment, only one major indexing strategy is implemented (S2 cells). +type Config struct { + S2Geography *S2GeographyConfig `protobuf:"bytes,1,opt,name=s2_geography,json=s2Geography,proto3" json:"s2_geography,omitempty"` + S2Geometry *S2GeometryConfig `protobuf:"bytes,2,opt,name=s2_geometry,json=s2Geometry,proto3" json:"s2_geometry,omitempty"` +} + +func (m *Config) Reset() { *m = Config{} } +func (m *Config) String() string { return proto.CompactTextString(m) } +func (*Config) ProtoMessage() {} +func (*Config) Descriptor() ([]byte, []int) { + return fileDescriptor_6c5614d57d337886, []int{0} +} +func (m *Config) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Config) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *Config) XXX_Merge(src proto.Message) { + xxx_messageInfo_Config.Merge(m, src) +} +func (m *Config) XXX_Size() int { + return m.Size() +} +func (m *Config) XXX_DiscardUnknown() { + xxx_messageInfo_Config.DiscardUnknown(m) +} + +var xxx_messageInfo_Config proto.InternalMessageInfo + +// S2Config is the required information to tune one instance of an S2 cell +// backed geospatial index. For advanced users only -- the defaults should be +// good enough. +// +// TODO(sumeer): Based on experiments, reduce the knobs below by making the +// covering self-tuning. +type S2Config struct { + // MinLevel is the minimum cell level stored in the index. If left unset, it + // defaults to 0. + MinLevel int32 `protobuf:"varint,1,opt,name=min_level,json=minLevel,proto3" json:"min_level,omitempty"` + // MaxLevel is the maximum cell level stored in the index. If left unset, it + // defaults to 30. + MaxLevel int32 `protobuf:"varint,2,opt,name=max_level,json=maxLevel,proto3" json:"max_level,omitempty"` + // `MaxLevel-MinLevel` must be an exact multiple of LevelMod. If left unset, + // it defaults to 1. + LevelMod int32 `protobuf:"varint,3,opt,name=level_mod,json=levelMod,proto3" json:"level_mod,omitempty"` + // MaxCells is a soft hint for the maximum number of entries used to store a + // single geospatial object. If left unset, it defaults to 4. + MaxCells int32 `protobuf:"varint,4,opt,name=max_cells,json=maxCells,proto3" json:"max_cells,omitempty"` +} + +func (m *S2Config) Reset() { *m = S2Config{} } +func (m *S2Config) String() string { return proto.CompactTextString(m) } +func (*S2Config) ProtoMessage() {} +func (*S2Config) Descriptor() ([]byte, []int) { + return fileDescriptor_6c5614d57d337886, []int{1} +} +func (m *S2Config) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *S2Config) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *S2Config) XXX_Merge(src proto.Message) { + xxx_messageInfo_S2Config.Merge(m, src) +} +func (m *S2Config) XXX_Size() int { + return m.Size() +} +func (m *S2Config) XXX_DiscardUnknown() { + xxx_messageInfo_S2Config.DiscardUnknown(m) +} + +var xxx_messageInfo_S2Config proto.InternalMessageInfo + +type S2GeographyConfig struct { + S2Config *S2Config `protobuf:"bytes,1,opt,name=s2_config,json=s2Config,proto3" json:"s2_config,omitempty"` +} + +func (m *S2GeographyConfig) Reset() { *m = S2GeographyConfig{} } +func (m *S2GeographyConfig) String() string { return proto.CompactTextString(m) } +func (*S2GeographyConfig) ProtoMessage() {} +func (*S2GeographyConfig) Descriptor() ([]byte, []int) { + return fileDescriptor_6c5614d57d337886, []int{2} +} +func (m *S2GeographyConfig) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *S2GeographyConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *S2GeographyConfig) XXX_Merge(src proto.Message) { + xxx_messageInfo_S2GeographyConfig.Merge(m, src) +} +func (m *S2GeographyConfig) XXX_Size() int { + return m.Size() +} +func (m *S2GeographyConfig) XXX_DiscardUnknown() { + xxx_messageInfo_S2GeographyConfig.DiscardUnknown(m) +} + +var xxx_messageInfo_S2GeographyConfig proto.InternalMessageInfo + +type S2GeometryConfig struct { + // The rectangle bounds of the plane that will be efficiently indexed. Shapes + // should rarely exceed these bounds. + MinX float64 `protobuf:"fixed64,1,opt,name=min_x,json=minX,proto3" json:"min_x,omitempty"` + MaxX float64 `protobuf:"fixed64,2,opt,name=max_x,json=maxX,proto3" json:"max_x,omitempty"` + MinY float64 `protobuf:"fixed64,3,opt,name=min_y,json=minY,proto3" json:"min_y,omitempty"` + MaxY float64 `protobuf:"fixed64,4,opt,name=max_y,json=maxY,proto3" json:"max_y,omitempty"` + S2Config *S2Config `protobuf:"bytes,5,opt,name=s2_config,json=s2Config,proto3" json:"s2_config,omitempty"` +} + +func (m *S2GeometryConfig) Reset() { *m = S2GeometryConfig{} } +func (m *S2GeometryConfig) String() string { return proto.CompactTextString(m) } +func (*S2GeometryConfig) ProtoMessage() {} +func (*S2GeometryConfig) Descriptor() ([]byte, []int) { + return fileDescriptor_6c5614d57d337886, []int{3} +} +func (m *S2GeometryConfig) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *S2GeometryConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *S2GeometryConfig) XXX_Merge(src proto.Message) { + xxx_messageInfo_S2GeometryConfig.Merge(m, src) +} +func (m *S2GeometryConfig) XXX_Size() int { + return m.Size() +} +func (m *S2GeometryConfig) XXX_DiscardUnknown() { + xxx_messageInfo_S2GeometryConfig.DiscardUnknown(m) +} + +var xxx_messageInfo_S2GeometryConfig proto.InternalMessageInfo + +func init() { + proto.RegisterType((*Config)(nil), "cockroach.parser.geo.geoindex.Config") + proto.RegisterType((*S2Config)(nil), "cockroach.parser.geo.geoindex.S2Config") + proto.RegisterType((*S2GeographyConfig)(nil), "cockroach.parser.geo.geoindex.S2GeographyConfig") + proto.RegisterType((*S2GeometryConfig)(nil), "cockroach.parser.geo.geoindex.S2GeometryConfig") +} + +func init() { proto.RegisterFile("geo/geopb/config.proto", fileDescriptor_6c5614d57d337886) } + +var fileDescriptor_6c5614d57d337886 = []byte{ + // 394 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x52, 0xbd, 0x6e, 0xfa, 0x30, + 0x1c, 0x8c, 0xf9, 0x03, 0x0a, 0xe6, 0x3f, 0xb4, 0x69, 0x85, 0xa2, 0x56, 0x32, 0x88, 0x89, 0x2e, + 0x89, 0x94, 0x6e, 0x48, 0x5d, 0xca, 0x50, 0x55, 0xa2, 0x52, 0x05, 0x0b, 0x74, 0x89, 0xf2, 0xe1, + 0x9a, 0x88, 0x24, 0x8e, 0x12, 0x5a, 0x25, 0x7b, 0x1f, 0xa0, 0x8f, 0xc0, 0xce, 0x8b, 0x30, 0x32, + 0x32, 0xb6, 0x61, 0xe9, 0x63, 0x54, 0x71, 0x9c, 0xa0, 0x7e, 0x0e, 0x1d, 0x22, 0xfd, 0x7c, 0x77, + 0xbf, 0xd3, 0x9d, 0x63, 0xd8, 0x22, 0x98, 0xaa, 0x04, 0xd3, 0xc0, 0x54, 0x2d, 0xea, 0xdf, 0x3b, + 0x44, 0x09, 0x42, 0xba, 0xa0, 0x52, 0xcb, 0xa2, 0xd6, 0x3c, 0xa4, 0x86, 0x35, 0x53, 0x08, 0xa6, + 0xd9, 0xe7, 0xf8, 0x36, 0x8e, 0x4f, 0x8e, 0x09, 0x25, 0x94, 0x49, 0xd4, 0x6c, 0xca, 0xd5, 0xdd, + 0x15, 0x80, 0xf5, 0x01, 0x5b, 0x97, 0x86, 0xf0, 0x7f, 0xa4, 0xe9, 0x04, 0x53, 0x12, 0x1a, 0xc1, + 0x2c, 0x91, 0x41, 0x07, 0xf4, 0x9a, 0xda, 0x99, 0xf2, 0xbd, 0x9f, 0x32, 0xd6, 0xae, 0x0a, 0x69, + 0x6e, 0x30, 0x6a, 0x46, 0x7b, 0x48, 0xba, 0x86, 0xcd, 0xdc, 0xcd, 0xc3, 0x8b, 0x30, 0x91, 0x2b, + 0xcc, 0xac, 0xf7, 0xab, 0x19, 0x53, 0x72, 0x2f, 0x18, 0x95, 0x48, 0x5f, 0x5c, 0x2f, 0xdb, 0xe0, + 0x6d, 0xd9, 0x06, 0xdd, 0x27, 0x00, 0xc5, 0xb1, 0xc6, 0xf3, 0x9e, 0xc2, 0x86, 0xe7, 0xf8, 0xba, + 0x8b, 0x1f, 0xb1, 0xcb, 0xc2, 0xd6, 0x46, 0xa2, 0xe7, 0xf8, 0xc3, 0xec, 0xcc, 0x48, 0x23, 0xe6, + 0x64, 0x85, 0x93, 0x46, 0x5c, 0x92, 0x8c, 0xd0, 0x3d, 0x6a, 0xcb, 0xff, 0x72, 0x92, 0x01, 0x37, + 0xd4, 0x2e, 0x36, 0x2d, 0xec, 0xba, 0x91, 0x5c, 0x2d, 0x37, 0x07, 0xd9, 0xb9, 0x5f, 0x65, 0x31, + 0x26, 0xf0, 0xf0, 0x4b, 0x7b, 0xe9, 0x02, 0x36, 0x22, 0x4d, 0xcf, 0x7f, 0x05, 0xbf, 0xbb, 0xce, + 0xcf, 0x75, 0x79, 0x4d, 0x31, 0xe2, 0x13, 0x77, 0x5e, 0x01, 0x78, 0xf0, 0xf9, 0x2e, 0xa4, 0x23, + 0x58, 0xcb, 0x8a, 0xc6, 0xcc, 0x15, 0x8c, 0xaa, 0x9e, 0xe3, 0x4f, 0x18, 0x68, 0xc4, 0x7a, 0xcc, + 0xca, 0x65, 0xa0, 0x11, 0x4f, 0x0a, 0x65, 0xc2, 0x4a, 0xe5, 0xca, 0x69, 0xa1, 0x4c, 0x58, 0x99, + 0x5c, 0x39, 0xfd, 0x98, 0xb6, 0xf6, 0xb7, 0xb4, 0x97, 0xb7, 0xeb, 0x57, 0x24, 0xac, 0x53, 0x04, + 0x36, 0x29, 0x02, 0xdb, 0x14, 0x81, 0x97, 0x14, 0x81, 0xe7, 0x1d, 0x12, 0x36, 0x3b, 0x24, 0x6c, + 0x77, 0x48, 0xb8, 0x53, 0x88, 0xb3, 0x98, 0x3d, 0x98, 0x8a, 0x45, 0x3d, 0xb5, 0x74, 0xb7, 0xcd, + 0xfd, 0xac, 0x06, 0x73, 0xa2, 0x96, 0x2f, 0xd9, 0xac, 0xb3, 0x57, 0x79, 0xfe, 0x1e, 0x00, 0x00, + 0xff, 0xff, 0x1e, 0xdc, 0x45, 0x29, 0xdd, 0x02, 0x00, 0x00, +} + +func (this *Config) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*Config) + if !ok { + that2, ok := that.(Config) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if !this.S2Geography.Equal(that1.S2Geography) { + return false + } + if !this.S2Geometry.Equal(that1.S2Geometry) { + return false + } + return true +} +func (this *S2Config) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*S2Config) + if !ok { + that2, ok := that.(S2Config) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.MinLevel != that1.MinLevel { + return false + } + if this.MaxLevel != that1.MaxLevel { + return false + } + if this.LevelMod != that1.LevelMod { + return false + } + if this.MaxCells != that1.MaxCells { + return false + } + return true +} +func (this *S2GeographyConfig) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*S2GeographyConfig) + if !ok { + that2, ok := that.(S2GeographyConfig) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if !this.S2Config.Equal(that1.S2Config) { + return false + } + return true +} +func (this *S2GeometryConfig) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*S2GeometryConfig) + if !ok { + that2, ok := that.(S2GeometryConfig) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.MinX != that1.MinX { + return false + } + if this.MaxX != that1.MaxX { + return false + } + if this.MinY != that1.MinY { + return false + } + if this.MaxY != that1.MaxY { + return false + } + if !this.S2Config.Equal(that1.S2Config) { + return false + } + return true +} +func (m *Config) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Config) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Config) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.S2Geometry != nil { + { + size, err := m.S2Geometry.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintConfig(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if m.S2Geography != nil { + { + size, err := m.S2Geography.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintConfig(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *S2Config) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *S2Config) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *S2Config) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.MaxCells != 0 { + i = encodeVarintConfig(dAtA, i, uint64(m.MaxCells)) + i-- + dAtA[i] = 0x20 + } + if m.LevelMod != 0 { + i = encodeVarintConfig(dAtA, i, uint64(m.LevelMod)) + i-- + dAtA[i] = 0x18 + } + if m.MaxLevel != 0 { + i = encodeVarintConfig(dAtA, i, uint64(m.MaxLevel)) + i-- + dAtA[i] = 0x10 + } + if m.MinLevel != 0 { + i = encodeVarintConfig(dAtA, i, uint64(m.MinLevel)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *S2GeographyConfig) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *S2GeographyConfig) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *S2GeographyConfig) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.S2Config != nil { + { + size, err := m.S2Config.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintConfig(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *S2GeometryConfig) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *S2GeometryConfig) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *S2GeometryConfig) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.S2Config != nil { + { + size, err := m.S2Config.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintConfig(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + if m.MaxY != 0 { + i -= 8 + encoding_binary.LittleEndian.PutUint64(dAtA[i:], uint64(math.Float64bits(float64(m.MaxY)))) + i-- + dAtA[i] = 0x21 + } + if m.MinY != 0 { + i -= 8 + encoding_binary.LittleEndian.PutUint64(dAtA[i:], uint64(math.Float64bits(float64(m.MinY)))) + i-- + dAtA[i] = 0x19 + } + if m.MaxX != 0 { + i -= 8 + encoding_binary.LittleEndian.PutUint64(dAtA[i:], uint64(math.Float64bits(float64(m.MaxX)))) + i-- + dAtA[i] = 0x11 + } + if m.MinX != 0 { + i -= 8 + encoding_binary.LittleEndian.PutUint64(dAtA[i:], uint64(math.Float64bits(float64(m.MinX)))) + i-- + dAtA[i] = 0x9 + } + return len(dAtA) - i, nil +} + +func encodeVarintConfig(dAtA []byte, offset int, v uint64) int { + offset -= sovConfig(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Config) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.S2Geography != nil { + l = m.S2Geography.Size() + n += 1 + l + sovConfig(uint64(l)) + } + if m.S2Geometry != nil { + l = m.S2Geometry.Size() + n += 1 + l + sovConfig(uint64(l)) + } + return n +} + +func (m *S2Config) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.MinLevel != 0 { + n += 1 + sovConfig(uint64(m.MinLevel)) + } + if m.MaxLevel != 0 { + n += 1 + sovConfig(uint64(m.MaxLevel)) + } + if m.LevelMod != 0 { + n += 1 + sovConfig(uint64(m.LevelMod)) + } + if m.MaxCells != 0 { + n += 1 + sovConfig(uint64(m.MaxCells)) + } + return n +} + +func (m *S2GeographyConfig) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.S2Config != nil { + l = m.S2Config.Size() + n += 1 + l + sovConfig(uint64(l)) + } + return n +} + +func (m *S2GeometryConfig) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.MinX != 0 { + n += 9 + } + if m.MaxX != 0 { + n += 9 + } + if m.MinY != 0 { + n += 9 + } + if m.MaxY != 0 { + n += 9 + } + if m.S2Config != nil { + l = m.S2Config.Size() + n += 1 + l + sovConfig(uint64(l)) + } + return n +} + +func sovConfig(x uint64) (n int) { + return int((uint32(math_bits.Len64(x|1)+6) * 37) >> 8) +} +func sozConfig(x uint64) (n int) { + return sovConfig(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (this *Config) GetValue() interface{} { + if this.S2Geography != nil { + return this.S2Geography + } + if this.S2Geometry != nil { + return this.S2Geometry + } + return nil +} + +func (this *Config) SetValue(value interface{}) bool { + switch vt := value.(type) { + case *S2GeographyConfig: + this.S2Geography = vt + case *S2GeometryConfig: + this.S2Geometry = vt + default: + return false + } + return true +} +func (m *Config) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowConfig + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Config: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Config: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field S2Geography", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowConfig + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthConfig + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthConfig + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.S2Geography == nil { + m.S2Geography = &S2GeographyConfig{} + } + if err := m.S2Geography.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field S2Geometry", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowConfig + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthConfig + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthConfig + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.S2Geometry == nil { + m.S2Geometry = &S2GeometryConfig{} + } + if err := m.S2Geometry.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipConfig(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthConfig + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *S2Config) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowConfig + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: S2Config: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: S2Config: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MinLevel", wireType) + } + m.MinLevel = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowConfig + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MinLevel |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxLevel", wireType) + } + m.MaxLevel = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowConfig + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MaxLevel |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field LevelMod", wireType) + } + m.LevelMod = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowConfig + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.LevelMod |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxCells", wireType) + } + m.MaxCells = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowConfig + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MaxCells |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipConfig(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthConfig + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *S2GeographyConfig) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowConfig + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: S2GeographyConfig: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: S2GeographyConfig: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field S2Config", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowConfig + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthConfig + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthConfig + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.S2Config == nil { + m.S2Config = &S2Config{} + } + if err := m.S2Config.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipConfig(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthConfig + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *S2GeometryConfig) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowConfig + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: S2GeometryConfig: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: S2GeometryConfig: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 1 { + return fmt.Errorf("proto: wrong wireType = %d for field MinX", wireType) + } + var v uint64 + if (iNdEx + 8) > l { + return io.ErrUnexpectedEOF + } + v = uint64(encoding_binary.LittleEndian.Uint64(dAtA[iNdEx:])) + iNdEx += 8 + m.MinX = float64(math.Float64frombits(v)) + case 2: + if wireType != 1 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxX", wireType) + } + var v uint64 + if (iNdEx + 8) > l { + return io.ErrUnexpectedEOF + } + v = uint64(encoding_binary.LittleEndian.Uint64(dAtA[iNdEx:])) + iNdEx += 8 + m.MaxX = float64(math.Float64frombits(v)) + case 3: + if wireType != 1 { + return fmt.Errorf("proto: wrong wireType = %d for field MinY", wireType) + } + var v uint64 + if (iNdEx + 8) > l { + return io.ErrUnexpectedEOF + } + v = uint64(encoding_binary.LittleEndian.Uint64(dAtA[iNdEx:])) + iNdEx += 8 + m.MinY = float64(math.Float64frombits(v)) + case 4: + if wireType != 1 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxY", wireType) + } + var v uint64 + if (iNdEx + 8) > l { + return io.ErrUnexpectedEOF + } + v = uint64(encoding_binary.LittleEndian.Uint64(dAtA[iNdEx:])) + iNdEx += 8 + m.MaxY = float64(math.Float64frombits(v)) + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field S2Config", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowConfig + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthConfig + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthConfig + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.S2Config == nil { + m.S2Config = &S2Config{} + } + if err := m.S2Config.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipConfig(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthConfig + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipConfig(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowConfig + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowConfig + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowConfig + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthConfig + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupConfig + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthConfig + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthConfig = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowConfig = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupConfig = fmt.Errorf("proto: unexpected end of group") +) + diff --git a/pkg/geo/geopb/config.proto b/pkg/geo/geopb/config.proto new file mode 100644 index 0000000..ababb1e --- /dev/null +++ b/pkg/geo/geopb/config.proto @@ -0,0 +1,60 @@ +// Copyright 2020 The Cockroach Authors. +// +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. + +syntax = "proto3"; +package cockroach.geo.geoindex; +option go_package = "github.com/cockroachdb/cockroach/pkg/geo/geopb"; + +import "gogoproto/gogo.proto"; + +// Config is the information used to tune one instance of a geospatial index. +// Each SQL index will have its own config. +// +// At the moment, only one major indexing strategy is implemented (S2 cells). +message Config { + option (gogoproto.equal) = true; + option (gogoproto.onlyone) = true; + S2GeographyConfig s2_geography = 1; + S2GeometryConfig s2_geometry = 2; +} + +// S2Config is the required information to tune one instance of an S2 cell +// backed geospatial index. For advanced users only -- the defaults should be +// good enough. +// +// TODO(sumeer): Based on experiments, reduce the knobs below by making the +// covering self-tuning. +message S2Config { + option (gogoproto.equal) = true; + // MinLevel is the minimum cell level stored in the index. If left unset, it + // defaults to 0. + int32 min_level = 1; + // MaxLevel is the maximum cell level stored in the index. If left unset, it + // defaults to 30. + int32 max_level = 2; + // `MaxLevel-MinLevel` must be an exact multiple of LevelMod. If left unset, + // it defaults to 1. + int32 level_mod = 3; + // MaxCells is a soft hint for the maximum number of entries used to store a + // single geospatial object. If left unset, it defaults to 4. + int32 max_cells = 4; +} + +message S2GeographyConfig { + option (gogoproto.equal) = true; + S2Config s2_config = 1; +} + +message S2GeometryConfig { + option (gogoproto.equal) = true; + // The rectangle bounds of the plane that will be efficiently indexed. Shapes + // should rarely exceed these bounds. + double min_x = 1; + double max_x = 2; + double min_y = 3; + double max_y = 4; + + S2Config s2_config = 5; +} diff --git a/pkg/geo/geopb/geopb.go b/pkg/geo/geopb/geopb.go index 3c70bd6..319d88b 100644 --- a/pkg/geo/geopb/geopb.go +++ b/pkg/geo/geopb/geopb.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package geopb @@ -20,13 +15,19 @@ func (b *SpatialObject) EWKBHex() string { return fmt.Sprintf("%X", b.EWKB) } -// MemSize returns the size of the spatial object in memory. -func (b *SpatialObject) MemSize() uintptr { +// MemSize returns the size of the spatial object in memory. If deterministic is +// true, then only length of EWKB slice is included - this option should only be +// used when determinism is favored over precision. +func (b *SpatialObject) MemSize(deterministic bool) uintptr { var bboxSize uintptr if bbox := b.BoundingBox; bbox != nil { bboxSize = unsafe.Sizeof(*bbox) } - return unsafe.Sizeof(*b) + bboxSize + uintptr(len(b.EWKB)) + ewkbSize := uintptr(cap(b.EWKB)) + if deterministic { + ewkbSize = uintptr(len(b.EWKB)) + } + return unsafe.Sizeof(*b) + bboxSize + ewkbSize } // MultiType returns the corresponding multi-type for a shape type, or unset diff --git a/pkg/geo/geopb/geopb.pb.go b/pkg/geo/geopb/geopb.pb.go index 0d22387..3e55211 100644 --- a/pkg/geo/geopb/geopb.pb.go +++ b/pkg/geo/geopb/geopb.pb.go @@ -480,7 +480,7 @@ func (m *BoundingBox) Size() (n int) { } func sovGeopb(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 + return int((uint32(math_bits.Len64(x|1)+6) * 37) >> 8) } func sozGeopb(x uint64) (n int) { return sovGeopb(uint64((x << 1) ^ uint64((int64(x) >> 63)))) diff --git a/pkg/geo/geopb/geopb.proto b/pkg/geo/geopb/geopb.proto index 7e04df7..d98f41d 100644 --- a/pkg/geo/geopb/geopb.proto +++ b/pkg/geo/geopb/geopb.proto @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. syntax = "proto3"; package cockroach.geopb; diff --git a/pkg/geo/geopb/types.go b/pkg/geo/geopb/types.go index f9f0f41..33b3718 100644 --- a/pkg/geo/geopb/types.go +++ b/pkg/geo/geopb/types.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package geopb diff --git a/pkg/geo/geoprojbase/embeddedproj/embedded_proj.go b/pkg/geo/geoprojbase/embeddedproj/embedded_proj.go index 172b28f..77a3d19 100644 --- a/pkg/geo/geoprojbase/embeddedproj/embedded_proj.go +++ b/pkg/geo/geoprojbase/embeddedproj/embedded_proj.go @@ -1,12 +1,7 @@ // Copyright 2021 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. // Package embeddedproj defines the format used to embed static projection data // in the Cockroach binary. Is is used to load the data as well as to generate diff --git a/pkg/geo/geoprojbase/geoprojbase.go b/pkg/geo/geoprojbase/geoprojbase.go index 5219fdc..1bc59ad 100644 --- a/pkg/geo/geoprojbase/geoprojbase.go +++ b/pkg/geo/geoprojbase/geoprojbase.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. // Package geoprojbase is a minimal dependency package that contains // basic metadata and data structures for SRIDs and their CRS diff --git a/pkg/geo/geoprojbase/projections.go b/pkg/geo/geoprojbase/projections.go index bb9b182..db6442f 100644 --- a/pkg/geo/geoprojbase/projections.go +++ b/pkg/geo/geoprojbase/projections.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. // This file was generated from `./pkg/cmd/generate-spatial-ref-sys`. diff --git a/pkg/geo/hilbert.go b/pkg/geo/hilbert.go index 1c4d015..1cf8f32d 100644 --- a/pkg/geo/hilbert.go +++ b/pkg/geo/hilbert.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package geo diff --git a/pkg/geo/iterator.go b/pkg/geo/iterator.go index 65a06db..37411cb 100644 --- a/pkg/geo/iterator.go +++ b/pkg/geo/iterator.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package geo diff --git a/pkg/geo/latlng.go b/pkg/geo/latlng.go index d71e0d8..5ac4d22 100644 --- a/pkg/geo/latlng.go +++ b/pkg/geo/latlng.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package geo diff --git a/pkg/geo/parse.go b/pkg/geo/parse.go index 041ff44..66105d0 100644 --- a/pkg/geo/parse.go +++ b/pkg/geo/parse.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package geo diff --git a/pkg/geo/polyline.go b/pkg/geo/polyline.go index c5bd243..212c1c9 100644 --- a/pkg/geo/polyline.go +++ b/pkg/geo/polyline.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package geo diff --git a/pkg/geo/summary.go b/pkg/geo/summary.go index 5265b7b..e0c234d 100644 --- a/pkg/geo/summary.go +++ b/pkg/geo/summary.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package geo diff --git a/pkg/keysbase/data.go b/pkg/keysbase/data.go index f7f2de9..dc5fa7e 100644 --- a/pkg/keysbase/data.go +++ b/pkg/keysbase/data.go @@ -1,12 +1,7 @@ // Copyright 2022 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package keysbase diff --git a/pkg/kv/kvserver/concurrency/isolation/levels.go b/pkg/kv/kvserver/concurrency/isolation/levels.go index 8c43c28..d563890 100644 --- a/pkg/kv/kvserver/concurrency/isolation/levels.go +++ b/pkg/kv/kvserver/concurrency/isolation/levels.go @@ -1,12 +1,7 @@ // Copyright 2023 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. // Package isolation provides type definitions for isolation level-related // concepts used by concurrency control in the key-value layer. diff --git a/pkg/kv/kvserver/concurrency/isolation/levels.proto b/pkg/kv/kvserver/concurrency/isolation/levels.proto index cfc6eb7..a6e49cc 100644 --- a/pkg/kv/kvserver/concurrency/isolation/levels.proto +++ b/pkg/kv/kvserver/concurrency/isolation/levels.proto @@ -1,12 +1,7 @@ // Copyright 2023 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. syntax = "proto3"; package cockroach.kv.kvserver.concurrency.isolation; diff --git a/pkg/security/username/username.go b/pkg/security/username/username.go index 8584296..0edcdba 100644 --- a/pkg/security/username/username.go +++ b/pkg/security/username/username.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package username diff --git a/pkg/settings/bool.go b/pkg/settings/bool.go new file mode 100644 index 0000000..83ab3fd --- /dev/null +++ b/pkg/settings/bool.go @@ -0,0 +1,160 @@ +// Copyright 2017 The Cockroach Authors. +// +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. + +package settings + +import ( + "context" + "strconv" + + "github.com/cockroachdb/errors" +) + +// BoolSetting is the interface of a setting variable that will be +// updated automatically when the corresponding cluster-wide setting +// of type "bool" is updated. +type BoolSetting struct { + common + defaultValue bool + validateFn func(*Values, bool) error +} + +var _ internalSetting = &BoolSetting{} + +// Get retrieves the bool value in the setting. +func (b *BoolSetting) Get(sv *Values) bool { + return sv.getInt64(b.slot) != 0 +} + +func (b *BoolSetting) String(sv *Values) string { + return EncodeBool(b.Get(sv)) +} + +// DefaultString returns the default value for the setting as a string. +func (b *BoolSetting) DefaultString() string { + return EncodeBool(b.defaultValue) +} + +// Encoded returns the encoded value of the current value of the setting. +func (b *BoolSetting) Encoded(sv *Values) string { + return b.String(sv) +} + +// EncodedDefault returns the encoded value of the default value of the setting. +func (b *BoolSetting) EncodedDefault() string { + return EncodeBool(b.defaultValue) +} + +// DecodeToString decodes and renders an encoded value. +func (b *BoolSetting) DecodeToString(encoded string) (string, error) { + bv, err := b.DecodeValue(encoded) + if err != nil { + return "", err + } + return EncodeBool(bv), nil +} + +// DecodeValue decodes the value into a float. +func (b *BoolSetting) DecodeValue(encoded string) (bool, error) { + return strconv.ParseBool(encoded) +} + +// Typ returns the short (1 char) string denoting the type of setting. +func (*BoolSetting) Typ() string { + return "b" +} + +// Default returns default value for setting. +func (b *BoolSetting) Default() bool { + return b.defaultValue +} + +// Defeat the linter. +var _ = (*BoolSetting).Default + +// Override changes the setting without validation and also overrides the +// default value. +// +// For testing usage only. +func (b *BoolSetting) Override(ctx context.Context, sv *Values, v bool) { + sv.setValueOrigin(ctx, b.slot, OriginOverride) + b.set(ctx, sv, v) + sv.setDefaultOverride(b.slot, v) +} + +// Validate that a value conforms with the validation function. +func (b *BoolSetting) Validate(sv *Values, v bool) error { + if b.validateFn != nil { + if err := b.validateFn(sv, v); err != nil { + return err + } + } + return nil +} + +func (b *BoolSetting) set(ctx context.Context, sv *Values, v bool) { + vInt := int64(0) + if v { + vInt = 1 + } + sv.setInt64(ctx, b.slot, vInt) +} + +func (b *BoolSetting) decodeAndSet(ctx context.Context, sv *Values, encoded string) error { + v, err := strconv.ParseBool(encoded) + if err := b.Validate(sv, v); err != nil { + return err + } + if err != nil { + return err + } + b.set(ctx, sv, v) + return nil +} + +func (b *BoolSetting) decodeAndSetDefaultOverride( + ctx context.Context, sv *Values, encoded string, +) error { + v, err := strconv.ParseBool(encoded) + if err != nil { + return err + } + sv.setDefaultOverride(b.slot, v) + return nil +} + +func (b *BoolSetting) setToDefault(ctx context.Context, sv *Values) { + // See if the default value was overridden. + if val := sv.getDefaultOverride(b.slot); val != nil { + b.set(ctx, sv, val.(bool)) + return + } + b.set(ctx, sv, b.defaultValue) +} + +// RegisterBoolSetting defines a new setting with type bool. +func RegisterBoolSetting( + class Class, key InternalKey, desc string, defaultValue bool, opts ...SettingOption, +) *BoolSetting { + validateFn := func(sv *Values, val bool) error { + for _, opt := range opts { + switch { + case opt.commonOpt != nil: + continue + case opt.validateBoolFn != nil: + default: + panic(errors.AssertionFailedf("wrong validator type")) + } + if err := opt.validateBoolFn(sv, val); err != nil { + return err + } + } + return nil + } + setting := &BoolSetting{defaultValue: defaultValue, validateFn: validateFn} + register(class, key, desc, setting) + setting.apply(opts) + return setting +} diff --git a/pkg/settings/byte_size.go b/pkg/settings/byte_size.go new file mode 100644 index 0000000..093e6e3 --- /dev/null +++ b/pkg/settings/byte_size.go @@ -0,0 +1,94 @@ +// Copyright 2017 The Cockroach Authors. +// +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. + +package settings + +import ( + "github.com/cockroachdb/cockroachdb-parser/pkg/util/humanizeutil" + "github.com/cockroachdb/errors" +) + +// ByteSizeSetting is the interface of a setting variable that will be +// updated automatically when the corresponding cluster-wide setting +// of type "bytesize" is updated. +type ByteSizeSetting struct { + IntSetting +} + +var _ internalSetting = &ByteSizeSetting{} + +// Typ returns the short (1 char) string denoting the type of setting. +func (*ByteSizeSetting) Typ() string { + return "z" +} + +func (b *ByteSizeSetting) String(sv *Values) string { + return string(humanizeutil.IBytes(b.Get(sv))) +} + +// DefaultString returns the default value for the setting as a string. +func (b *ByteSizeSetting) DefaultString() string { + return string(humanizeutil.IBytes(b.defaultValue)) +} + +// DecodeToString decodes and renders an encoded value. +func (b *ByteSizeSetting) DecodeToString(encoded string) (string, error) { + iv, err := b.DecodeNumericValue(encoded) + if err != nil { + return "", err + } + return string(humanizeutil.IBytes(iv)), nil +} + +// RegisterByteSizeSetting defines a new setting with type bytesize and any +// supplied validation function(s). If no validation functions are given, then +// the non-negative int validation is performed. +func RegisterByteSizeSetting( + class Class, key InternalKey, desc string, defaultValue int64, opts ...SettingOption, +) *ByteSizeSetting { + validateFn := func(v int64) error { + hasExplicitValidationFn := false + for _, opt := range opts { + switch { + case opt.commonOpt != nil: + continue + case opt.validateInt64Fn != nil: + default: + panic(errors.AssertionFailedf("wrong validator type")) + } + hasExplicitValidationFn = true + if err := opt.validateInt64Fn(v); err != nil { + return errors.Wrapf(err, "invalid value for %s", key) + } + } + if !hasExplicitValidationFn { + // Default validation. + return nonNegativeIntInternal(v) + } + return nil + } + + if err := validateFn(defaultValue); err != nil { + panic(errors.Wrap(err, "invalid default")) + } + setting := &ByteSizeSetting{IntSetting{ + defaultValue: defaultValue, + validateFn: validateFn, + }} + register(class, key, desc, setting) + setting.apply(opts) + return setting +} + +// ByteSizeWithMinimum can be passed to RegisterByteSizeSetting. +func ByteSizeWithMinimum(minVal int64) SettingOption { + return WithValidateInt(func(v int64) error { + if v < minVal { + return errors.Errorf("cannot be set to a value lower than %v", + humanizeutil.IBytes(minVal)) + } + return nil + }) +} diff --git a/pkg/settings/common.go b/pkg/settings/common.go new file mode 100644 index 0000000..52343a6 --- /dev/null +++ b/pkg/settings/common.go @@ -0,0 +1,193 @@ +// Copyright 2021 The Cockroach Authors. +// +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. + +package settings + +import ( + "context" + "fmt" + + "github.com/cockroachdb/errors" +) + +// common implements basic functionality used by all setting types. +type common struct { + class Class + key InternalKey + name SettingName + description string + visibility Visibility + unsafe bool + slot slotIdx + nonReportable bool + retired bool + sensitive bool +} + +// slotIdx is an integer in the range [0, MaxSetting) which is uniquely +// associated with a registered setting. Slot indexes are used as "handles" for +// manipulating the setting values. They are generated sequentially, in the +// order of registration. +type slotIdx int32 + +// init must be called to initialize the fields that don't have defaults. +func (c *common) init(class Class, key InternalKey, description string, slot slotIdx) { + c.class = class + c.key = key + c.name = SettingName(key) // until overridden + c.description = description + if slot < 0 { + panic(fmt.Sprintf("Invalid slot index %d", slot)) + } + if slot >= MaxSettings { + panic("too many settings; increase MaxSettings") + } + c.slot = slot +} + +func (c common) Class() Class { + return c.class +} + +func (c common) InternalKey() InternalKey { + return c.key +} + +func (c common) Name() SettingName { + return c.name +} + +func (c common) Description() string { + return c.description +} + +func (c common) Visibility() Visibility { + return c.visibility +} + +func (c common) isReportable() bool { + return !c.nonReportable +} + +func (c *common) isRetired() bool { + return c.retired +} + +func (c *common) isSensitive() bool { + return c.sensitive +} + +func (c *common) ErrorHint() (bool, string) { + return false, "" +} + +func (c *common) getSlot() slotIdx { + return c.slot +} + +// ValueOrigin returns the origin of the current value of the setting. +func (c *common) ValueOrigin(ctx context.Context, sv *Values) ValueOrigin { + return sv.getValueOrigin(ctx, c.slot) +} + +// setReportable configures the reportability. +// Refer to the WithReportable option for details. +func (c *common) setReportable(reportable bool) { + c.nonReportable = !reportable +} + +// setVisibility customizes the visibility of a setting. +// Refer to the WithVisibility option for details. +func (c *common) setVisibility(v Visibility) { + c.visibility = v +} + +// setRetired marks the setting as obsolete. It also hides +// it from the output of SHOW CLUSTER SETTINGS. +func (c *common) setRetired() { + c.description = "do not use - " + c.description + c.retired = true +} + +// setSensitive marks the setting as sensitive, which means that it will always +// be redacted in any output. It also makes the setting non-reportable. +func (c *common) setSensitive() { + c.sensitive = true + c.nonReportable = true +} + +// setName is used to override the name of the setting. +// Refer to the WithName option for details. +func (c *common) setName(name SettingName) { + if c.name != SettingName(c.key) { + panic(errors.AssertionFailedf("duplicate use of WithName")) + } + c.name = name +} + +// setUnsafe is used to override the unsafe status of the setting. +// Refer to the WithUnsafe option for details. +func (c *common) setUnsafe() { + c.unsafe = true +} + +// IsUnsafe indicates whether the setting is unsafe. +func (c *common) IsUnsafe() bool { + return c.unsafe +} + +// SetOnChange installs a callback to be called when a setting's value changes. +// `fn` should avoid doing long-running or blocking work as it is called on the +// goroutine which handles all settings updates. +func (c *common) SetOnChange(sv *Values, fn func(ctx context.Context)) { + sv.setOnChange(c.slot, fn) +} + +type internalSetting interface { + NonMaskedSetting + + init(class Class, key InternalKey, description string, slot slotIdx) + isRetired() bool + isSensitive() bool + getSlot() slotIdx + + // isReportable indicates whether the value of the setting can be + // included in user-facing reports such as that produced by SHOW ALL + // CLUSTER SETTINGS. + // This only affects reports though; direct access is unconstrained. + // For example, `enterprise.license` is non-reportable: + // it cannot be listed, but can be accessed with `SHOW CLUSTER + // SETTING enterprise.license` or SET CLUSTER SETTING. + isReportable() bool + + setToDefault(ctx context.Context, sv *Values) + + // decodeAndSet sets the setting after decoding the encoded value. + decodeAndSet(ctx context.Context, sv *Values, encoded string) error + + // decodeAndOverrideDefault overrides the default value for the respective + // setting to newVal. It does not change the current value. Validation checks + // are not run against the decoded value. + decodeAndSetDefaultOverride(ctx context.Context, sv *Values, encoded string) error +} + +// TestingIsReportable is used in testing for reportability. +func TestingIsReportable(s Setting) bool { + if _, ok := s.(*MaskedSetting); ok { + return false + } + if e, ok := s.(internalSetting); ok { + return e.isReportable() + } + return true +} + +// TestingIsSensitive is used in testing for sensitivity. +func TestingIsSensitive(s Setting) bool { + if e, ok := s.(internalSetting); ok { + return e.isSensitive() + } + return false +} diff --git a/pkg/settings/doc.go b/pkg/settings/doc.go new file mode 100644 index 0000000..807770c --- /dev/null +++ b/pkg/settings/doc.go @@ -0,0 +1,110 @@ +// Copyright 2017 The Cockroach Authors. +// +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. + +/* +Package settings provides a central registry of runtime editable settings and +accompanying helper functions for retrieving their current values. + +# Overview + +Settings values are stored in the system.settings table. A +rangefeed-driven worker updates the cached value when the table +changes (see package 'settingswatcher'). + +To add a new setting, call one of the `Register` methods in `registry.go` and +save the accessor created by the register function in the package where the +setting is to be used. For example, to add an "enterprise" flag, adding into +license_check.go: + + var enterpriseEnabled = settings.RegisterBoolSetting( + settings.ApplicationLevel, + "enterprise.enabled", + "some doc for the setting", + false, + ) + +Then use with `if enterpriseEnabled.Get(...) ...` + +# Setting names + +Settings have both a "key" and a "name". + +The key is what is used to persist the value and synchronize it across +nodes. The key should remain immutable through the lifetime of the +setting. This is the main argument passed through the Register() calls. + +The name is what end-users see in docs and can use via the SQL +statements SET/SHOW CLUSTER SETTING. It can change over time. It is +also subject to a linter; for example boolean settings should have a +name ending with '.enabled'. + +When no name is specified, it defaults to the key. Another name +can be specified using `WithName()`, for example: + + var mySetting = settings.RegisterBoolSetting( + "mykey", ..., + settings.WithName("descriptive.name.enabled"), + ) + +For convenience, users can also refer to a setting using its key +in the SET/SHOW CLUSTER SETTING statements. Because of this, +the keys and names are in the same namespace and cannot overlap. + +# Careful choice of default values, value propagation delay + +Settings should always be defined with "safe" default values -- until a node +receives values asynchronously, or even after that, if it cannot read them for some +reason, it will use the default values, so define defaults that "fail safe". + +In cases where the "safe" default doesn't actually match the desired default, +like respecting an opt-*out* setting, we can default to `false` (opted out) and +then use a migration to write an explicit `true`: in practice you'd still expect +to read `true` unless a preference is expressed, but in the rare cases where you +read a default, you don't risk ignoring an expressed opt-out. + +Ideally, when passing configuration into some structure or subsystem, e.g. a +rate limit into a client or something, passing a `*FooSetting` rather than a +`Foo` and waiting to call `.Get()` until the value is actually used ensures +observing the latest value. + +# Changing names of settings + +Sometimes for UX or documentation purposes it is useful to rename a setting. +However, to preserve backward-compatibility, its key cannot change. + +There are two situations possible: + + - The setting currently has the same name as its key. To rename the setting, + use the `WithName()` option. + + - The setting already has another name than its key. In this case, + modify the name in the `WithName()` option and also add a + `WithRetiredName()` option with the previous name. A SQL notice + will redirect users to the new name. + +# Retiring settings + +Settings may become irrelevant over time, especially when introduced to provide +a workaround to a system limitation which is later corrected. There are two +possible scenarios: + + - The setting may still be referred to from automation (e.g. external + scripts). In this case, use the option `settings.Retired` at the + registration point. + + - The setting will not ever be reused anywhere and can be deleted. + When deleting a setting's registration from the codebase, add its + name to the list of `retiredSettings` in settings/registry.go -- + this ensures the name cannot be accidentally reused, and suppresses + log spam about the existing value. + +The list of deleted+retired settings can periodically (i.e. in major versions) be +"flushed" by adding a migration that deletes all stored values for those keys +at which point the key would be available for reuse in a later version. Is is +only safe to run such a migration after the cluster upgrade process ensures no +older nodes are still using the values for those old settings though, so such a +migration needs to be version gated. +*/ +package settings diff --git a/pkg/settings/duration.go b/pkg/settings/duration.go new file mode 100644 index 0000000..4c5e1d8 --- /dev/null +++ b/pkg/settings/duration.go @@ -0,0 +1,286 @@ +// Copyright 2017 The Cockroach Authors. +// +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. + +package settings + +import ( + "context" + "time" + + "github.com/cockroachdb/errors" +) + +// DurationSetting is the interface of a setting variable that will be +// updated automatically when the corresponding cluster-wide setting +// of type "duration" is updated. +type DurationSetting struct { + common + defaultValue time.Duration + validateFn func(time.Duration) error +} + +// DurationSettingWithExplicitUnit is like DurationSetting except it requires an +// explicit unit when being set. (eg. 1s works, but 1 does not). +type DurationSettingWithExplicitUnit struct { + DurationSetting +} + +var _ internalSetting = &DurationSetting{} + +var _ internalSetting = &DurationSettingWithExplicitUnit{} + +// ErrorHint returns a hint message to be displayed on error to the user. +func (d *DurationSettingWithExplicitUnit) ErrorHint() (bool, string) { + return true, "try using an interval value with explicit units, e.g 500ms or 1h2m" +} + +// Get retrieves the duration value in the setting. +func (d *DurationSetting) Get(sv *Values) time.Duration { + return time.Duration(sv.getInt64(d.slot)) +} + +func (d *DurationSetting) String(sv *Values) string { + return EncodeDuration(d.Get(sv)) +} + +// DefaultString returns the default value for the setting as a string. +func (d *DurationSetting) DefaultString() string { + return EncodeDuration(d.defaultValue) +} + +// Encoded returns the encoded value of the current value of the setting. +func (d *DurationSetting) Encoded(sv *Values) string { + return d.String(sv) +} + +// EncodedDefault returns the encoded value of the default value of the setting. +func (d *DurationSetting) EncodedDefault() string { + return EncodeDuration(d.defaultValue) +} + +// DecodeToString decodes and renders an encoded value. +func (d *DurationSetting) DecodeToString(encoded string) (string, error) { + v, err := d.DecodeValue(encoded) + if err != nil { + return "", err + } + return v.String(), nil +} + +// DecodeValue decodes the value into a float. +func (d *DurationSetting) DecodeValue(encoded string) (time.Duration, error) { + return time.ParseDuration(encoded) +} + +// Typ returns the short (1 char) string denoting the type of setting. +func (*DurationSetting) Typ() string { + return "d" +} + +// Default returns default value for setting. +func (d *DurationSetting) Default() time.Duration { + return d.defaultValue +} + +// Defeat the linter. +var _ = (*DurationSetting).Default + +// Validate that a value conforms with the validation function. +func (d *DurationSetting) Validate(v time.Duration) error { + if d.validateFn != nil { + if err := d.validateFn(v); err != nil { + return err + } + } + return nil +} + +// Override changes the setting without validation and also overrides the +// default value. +// +// For testing usage only. +func (d *DurationSetting) Override(ctx context.Context, sv *Values, v time.Duration) { + sv.setValueOrigin(ctx, d.slot, OriginOverride) + sv.setInt64(ctx, d.slot, int64(v)) + sv.setDefaultOverride(d.slot, v) +} + +func (d *DurationSetting) set(ctx context.Context, sv *Values, v time.Duration) error { + if err := d.Validate(v); err != nil { + return err + } + sv.setInt64(ctx, d.slot, int64(v)) + return nil +} + +func (d *DurationSetting) decodeAndSet(ctx context.Context, sv *Values, encoded string) error { + v, err := d.DecodeValue(encoded) + if err != nil { + return err + } + return d.set(ctx, sv, v) +} + +func (d *DurationSetting) decodeAndSetDefaultOverride( + ctx context.Context, sv *Values, encoded string, +) error { + v, err := d.DecodeValue(encoded) + if err != nil { + return err + } + sv.setDefaultOverride(d.slot, v) + return nil +} + +func (d *DurationSetting) setToDefault(ctx context.Context, sv *Values) { + // See if the default value was overridden. + if val := sv.getDefaultOverride(d.slot); val != nil { + // As per the semantics of override, these values don't go through + // validation. + _ = d.set(ctx, sv, val.(time.Duration)) + return + } + if err := d.set(ctx, sv, d.defaultValue); err != nil { + panic(err) + } +} + +// RegisterDurationSetting defines a new setting with type duration. +func RegisterDurationSetting( + class Class, key InternalKey, desc string, defaultValue time.Duration, opts ...SettingOption, +) *DurationSetting { + validateFn := func(val time.Duration) error { + for _, opt := range opts { + switch { + case opt.commonOpt != nil: + continue + case opt.validateDurationFn != nil: + default: + panic(errors.AssertionFailedf("wrong validator type")) + } + if err := opt.validateDurationFn(val); err != nil { + return errors.Wrapf(err, "invalid value for %s", key) + } + } + return nil + } + + if err := validateFn(defaultValue); err != nil { + panic(errors.Wrap(err, "invalid default")) + } + setting := &DurationSetting{ + defaultValue: defaultValue, + validateFn: validateFn, + } + register(class, key, desc, setting) + setting.apply(opts) + return setting +} + +// RegisterPublicDurationSettingWithExplicitUnit defines a new +// public setting with type duration which requires an explicit unit when being +// set. +func RegisterDurationSettingWithExplicitUnit( + class Class, key InternalKey, desc string, defaultValue time.Duration, opts ...SettingOption, +) *DurationSettingWithExplicitUnit { + validateFn := func(val time.Duration) error { + for _, opt := range opts { + switch { + case opt.commonOpt != nil: + continue + case opt.validateDurationFn != nil: + default: + panic(errors.AssertionFailedf("wrong validator type")) + } + if err := opt.validateDurationFn(val); err != nil { + return errors.Wrapf(err, "invalid value for %s", key) + } + } + return nil + } + if err := validateFn(defaultValue); err != nil { + panic(errors.Wrap(err, "invalid default")) + } + setting := &DurationSettingWithExplicitUnit{ + DurationSetting{ + defaultValue: defaultValue, + validateFn: validateFn, + }, + } + register(class, key, desc, setting) + setting.apply(opts) + return setting +} + +// NonNegativeDuration checks that the duration is greater or equal to +// zero. It can be passed to RegisterDurationSetting. +var NonNegativeDuration SettingOption = WithValidateDuration(nonNegativeDurationInternal) + +func nonNegativeDurationInternal(v time.Duration) error { + if v < 0 { + return errors.Errorf("cannot be set to a negative duration: %s", v) + } + return nil +} + +// DurationInRange returns a validation option that checks the value +// is within the given bounds (inclusive). +func DurationInRange(minVal, maxVal time.Duration) SettingOption { + return WithValidateDuration(func(v time.Duration) error { + if v < minVal || v > maxVal { + return errors.Errorf("expected value in range [%v, %v], got: %v", minVal, maxVal, v) + } + return nil + }) +} + +// NonNegativeDurationWithMaximum returns a validation option that +// checks the duration is in the range [0, maxValue]. It can be passed +// to RegisterDurationSetting. +func NonNegativeDurationWithMaximum(maxValue time.Duration) SettingOption { + return DurationInRange(0, maxValue) +} + +// DurationWithMinimum returns a validation option that checks the +// duration is greater or equal to the given minimum. It can be passed +// to RegisterDurationSetting. +func DurationWithMinimum(minValue time.Duration) SettingOption { + return WithValidateDuration(func(v time.Duration) error { + if minValue >= 0 { + if err := nonNegativeDurationInternal(v); err != nil { + return err + } + } + if v < minValue { + return errors.Errorf("cannot be set to a value smaller than %s", minValue) + } + return nil + }) +} + +// DurationWithMinimumOrZeroDisable returns a validation option that +// checks the value is at least the given minimum, or zero to disable. +// It can be passed to RegisterDurationSetting. +func DurationWithMinimumOrZeroDisable(minValue time.Duration) SettingOption { + return WithValidateDuration(func(v time.Duration) error { + if minValue >= 0 && v < 0 { + return errors.Errorf("cannot be set to a negative duration: %s", v) + } + if v != 0 && v < minValue { + return errors.Errorf("cannot be set to a value smaller than %s", + minValue) + } + return nil + }) +} + +// PositiveDuration checks that the value is strictly positive. It can +// be passed to RegisterDurationSetting. +var PositiveDuration SettingOption = WithValidateDuration(func(v time.Duration) error { + if v <= 0 { + return errors.Errorf("cannot be set to a non-positive duration: %s", v) + } + return nil +}) diff --git a/pkg/settings/encoding.go b/pkg/settings/encoding.go new file mode 100644 index 0000000..34b0608 --- /dev/null +++ b/pkg/settings/encoding.go @@ -0,0 +1,23 @@ +// Copyright 2022 The Cockroach Authors. +// +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. + +package settings + +import ( + "github.com/cockroachdb/redact" + "github.com/cockroachdb/redact/interfaces" +) + +// String is part of fmt.Stringer. +func (v EncodedValue) String() string { + return redact.Sprint(v).StripMarkers() +} + +// SafeFormat is part of redact.SafeFormatter. +func (v EncodedValue) SafeFormat(s interfaces.SafePrinter, verb rune) { + s.Printf("%q (%s)", v.Value, redact.SafeString(v.Type)) +} + +var _ redact.SafeFormatter = EncodedValue{} diff --git a/pkg/settings/encoding.pb.go b/pkg/settings/encoding.pb.go new file mode 100644 index 0000000..0948350 --- /dev/null +++ b/pkg/settings/encoding.pb.go @@ -0,0 +1,381 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: settings/encoding.proto + +package settings + +import ( + fmt "fmt" + _ "github.com/gogo/protobuf/gogoproto" + proto "github.com/gogo/protobuf/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// EncodedValue contains the value of a cluster setting serialized as an opaque +// string, along with a type identifier. Used when storing setting values on +// disk or passing them over the wire. +type EncodedValue struct { + Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` + Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` +} + +func (m *EncodedValue) Reset() { *m = EncodedValue{} } +func (*EncodedValue) ProtoMessage() {} +func (*EncodedValue) Descriptor() ([]byte, []int) { + return fileDescriptor_714f9b2611bd3e0b, []int{0} +} +func (m *EncodedValue) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *EncodedValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *EncodedValue) XXX_Merge(src proto.Message) { + xxx_messageInfo_EncodedValue.Merge(m, src) +} +func (m *EncodedValue) XXX_Size() int { + return m.Size() +} +func (m *EncodedValue) XXX_DiscardUnknown() { + xxx_messageInfo_EncodedValue.DiscardUnknown(m) +} + +var xxx_messageInfo_EncodedValue proto.InternalMessageInfo + +func init() { + proto.RegisterType((*EncodedValue)(nil), "cockroach.parser.settings.EncodedValue") +} + +func init() { proto.RegisterFile("settings/encoding.proto", fileDescriptor_714f9b2611bd3e0b) } + +var fileDescriptor_714f9b2611bd3e0b = []byte{ + // 197 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x2f, 0x4e, 0x2d, 0x29, + 0xc9, 0xcc, 0x4b, 0x2f, 0xd6, 0x4f, 0xcd, 0x4b, 0xce, 0x4f, 0xc9, 0xcc, 0x4b, 0xd7, 0x2b, 0x28, + 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x4a, 0xce, 0x4f, 0xce, 0x2e, 0xca, 0x4f, 0x4c, 0xce, 0xd0, 0x83, + 0x29, 0x91, 0x12, 0x49, 0xcf, 0x4f, 0xcf, 0x07, 0x4b, 0xeb, 0x83, 0x58, 0x10, 0x95, 0x4a, 0x4e, + 0x5c, 0x3c, 0xae, 0x20, 0xbd, 0xa9, 0x29, 0x61, 0x89, 0x39, 0xa5, 0xa9, 0x42, 0x22, 0x5c, 0xac, + 0x65, 0x20, 0x86, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0x67, 0x10, 0x84, 0x23, 0x24, 0xc4, 0xc5, 0x52, + 0x52, 0x59, 0x90, 0x2a, 0xc1, 0x04, 0x16, 0x04, 0xb3, 0xad, 0x38, 0x66, 0x2c, 0x90, 0x67, 0x78, + 0xb1, 0x40, 0x9e, 0xd1, 0xc9, 0xff, 0xc4, 0x43, 0x39, 0x86, 0x13, 0x8f, 0xe4, 0x18, 0x2f, 0x3c, + 0x92, 0x63, 0xbc, 0xf1, 0x48, 0x8e, 0xf1, 0xc1, 0x23, 0x39, 0xc6, 0x09, 0x8f, 0xe5, 0x18, 0x2e, + 0x3c, 0x96, 0x63, 0xb8, 0xf1, 0x58, 0x8e, 0x21, 0x4a, 0x37, 0x3d, 0xb3, 0x24, 0xa3, 0x34, 0x49, + 0x2f, 0x39, 0x3f, 0x57, 0x1f, 0xee, 0xb4, 0x94, 0x24, 0x04, 0x5b, 0xbf, 0x20, 0x3b, 0x5d, 0x1f, + 0xe6, 0xd4, 0x24, 0x36, 0xb0, 0xdb, 0x8c, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0xb9, 0xd8, 0x95, + 0x49, 0xe0, 0x00, 0x00, 0x00, +} + +func (this *EncodedValue) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*EncodedValue) + if !ok { + that2, ok := that.(EncodedValue) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.Value != that1.Value { + return false + } + if this.Type != that1.Type { + return false + } + return true +} +func (m *EncodedValue) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *EncodedValue) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *EncodedValue) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Type) > 0 { + i -= len(m.Type) + copy(dAtA[i:], m.Type) + i = encodeVarintEncoding(dAtA, i, uint64(len(m.Type))) + i-- + dAtA[i] = 0x12 + } + if len(m.Value) > 0 { + i -= len(m.Value) + copy(dAtA[i:], m.Value) + i = encodeVarintEncoding(dAtA, i, uint64(len(m.Value))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintEncoding(dAtA []byte, offset int, v uint64) int { + offset -= sovEncoding(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *EncodedValue) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Value) + if l > 0 { + n += 1 + l + sovEncoding(uint64(l)) + } + l = len(m.Type) + if l > 0 { + n += 1 + l + sovEncoding(uint64(l)) + } + return n +} + +func sovEncoding(x uint64) (n int) { + return int((uint32(math_bits.Len64(x|1)+6) * 37) >> 8) +} +func sozEncoding(x uint64) (n int) { + return sovEncoding(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *EncodedValue) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEncoding + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: EncodedValue: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: EncodedValue: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEncoding + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEncoding + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEncoding + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Value = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEncoding + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEncoding + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEncoding + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Type = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipEncoding(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEncoding + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipEncoding(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowEncoding + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowEncoding + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowEncoding + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthEncoding + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupEncoding + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthEncoding + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthEncoding = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowEncoding = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupEncoding = fmt.Errorf("proto: unexpected end of group") +) + diff --git a/pkg/settings/encoding.proto b/pkg/settings/encoding.proto new file mode 100644 index 0000000..4d9fea8 --- /dev/null +++ b/pkg/settings/encoding.proto @@ -0,0 +1,21 @@ +// Copyright 2022 The Cockroach Authors. +// +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. + +syntax = "proto3"; +package cockroach.settings; +option go_package = "github.com/cockroachdb/cockroach/pkg/settings"; + +import "gogoproto/gogo.proto"; + +// EncodedValue contains the value of a cluster setting serialized as an opaque +// string, along with a type identifier. Used when storing setting values on +// disk or passing them over the wire. +message EncodedValue { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = false; + + string value = 1; + string type = 2; +} diff --git a/pkg/settings/enum.go b/pkg/settings/enum.go new file mode 100644 index 0000000..14ca86c --- /dev/null +++ b/pkg/settings/enum.go @@ -0,0 +1,232 @@ +// Copyright 2017 The Cockroach Authors. +// +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. + +package settings + +import ( + "bytes" + "context" + "fmt" + "sort" + "strconv" + "strings" + + "golang.org/x/exp/constraints" +) + +// EnumSetting is a StringSetting that restricts the values to be one of the `enumValues` +type EnumSetting[T constraints.Integer] struct { + common + defaultValue T + // enumValues maps each valid value of T to a lowercase string. + enumValues map[T]string +} + +// AnyEnumSetting is an interface that is used when the specific enum type T is +// not known. +type AnyEnumSetting interface { + internalSetting + + // ParseEnum parses a string that is either a string in enumValues or an + // integer and returns the enum value as an int64 (and a boolean that + // indicates if it was parseable). + ParseEnum(raw string) (int64, bool) + + // GetAvailableValuesAsHint returns the possible enum settings as a string that + // can be provided as an error hint to a user. + GetAvailableValuesAsHint() string +} + +var _ AnyEnumSetting = &EnumSetting[int]{} + +// Typ returns the short (1 char) string denoting the type of setting. +func (e *EnumSetting[T]) Typ() string { + return "e" +} + +// Get retrieves the int value in the setting. +func (e *EnumSetting[T]) Get(sv *Values) T { + return T(sv.container.getInt64(e.slot)) +} + +// Override changes the setting without validation and also overrides the +// default value. +func (e *EnumSetting[T]) Override(ctx context.Context, sv *Values, v T) { + sv.setValueOrigin(ctx, e.slot, OriginOverride) + sv.setInt64(ctx, e.slot, int64(v)) + sv.setDefaultOverride(e.slot, int64(v)) +} + +// String returns the enum's string value. +func (e *EnumSetting[T]) String(sv *Values) string { + enumID := e.Get(sv) + if str, ok := e.enumValues[enumID]; ok { + return str + } + return fmt.Sprintf("unknown(%d)", enumID) +} + +// DefaultString returns the default value for the setting as a string. +func (e *EnumSetting[T]) DefaultString() string { + return e.enumValues[e.defaultValue] +} + +func (e *EnumSetting[T]) Encoded(sv *Values) string { + return EncodeInt(int64(e.Get(sv))) +} + +func (e *EnumSetting[T]) EncodedDefault() string { + return EncodeInt(int64(e.defaultValue)) +} + +func (e *EnumSetting[T]) setToDefault(ctx context.Context, sv *Values) { + // See if the default value was overridden. + if val := sv.getDefaultOverride(e.slot); val != nil { + // As per the semantics of override, these values don't go through + // validation. + sv.setInt64(ctx, e.slot, val.(int64)) + return + } + sv.setInt64(ctx, e.slot, int64(e.defaultValue)) +} + +func (e *EnumSetting[T]) decodeAndSet(ctx context.Context, sv *Values, encoded string) error { + v, err := strconv.ParseInt(encoded, 10, 64) + if err != nil { + return err + } + sv.setInt64(ctx, e.slot, v) + return nil +} + +func (e *EnumSetting[T]) decodeAndSetDefaultOverride( + ctx context.Context, sv *Values, encoded string, +) error { + v, err := strconv.ParseInt(encoded, 10, 64) + if err != nil { + return err + } + sv.setDefaultOverride(e.slot, v) + return nil +} + +// DecodeToString decodes and renders an encoded value. +func (e *EnumSetting[T]) DecodeToString(encoded string) (string, error) { + v, err := strconv.ParseInt(encoded, 10, 64) + if err != nil { + return "", err + } + if str, ok := e.enumValues[T(v)]; ok { + return str, nil + } + return encoded, nil +} + +// ParseEnum parses a string that is either a string in enumValues or an integer +// and returns the enum value as an int64 (and a boolean that indicates if it +// was parseable). +func (e *EnumSetting[T]) ParseEnum(raw string) (int64, bool) { + rawLower := strings.ToLower(raw) + for k, v := range e.enumValues { + if v == rawLower { + return int64(k), true + } + } + // Attempt to parse the string as an integer since it isn't a valid enum string. + v, err := strconv.ParseInt(raw, 10, 64) + if err != nil { + return 0, false + } + _, ok := e.enumValues[T(v)] + return v, ok +} + +// GetAvailableValuesAsHint returns the possible enum settings as a string that +// can be provided as an error hint to a user. +func (e *EnumSetting[T]) GetAvailableValuesAsHint() string { + // First stabilize output by sorting by key. + valIdxs := make([]int, 0, len(e.enumValues)) + for i := range e.enumValues { + valIdxs = append(valIdxs, int(i)) + } + sort.Ints(valIdxs) + + // Now use those indices + vals := make([]string, 0, len(e.enumValues)) + for _, enumIdx := range valIdxs { + vals = append(vals, fmt.Sprintf("%d: %s", enumIdx, e.enumValues[T(enumIdx)])) + } + return "Available values: " + strings.Join(vals, ", ") +} + +// GetAvailableValues returns the possible enum settings as a string +// slice. +func (e *EnumSetting[T]) GetAvailableValues() []string { + // First stabilize output by sorting by key. + valIdxs := make([]int, 0, len(e.enumValues)) + for i := range e.enumValues { + valIdxs = append(valIdxs, int(i)) + } + sort.Ints(valIdxs) + + // Now use those indices + vals := make([]string, 0, len(e.enumValues)) + for _, enumIdx := range valIdxs { + vals = append(vals, e.enumValues[T(enumIdx)]) + } + return vals +} + +func enumValuesToDesc[T constraints.Integer](enumValues map[T]string) string { + var buffer bytes.Buffer + values := make([]T, 0, len(enumValues)) + for k := range enumValues { + values = append(values, k) + } + sort.Slice(values, func(i, j int) bool { return values[i] < values[j] }) + + buffer.WriteString("[") + for i, k := range values { + if i > 0 { + buffer.WriteString(", ") + } + fmt.Fprintf(&buffer, "%s = %d", strings.ToLower(enumValues[k]), k) + } + buffer.WriteString("]") + return buffer.String() +} + +// RegisterEnumSetting defines a new setting with type int. +func RegisterEnumSetting[T constraints.Integer]( + class Class, + key InternalKey, + desc string, + defaultValue string, + enumValues map[T]string, + opts ...SettingOption, +) *EnumSetting[T] { + enumValuesLower := make(map[T]string, len(enumValues)) + for k, v := range enumValues { + enumValuesLower[k] = strings.ToLower(v) + } + + defaultVal := func() T { + for k, v := range enumValues { + if v == defaultValue { + return k + } + } + panic(fmt.Sprintf("enum registered with default value %s not in map %s", defaultValue, enumValuesToDesc(enumValuesLower))) + }() + + setting := &EnumSetting[T]{ + defaultValue: defaultVal, + enumValues: enumValuesLower, + } + + register(class, key, fmt.Sprintf("%s %s", desc, enumValuesToDesc(enumValues)), setting) + setting.apply(opts) + return setting +} diff --git a/pkg/settings/float.go b/pkg/settings/float.go new file mode 100644 index 0000000..2450bad --- /dev/null +++ b/pkg/settings/float.go @@ -0,0 +1,260 @@ +// Copyright 2017 The Cockroach Authors. +// +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. + +package settings + +import ( + "context" + "math" + "strconv" + + "github.com/cockroachdb/errors" +) + +// FloatSetting is the interface of a setting variable that will be +// updated automatically when the corresponding cluster-wide setting +// of type "float" is updated. +type FloatSetting struct { + common + defaultValue float64 + validateFn func(float64) error +} + +var _ internalSetting = &FloatSetting{} + +// Get retrieves the float value in the setting. +func (f *FloatSetting) Get(sv *Values) float64 { + return math.Float64frombits(uint64(sv.getInt64(f.slot))) +} + +func (f *FloatSetting) String(sv *Values) string { + return EncodeFloat(f.Get(sv)) +} + +// DefaultString returns the default value for the setting as a string. +func (f *FloatSetting) DefaultString() string { + return EncodeFloat(f.defaultValue) +} + +// Encoded returns the encoded value of the current value of the setting. +func (f *FloatSetting) Encoded(sv *Values) string { + return f.String(sv) +} + +// EncodedDefault returns the encoded value of the default value of the setting. +func (f *FloatSetting) EncodedDefault() string { + return EncodeFloat(f.defaultValue) +} + +// DecodeToString decodes and renders an encoded value. +func (f *FloatSetting) DecodeToString(encoded string) (string, error) { + fv, err := f.DecodeValue(encoded) + if err != nil { + return "", err + } + return EncodeFloat(fv), nil +} + +// DecodeValue decodes the value into a float. +func (f *FloatSetting) DecodeValue(encoded string) (float64, error) { + return strconv.ParseFloat(encoded, 64) +} + +// Typ returns the short (1 char) string denoting the type of setting. +func (*FloatSetting) Typ() string { + return "f" +} + +// Default returns default value for setting. +func (f *FloatSetting) Default() float64 { + return f.defaultValue +} + +// Defeat the linter. +var _ = (*FloatSetting).Default + +// Override changes the setting panicking if validation fails and also overrides +// the default value. +// +// For testing usage only. +func (f *FloatSetting) Override(ctx context.Context, sv *Values, v float64) { + sv.setValueOrigin(ctx, f.slot, OriginOverride) + if err := f.set(ctx, sv, v); err != nil { + panic(err) + } + sv.setDefaultOverride(f.slot, v) +} + +// Validate that a value conforms with the validation function. +func (f *FloatSetting) Validate(v float64) error { + if f.validateFn != nil { + if err := f.validateFn(v); err != nil { + return err + } + } + return nil +} + +func (f *FloatSetting) set(ctx context.Context, sv *Values, v float64) error { + if err := f.Validate(v); err != nil { + return err + } + sv.setInt64(ctx, f.slot, int64(math.Float64bits(v))) + return nil +} + +func (f *FloatSetting) decodeAndSet(ctx context.Context, sv *Values, encoded string) error { + v, err := f.DecodeValue(encoded) + if err != nil { + return err + } + return f.set(ctx, sv, v) +} + +func (f *FloatSetting) decodeAndSetDefaultOverride( + ctx context.Context, sv *Values, encoded string, +) error { + v, err := f.DecodeValue(encoded) + if err != nil { + return err + } + sv.setDefaultOverride(f.slot, v) + return nil +} + +func (f *FloatSetting) setToDefault(ctx context.Context, sv *Values) { + // See if the default value was overridden. + if val := sv.getDefaultOverride(f.slot); val != nil { + // As per the semantics of override, these values don't go through + // validation. + _ = f.set(ctx, sv, val.(float64)) + return + } + if err := f.set(ctx, sv, f.defaultValue); err != nil { + panic(err) + } +} + +// RegisterFloatSetting defines a new setting with type float. +func RegisterFloatSetting( + class Class, key InternalKey, desc string, defaultValue float64, opts ...SettingOption, +) *FloatSetting { + validateFn := func(v float64) error { + for _, opt := range opts { + switch { + case opt.commonOpt != nil: + continue + case opt.validateFloat64Fn != nil: + default: + panic(errors.AssertionFailedf("wrong validator type")) + } + if err := opt.validateFloat64Fn(v); err != nil { + return err + } + } + return nil + } + + if err := validateFn(defaultValue); err != nil { + panic(errors.Wrap(err, "invalid default")) + } + setting := &FloatSetting{ + defaultValue: defaultValue, + validateFn: validateFn, + } + register(class, key, desc, setting) + setting.apply(opts) + return setting +} + +// NonNegativeFloat checks the value is greater or equal to zero. It +// can be passed to RegisterFloatSetting. +var NonNegativeFloat SettingOption = FloatWithMinimum(0) + +// FloatWithMinimum returns a validation option that checks that the +// value is at least the given minimum. It can be passed to +// RegisterFloatSetting. +func FloatWithMinimum(minVal float64) SettingOption { + return WithValidateFloat(func(v float64) error { + if minVal >= 0 && v < 0 { + return errors.Errorf("cannot set to a negative value: %f", v) + } + if v < minVal { + return errors.Errorf("cannot set to a value lower than %f: %f", minVal, v) + } + return nil + }) +} + +// FloatWithMinimumOrZeroDisable returns a validation option that +// verifies the value is at least the given minimum, or zero to +// disable. It can be passed to RegisterFloatSetting. +func FloatWithMinimumOrZeroDisable(minVal float64) SettingOption { + return WithValidateFloat(func(v float64) error { + if minVal >= 0 && v < 0 { + return errors.Errorf("cannot set to a negative value: %f", v) + } + if v != 0 && v < minVal { + return errors.Errorf("cannot set to a value lower than %f: %f", minVal, v) + } + return nil + }) +} + +// NonNegativeFloatWithMaximum returns a validation option that checks +// that the value is in the range [0, maxValue]. It can be passed to +// RegisterFloatSetting. +func NonNegativeFloatWithMaximum(maxValue float64) SettingOption { + return FloatInRange(0, maxValue) +} + +// PositiveFloat checks that the value is strictly greater than zero. +// It can be passed to RegisterFloatSetting. +var PositiveFloat SettingOption = WithValidateFloat(func(v float64) error { + if v <= 0 { + return errors.Errorf("cannot set to a non-positive value: %f", v) + } + return nil +}) + +// NonZeroFloat checks that the value is non-zero. It can be passed to +// RegisterFloatSetting. +var NonZeroFloat SettingOption = WithValidateFloat(func(v float64) error { + if v == 0 { + return errors.New("cannot set to zero value") + } + return nil +}) + +// Fraction requires the setting to be in the interval [0, 1]. It can +// be passed to RegisterFloatSetting. +var Fraction SettingOption = FloatInRange(0, 1) + +// FloatInRange returns a validation option that checks the value is +// within the given bounds (inclusive). +func FloatInRange(minVal, maxVal float64) SettingOption { + return WithValidateFloat(func(v float64) error { + if v < minVal || v > maxVal { + return errors.Errorf("expected value in range [%f, %f], got: %f", minVal, maxVal, v) + } + return nil + }) +} + +// FractionUpperExclusive requires the setting to be in the interval +// [0, 1). It can be passed to RegisterFloatSetting. +var FractionUpperExclusive SettingOption = FloatInRangeUpperExclusive(0, 1) + +// FloatInRangeUpperExclusive returns a validation option that checks +// the value is within the given bounds (inclusive lower, exclusive +// upper). +func FloatInRangeUpperExclusive(minVal, maxVal float64) SettingOption { + return WithValidateFloat(func(v float64) error { + if v < minVal || v >= maxVal { + return errors.Errorf("expected value in range [%f, %f), got: %f", minVal, maxVal, v) + } + return nil + }) +} diff --git a/pkg/settings/int.go b/pkg/settings/int.go new file mode 100644 index 0000000..2e0c890 --- /dev/null +++ b/pkg/settings/int.go @@ -0,0 +1,238 @@ +// Copyright 2017 The Cockroach Authors. +// +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. + +package settings + +import ( + "context" + "strconv" + + "github.com/cockroachdb/errors" +) + +// IntSetting is the interface of a setting variable that will be +// updated automatically when the corresponding cluster-wide setting +// of type "int" is updated. +type IntSetting struct { + common + defaultValue int64 + validateFn func(int64) error +} + +var _ internalSetting = &IntSetting{} + +// Get retrieves the int value in the setting. +func (i *IntSetting) Get(sv *Values) int64 { + return sv.container.getInt64(i.slot) +} + +func (i *IntSetting) String(sv *Values) string { + return EncodeInt(i.Get(sv)) +} + +// DefaultString returns the default value for the setting as a string. +func (i *IntSetting) DefaultString() string { + return EncodeInt(i.defaultValue) +} + +// Encoded returns the encoded value of the current value of the setting. +func (i *IntSetting) Encoded(sv *Values) string { + return i.String(sv) +} + +// EncodedDefault returns the encoded value of the default value of the setting. +func (i *IntSetting) EncodedDefault() string { + return EncodeInt(i.defaultValue) +} + +// DecodeToString decodes and renders an encoded value. +func (i *IntSetting) DecodeToString(encoded string) (string, error) { + iv, err := i.DecodeNumericValue(encoded) + if err != nil { + return "", err + } + return EncodeInt(iv), nil +} + +// DecodeValue decodes the value into an integer. +func (i *IntSetting) DecodeNumericValue(value string) (int64, error) { + return strconv.ParseInt(value, 10, 64) +} + +// Typ returns the short (1 char) string denoting the type of setting. +func (*IntSetting) Typ() string { + return "i" +} + +// Default returns default value for setting. +func (i *IntSetting) Default() int64 { + return i.defaultValue +} + +// Defeat the linter. +var _ = (*IntSetting).Default + +// Validate that a value conforms with the validation function. +func (i *IntSetting) Validate(v int64) error { + if i.validateFn != nil { + if err := i.validateFn(v); err != nil { + return err + } + } + return nil +} + +// Override changes the setting without validation and also overrides the +// default value. +// +// For testing usage only. +func (i *IntSetting) Override(ctx context.Context, sv *Values, v int64) { + sv.setValueOrigin(ctx, i.slot, OriginOverride) + sv.setInt64(ctx, i.slot, v) + sv.setDefaultOverride(i.slot, v) +} + +func (i *IntSetting) decodeAndSet(ctx context.Context, sv *Values, encoded string) error { + v, err := strconv.ParseInt(encoded, 10, 64) + if err != nil { + return err + } + if err := i.Validate(v); err != nil { + return err + } + sv.setInt64(ctx, i.slot, v) + return nil +} + +func (i *IntSetting) decodeAndSetDefaultOverride( + ctx context.Context, sv *Values, encoded string, +) error { + v, err := strconv.ParseInt(encoded, 10, 64) + if err != nil { + return err + } + sv.setDefaultOverride(i.slot, v) + return nil +} + +func (i *IntSetting) set(ctx context.Context, sv *Values, v int64) error { + if err := i.Validate(v); err != nil { + return err + } + sv.setInt64(ctx, i.slot, v) + return nil +} + +func (i *IntSetting) setToDefault(ctx context.Context, sv *Values) { + // See if the default value was overridden. + if val := sv.getDefaultOverride(i.slot); val != nil { + // As per the semantics of override, these values don't go through + // validation. + _ = i.set(ctx, sv, val.(int64)) + return + } + if err := i.set(ctx, sv, i.defaultValue); err != nil { + panic(err) + } +} + +// RegisterIntSetting defines a new setting with type int with a +// validation function. +func RegisterIntSetting( + class Class, key InternalKey, desc string, defaultValue int64, opts ...SettingOption, +) *IntSetting { + validateFn := func(val int64) error { + for _, opt := range opts { + switch { + case opt.commonOpt != nil: + continue + case opt.validateInt64Fn != nil: + default: + panic(errors.AssertionFailedf("wrong validator type")) + } + if err := opt.validateInt64Fn(val); err != nil { + return err + } + } + return nil + } + if err := validateFn(defaultValue); err != nil { + panic(errors.Wrap(err, "invalid default")) + } + setting := &IntSetting{ + defaultValue: defaultValue, + validateFn: validateFn, + } + register(class, key, desc, setting) + setting.apply(opts) + return setting +} + +// PositiveInt can be passed to RegisterIntSetting. +var PositiveInt SettingOption = WithValidateInt(func(v int64) error { + if v <= 0 { + return errors.Errorf("cannot be set to a non-positive value: %d", v) + } + return nil +}) + +// NonNegativeInt checks the value is zero or positive. It can be +// passed to RegisterIntSetting. +var NonNegativeInt SettingOption = WithValidateInt(nonNegativeIntInternal) + +func nonNegativeIntInternal(v int64) error { + if v < 0 { + return errors.Errorf("cannot be set to a negative value: %d", v) + } + return nil +} + +// IntWithMinimum returns a validation option that checks +// that the value is greater or equal to the given minimum. It can be +// passed to RegisterIntSetting. +func IntWithMinimum(minVal int64) SettingOption { + return WithValidateInt(func(v int64) error { + if minVal >= 0 { + if err := nonNegativeIntInternal(v); err != nil { + return err + } + } + if v < minVal { + return errors.Errorf("cannot be set to a value lower than %d: %d", minVal, v) + } + return nil + }) +} + +// NonNegativeIntWithMaximum returns a validation option that checks +// that the value is in the range [0, maxValue]. It can be passed to +// RegisterIntSetting. +func NonNegativeIntWithMaximum(maxValue int64) SettingOption { + return IntInRange(0, maxValue) +} + +// IntInRange returns a validation option that checks the value is +// within the given bounds (inclusive). It can be passed to +// RegisterIntSetting. +func IntInRange(minVal, maxVal int64) SettingOption { + return WithValidateInt(func(v int64) error { + if v < minVal || v > maxVal { + return errors.Errorf("expected value in range [%d, %d], got: %d", minVal, maxVal, v) + } + return nil + }) +} + +// IntInRangeOrZeroDisable returns a validation option that checks the +// value is within the given bounds (inclusive) or is zero (disabled). +// It can be passed to RegisterIntSetting. +func IntInRangeOrZeroDisable(minVal, maxVal int64) SettingOption { + return WithValidateInt(func(v int64) error { + if v != 0 && (v < minVal || v > maxVal) { + return errors.Errorf("expected value in range [%d, %d] or 0 to disable, got: %d", minVal, maxVal, v) + } + return nil + }) +} diff --git a/pkg/settings/masked.go b/pkg/settings/masked.go new file mode 100644 index 0000000..8776cdb --- /dev/null +++ b/pkg/settings/masked.go @@ -0,0 +1,92 @@ +// Copyright 2019 The Cockroach Authors. +// +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. + +package settings + +import "context" + +// MaskedSetting is a wrapper for non-reportable settings that were retrieved +// for reporting (see SetReportable and LookupForReportingByKey). +type MaskedSetting struct { + setting NonMaskedSetting +} + +var _ Setting = &MaskedSetting{} + +// redactSensitiveSettingsEnabled enables or disables the redaction of sensitive +// cluster settings. +var redactSensitiveSettingsEnabled = RegisterBoolSetting( + ApplicationLevel, + "server.redact_sensitive_settings.enabled", + "enables or disables the redaction of sensitive settings in the output of SHOW CLUSTER SETTINGS and "+ + "SHOW ALL CLUSTER SETTINGS for users without the MODIFYCLUSTERSETTING privilege", + false, + WithPublic, +) + +// String hides the underlying value. +func (s *MaskedSetting) String(sv *Values) string { + // Special case for non-reportable/sensitive strings: we still want + // to distinguish empty from non-empty (= customized). + if st, ok := s.setting.(*StringSetting); ok && st.String(sv) == "" { + return "" + } + isSensitive := false + if st, ok := s.setting.(internalSetting); ok { + isSensitive = st.isSensitive() + } + sensitiveRedactionEnabled := redactSensitiveSettingsEnabled.Get(sv) + // Non-reportable settings are always redacted. Sensitive settings are + // redacted if the redaction cluster setting is enabled. + if !isSensitive || sensitiveRedactionEnabled { + return "" + } + return s.setting.String(sv) +} + +// DefaultString returns the default value for the setting as a string. +func (s *MaskedSetting) DefaultString() string { + return s.setting.DefaultString() +} + +// Visibility returns the visibility setting for the underlying setting. +func (s *MaskedSetting) Visibility() Visibility { + return s.setting.Visibility() +} + +// InternalKey returns the key string for the underlying setting. +func (s *MaskedSetting) InternalKey() InternalKey { + return s.setting.InternalKey() +} + +// Name returns the name string for the underlying setting. +func (s *MaskedSetting) Name() SettingName { + return s.setting.Name() +} + +// Description returns the description string for the underlying setting. +func (s *MaskedSetting) Description() string { + return s.setting.Description() +} + +// Typ returns the short (1 char) string denoting the type of setting. +func (s *MaskedSetting) Typ() string { + return s.setting.Typ() +} + +// Class returns the class for the underlying setting. +func (s *MaskedSetting) Class() Class { + return s.setting.Class() +} + +// ValueOrigin returns the origin of the current value of the setting. +func (s *MaskedSetting) ValueOrigin(ctx context.Context, sv *Values) ValueOrigin { + return s.setting.ValueOrigin(ctx, sv) +} + +// IsUnsafe returns whether the underlying setting is unsafe. +func (s *MaskedSetting) IsUnsafe() bool { + return s.setting.IsUnsafe() +} diff --git a/pkg/settings/options.go b/pkg/settings/options.go new file mode 100644 index 0000000..e030b93 --- /dev/null +++ b/pkg/settings/options.go @@ -0,0 +1,128 @@ +// Copyright 2023 The Cockroach Authors. +// +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. + +package settings + +import ( + "time" + + "github.com/cockroachdb/cockroachdb-parser/pkg/util/protoutil" +) + +// SettingOption is the type of an option that can be passed to Register. +type SettingOption struct { + commonOpt func(*common) + validateBoolFn func(*Values, bool) error + validateDurationFn func(time.Duration) error + validateInt64Fn func(int64) error + validateFloat64Fn func(float64) error + validateStringFn func(*Values, string) error + validateProtoFn func(*Values, protoutil.Message) error +} + +// NameStatus indicates the status of a setting name. +type NameStatus bool + +const ( + // NameActive indicates that the name is currently in use. + NameActive NameStatus = true + // NameRetired indicates that the name is no longer in use. + NameRetired NameStatus = false +) + +// WithName configures the user-visible name of the setting. +func WithName(name SettingName) SettingOption { + return SettingOption{commonOpt: func(c *common) { + c.setName(name) + registerAlias(c.key, name, NameActive) + }} +} + +// WithRetiredName configures a previous user-visible name of the setting, +// when that name was different from the key and is not in use any more. +func WithRetiredName(name SettingName) SettingOption { + return SettingOption{commonOpt: func(c *common) { + registerAlias(c.key, name, NameRetired) + }} +} + +// WithVisibility customizes the visibility of a setting. +func WithVisibility(v Visibility) SettingOption { + return SettingOption{commonOpt: func(c *common) { + c.setVisibility(v) + }} +} + +// WithUnsafe indicates that the setting is unsafe. +// Unsafe settings need an interlock to be updated. They also cannot be public. +var WithUnsafe SettingOption = SettingOption{commonOpt: func(c *common) { + c.setUnsafe() +}} + +// WithPublic sets public visibility. +var WithPublic SettingOption = WithVisibility(Public) + +// WithReportable indicates whether a setting's value can show up in SHOW ALL +// CLUSTER SETTINGS and telemetry reports. +func WithReportable(reportable bool) SettingOption { + return SettingOption{commonOpt: func(c *common) { + c.setReportable(reportable) + }} +} + +// Retired marks the setting as obsolete. It also hides it from the +// output of SHOW CLUSTER SETTINGS. Note: in many case the setting +// definition can be removed outright, and its name added to the +// retiredSettings map (in settings/registry.go). The Retired option +// exists for cases where there is a need to maintain compatibility +// with automation. +var Retired SettingOption = SettingOption{commonOpt: func(c *common) { + c.setRetired() +}} + +// Sensitive marks the setting as sensitive, which means that it will always +// be redacted in any output. It also makes the setting non-reportable. It can +// only be used for string settings. +var Sensitive SettingOption = SettingOption{commonOpt: func(c *common) { + c.setSensitive() +}} + +// WithValidateDuration adds a validation function for a duration setting. +func WithValidateDuration(fn func(time.Duration) error) SettingOption { + return SettingOption{validateDurationFn: fn} +} + +// WithValidateInt adds a validation function for an int64 setting. +func WithValidateInt(fn func(int64) error) SettingOption { + return SettingOption{validateInt64Fn: fn} +} + +// WithValidateFloat adds a validation function for a float64 setting. +func WithValidateFloat(fn func(float64) error) SettingOption { + return SettingOption{validateFloat64Fn: fn} +} + +// WithValidateBool adds a validation function for a boolean setting. +func WithValidateBool(fn func(*Values, bool) error) SettingOption { + return SettingOption{validateBoolFn: fn} +} + +// WithValidateString adds a validation function for a string setting. +func WithValidateString(fn func(*Values, string) error) SettingOption { + return SettingOption{validateStringFn: fn} +} + +// WithValidateProto adds a validation function for a proto setting. +func WithValidateProto(fn func(*Values, protoutil.Message) error) SettingOption { + return SettingOption{validateProtoFn: fn} +} + +func (c *common) apply(opts []SettingOption) { + for _, opt := range opts { + if opt.commonOpt != nil { + opt.commonOpt(c) + } + } +} diff --git a/pkg/settings/protobuf.go b/pkg/settings/protobuf.go new file mode 100644 index 0000000..c38f572 --- /dev/null +++ b/pkg/settings/protobuf.go @@ -0,0 +1,241 @@ +// Copyright 2022 The Cockroach Authors. +// +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. + +package settings + +import ( + "context" + "reflect" + "strings" + + "github.com/cockroachdb/cockroachdb-parser/pkg/util/protoutil" + "github.com/cockroachdb/errors" + "github.com/gogo/protobuf/jsonpb" + "github.com/gogo/protobuf/proto" +) + +// ProtobufSetting is the interface of a setting variable that will be updated +// automatically when the corresponding cluster-wide setting of type "protobuf" +// is updated. The proto message is held in memory, the byte representation +// stored in system.settings, and JSON presentation used when accepting input +// and rendering (just through SHOW CLUSTER SETTING , the raw form +// is visible when looking directly at system.settings). +type ProtobufSetting struct { + defaultValue protoutil.Message + validateFn func(*Values, protoutil.Message) error + common +} + +var _ internalSetting = &ProtobufSetting{} + +// String returns the string representation of the setting's current value. +func (s *ProtobufSetting) String(sv *Values) string { + p := s.Get(sv) + json, err := s.MarshalToJSON(p) + if err != nil { + panic(errors.Wrapf(err, "marshaling %s: %+v", proto.MessageName(p), p)) + } + return json +} + +// DefaultString returns the default value for the setting as a string. +func (s *ProtobufSetting) DefaultString() string { + json, err := s.MarshalToJSON(s.defaultValue) + if err != nil { + panic(errors.Wrapf(err, "marshaling %s: %+v", proto.MessageName(s.defaultValue), s.defaultValue)) + } + return json +} + +// Encoded returns the encoded value of the current value of the setting. +func (s *ProtobufSetting) Encoded(sv *Values) string { + p := s.Get(sv) + return EncodeProtobuf(p) +} + +// EncodedDefault returns the encoded value of the default value of the setting. +func (s *ProtobufSetting) EncodedDefault() string { + return EncodeProtobuf(s.defaultValue) +} + +// DecodeToString decodes and renders an encoded value. +func (s *ProtobufSetting) DecodeToString(encoded string) (string, error) { + message, err := s.DecodeValue(encoded) + if err != nil { + return "", err + } + return s.MarshalToJSON(message) +} + +// Typ returns the short (1 char) string denoting the type of setting. +func (*ProtobufSetting) Typ() string { + return "p" +} + +// DecodeValue decodes the value into a protobuf. +func (s *ProtobufSetting) DecodeValue(encoded string) (protoutil.Message, error) { + p, err := newProtoMessage(proto.MessageName(s.defaultValue)) + if err != nil { + return nil, err + } + + if err := protoutil.Unmarshal([]byte(encoded), p); err != nil { + return nil, err + } + return p, nil +} + +// Default returns default value for setting. +func (s *ProtobufSetting) Default() protoutil.Message { + return s.defaultValue +} + +// Get retrieves the protobuf value in the setting. +func (s *ProtobufSetting) Get(sv *Values) protoutil.Message { + loaded := sv.getGeneric(s.slot) + if loaded == nil { + return s.defaultValue + } + return loaded.(protoutil.Message) +} + +// Validate that a value conforms with the validation function. +func (s *ProtobufSetting) Validate(sv *Values, p protoutil.Message) error { + if s.validateFn == nil { + return nil // nothing to do + } + return s.validateFn(sv, p) +} + +// Override sets the setting to the given value, assuming it passes validation. +func (s *ProtobufSetting) Override(ctx context.Context, sv *Values, p protoutil.Message) { + sv.setValueOrigin(ctx, s.slot, OriginOverride) + _ = s.set(ctx, sv, p) + sv.setDefaultOverride(s.slot, p) +} + +func (s *ProtobufSetting) decodeAndSet(ctx context.Context, sv *Values, encoded string) error { + p, err := s.DecodeValue(encoded) + if err != nil { + return err + } + return s.set(ctx, sv, p) +} + +func (s *ProtobufSetting) decodeAndSetDefaultOverride( + ctx context.Context, sv *Values, encoded string, +) error { + p, err := s.DecodeValue(encoded) + if err != nil { + return err + } + sv.setDefaultOverride(s.slot, p) + return nil +} + +func (s *ProtobufSetting) set(ctx context.Context, sv *Values, p protoutil.Message) error { + if err := s.Validate(sv, p); err != nil { + return err + } + if s.Get(sv) != p { + sv.setGeneric(ctx, s.slot, p) + } + return nil +} + +func (s *ProtobufSetting) setToDefault(ctx context.Context, sv *Values) { + // See if the default value was overridden. + if val := sv.getDefaultOverride(s.slot); val != nil { + // As per the semantics of override, these values don't go through + // validation. + _ = s.set(ctx, sv, val.(protoutil.Message)) + return + } + if err := s.set(ctx, sv, s.defaultValue); err != nil { + panic(err) + } +} + +// MarshalToJSON returns a JSON representation of the protobuf. +func (s *ProtobufSetting) MarshalToJSON(p protoutil.Message) (string, error) { + jsonEncoder := jsonpb.Marshaler{EmitDefaults: false} + return jsonEncoder.MarshalToString(p) +} + +// UnmarshalFromJSON unmarshals a protobuf from a json representation. +func (s *ProtobufSetting) UnmarshalFromJSON(jsonEncoded string) (protoutil.Message, error) { + p, err := newProtoMessage(proto.MessageName(s.defaultValue)) + if err != nil { + return nil, err + } + + json := &jsonpb.Unmarshaler{} + if err := json.Unmarshal(strings.NewReader(jsonEncoded), p); err != nil { + return nil, errors.Wrapf(err, "unmarshaling json to %s", proto.MessageName(p)) + } + return p, nil +} + +// RegisterProtobufSetting defines a new setting with type protobuf. +func RegisterProtobufSetting( + class Class, key InternalKey, desc string, defaultValue protoutil.Message, opts ...SettingOption, +) *ProtobufSetting { + validateFn := func(sv *Values, p protoutil.Message) error { + for _, opt := range opts { + switch { + case opt.commonOpt != nil: + continue + case opt.validateProtoFn != nil: + default: + panic(errors.AssertionFailedf("wrong validator type")) + } + if err := opt.validateProtoFn(sv, p); err != nil { + return err + } + } + return nil + } + setting := &ProtobufSetting{ + defaultValue: defaultValue, + validateFn: validateFn, + } + + // By default, all protobuf settings are considered to contain PII and are + // thus non-reportable (to exclude them from telemetry reports). + setting.setReportable(false) + register(class, key, desc, setting) + setting.apply(opts) + return setting +} + +// Defeat the unused linter. +var _ = (*ProtobufSetting).Default + +// newProtoMessage creates a new protocol message object, given its fully +// qualified name. +func newProtoMessage(name string) (protoutil.Message, error) { + // Get the reflected type of the protocol message. + rt := proto.MessageType(name) + if rt == nil { + return nil, errors.Newf("unknown proto message type %s", name) + } + + // If the message is known, we should get the pointer to our message. + if rt.Kind() != reflect.Ptr { + return nil, errors.AssertionFailedf( + "expected ptr to message, got %s instead", rt.Kind().String()) + } + + // Construct message of appropriate type, through reflection. + rv := reflect.New(rt.Elem()) + msg, ok := rv.Interface().(protoutil.Message) + if !ok { + // Just to be safe. + return nil, errors.AssertionFailedf( + "unexpected proto type for %s; expected protoutil.Message, got %T", + name, rv.Interface()) + } + return msg, nil +} diff --git a/pkg/settings/registry.go b/pkg/settings/registry.go new file mode 100644 index 0000000..e6e2321 --- /dev/null +++ b/pkg/settings/registry.go @@ -0,0 +1,574 @@ +// Copyright 2017 The Cockroach Authors. +// +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. + +package settings + +import ( + "fmt" + "sort" + "strings" +) + +// registry contains all defined settings, their types and default values. +// +// The registry does not store the current values of the settings; those are +// stored separately in Values, allowing multiple independent instances +// of each setting in the registry. +// +// registry should never be mutated after creation (except in tests), as it is +// read concurrently by different callers. +var registry = make(map[InternalKey]internalSetting) + +// tenantReadOnlyKeys contains the keys of settings that have the +// class SystemVisible. This is used to initialize defaults in the +// tenant settings watcher. +var tenantReadOnlyKeys []InternalKey + +// aliasRegistry contains the mapping of names to keys, for names +// different from the keys. +var aliasRegistry = make(map[SettingName]aliasEntry) + +type aliasEntry struct { + // key is the setting this name is referring to. + key InternalKey + // active indicates whether this name is currently in use. + active NameStatus +} + +// slotTable stores the same settings as the registry, but accessible by the +// slot index. +var slotTable [MaxSettings]internalSetting + +// TestingSaveRegistry can be used in tests to save/restore the current +// contents of the registry. +func TestingSaveRegistry() func() { + var origRegistry = make(map[InternalKey]internalSetting) + for k, v := range registry { + origRegistry[k] = v + } + var origAliases = make(map[SettingName]aliasEntry) + for k, v := range aliasRegistry { + origAliases[k] = v + } + var origSystemVisibleKeys = make([]InternalKey, len(tenantReadOnlyKeys)) + copy(origSystemVisibleKeys, tenantReadOnlyKeys) + return func() { + registry = origRegistry + aliasRegistry = origAliases + tenantReadOnlyKeys = origSystemVisibleKeys + } +} + +// When a setting class changes from ApplicationLevel to System, it should +// be added to this list so that we can offer graceful degradation to +// users of previous versions. +var systemSettingsWithPreviousApplicationClass = map[InternalKey]struct{}{ + // Changed in v23.2. + "cluster.organization": {}, + "enterprise.license": {}, + "kv.bulk_io_write.concurrent_export_requests": {}, + "kv.closed_timestamp.propagation_slack": {}, + "kv.closed_timestamp.side_transport_interval": {}, + "kv.closed_timestamp.target_duration": {}, + "kv.raft.command.max_size": {}, + "kv.rangefeed.enabled": {}, + "server.rangelog.ttl": {}, + "timeseries.storage.enabled": {}, + "timeseries.storage.resolution_10s.ttl": {}, + "timeseries.storage.resolution_30m.ttl": {}, +} + +// SettingPreviouslyHadApplicationClass returns true if the setting +// used to have the ApplicationLevel class. +func SettingPreviouslyHadApplicationClass(key InternalKey) bool { + _, ok := systemSettingsWithPreviousApplicationClass[key] + return ok +} + +// When a setting is removed, it should be added to this list so that we cannot +// accidentally reuse its name, potentially mis-handling older values. +var retiredSettings = map[InternalKey]struct{}{ + // removed as of 2.0. + "kv.gc.batch_size": {}, + "kv.transaction.max_intents": {}, + "diagnostics.reporting.report_metrics": {}, + // removed as of 2.1. + "kv.allocator.stat_based_rebalancing.enabled": {}, + "kv.allocator.stat_rebalance_threshold": {}, + // removed as of 19.1. + "kv.raft_log.synchronize": {}, + // removed as of 19.2. + "schemachanger.bulk_index_backfill.enabled": {}, + "rocksdb.ingest_backpressure.delay_l0_file": {}, // never used + "server.heap_profile.system_memory_threshold_fraction": {}, + "timeseries.storage.10s_resolution_ttl": {}, + "changefeed.push.enabled": {}, + "sql.defaults.optimizer": {}, + "kv.bulk_io_write.addsstable_max_rate": {}, + // removed as of 20.1. + "schemachanger.lease.duration": {}, + "schemachanger.lease.renew_fraction": {}, + "diagnostics.forced_stat_reset.interval": {}, + // removed as of 20.2. + "rocksdb.ingest_backpressure.pending_compaction_threshold": {}, + "sql.distsql.temp_storage.joins": {}, + "sql.distsql.temp_storage.sorts": {}, + "sql.distsql.distribute_index_joins": {}, + "sql.distsql.merge_joins.enabled": {}, + "sql.defaults.optimizer_foreign_keys.enabled": {}, + "sql.defaults.experimental_optimizer_foreign_key_cascades.enabled": {}, + "sql.parallel_scans.enabled": {}, + "backup.table_statistics.enabled": {}, + // removed as of 21.1. + "sql.distsql.interleaved_joins.enabled": {}, + "sql.testing.vectorize.batch_size": {}, + "sql.testing.mutations.max_batch_size": {}, + "sql.testing.mock_contention.enabled": {}, + "kv.atomic_replication_changes.enabled": {}, + // removed as of 21.1.2. + "kv.tenant_rate_limiter.read_requests.rate_limit": {}, + "kv.tenant_rate_limiter.read_requests.burst_limit": {}, + "kv.tenant_rate_limiter.write_requests.rate_limit": {}, + "kv.tenant_rate_limiter.write_requests.burst_limit": {}, + "kv.tenant_rate_limiter.read_bytes.rate_limit": {}, + "kv.tenant_rate_limiter.read_bytes.burst_limit": {}, + "kv.tenant_rate_limiter.write_bytes.rate_limit": {}, + "kv.tenant_rate_limiter.write_bytes.burst_limit": {}, + + // removed as of 21.2. + "sql.defaults.vectorize_row_count_threshold": {}, + "cloudstorage.gs.default.key": {}, + "storage.sst_export.max_intents_per_error": {}, + "jobs.registry.leniency": {}, + "sql.defaults.experimental_expression_based_indexes.enabled": {}, + "kv.transaction.write_pipelining_max_outstanding_size": {}, + "sql.defaults.optimizer_improve_disjunction_selectivity.enabled": {}, + "bulkio.backup.proxy_file_writes.enabled": {}, + "sql.distsql.prefer_local_execution.enabled": {}, + "kv.follower_read.target_multiple": {}, + "kv.closed_timestamp.close_fraction": {}, + "sql.telemetry.query_sampling.qps_threshold": {}, + "sql.telemetry.query_sampling.sample_rate": {}, + "diagnostics.sql_stat_reset.interval": {}, + "changefeed.mem.pushback_enabled": {}, + "sql.distsql.index_join_limit_hint.enabled": {}, + + // removed as of 22.1. + "sql.defaults.drop_enum_value.enabled": {}, + "trace.lightstep.token": {}, + "trace.datadog.agent": {}, + "trace.datadog.project": {}, + "sql.defaults.interleaved_tables.enabled": {}, + "sql.defaults.copy_partitioning_when_deinterleaving_table.enabled": {}, + "server.declined_reservation_timeout": {}, + "bulkio.backup.resolve_destination_in_job.enabled": {}, + "sql.defaults.experimental_hash_sharded_indexes.enabled": {}, + "schemachanger.backfiller.max_sst_size": {}, + "kv.bulk_ingest.buffer_increment": {}, + "schemachanger.backfiller.buffer_increment": {}, + "kv.rangefeed.separated_intent_scan.enabled": {}, + + // removed as of 22.1.2. + "tenant_cost_model.kv_read_request_cost": {}, + "tenant_cost_model.kv_read_cost_per_megabyte": {}, + "tenant_cost_model.kv_write_request_cost": {}, + "tenant_cost_model.kv_write_cost_per_megabyte": {}, + "tenant_cost_model.pod_cpu_second_cost": {}, + "tenant_cost_model.pgwire_egress_cost_per_megabyte": {}, + "sql.ttl.range_batch_size": {}, + + // removed as of 22.2. + "bulkio.restore_at_current_time.enabled": {}, + "bulkio.import_at_current_time.enabled": {}, + "kv.bulk_io_write.experimental_incremental_export_enabled": {}, + "kv.bulk_io_write.revert_range_time_bound_iterator.enabled": {}, + "kv.rangefeed.catchup_scan_iterator_optimization.enabled": {}, + "kv.refresh_range.time_bound_iterators.enabled": {}, + "sql.defaults.datestyle.enabled": {}, + "sql.defaults.intervalstyle.enabled": {}, + + // removed as of 22.2.1 + "sql.ttl.default_range_concurrency": {}, + "server.web_session.purge.period": {}, + "server.web_session.purge.max_deletions_per_cycle": {}, + "server.web_session.auto_logout.timeout": {}, + + // removed as of 23.1. + "sql.auth.modify_cluster_setting_applies_to_all.enabled": {}, + "sql.catalog.descs.validate_on_write.enabled": {}, + "sql.distsql.max_running_flows": {}, + "sql.distsql.flow_scheduler_queueing.enabled": {}, + "sql.distsql.drain.cancel_after_wait.enabled": {}, + "changefeed.active_protected_timestamps.enabled": {}, + "jobs.scheduler.single_node_scheduler.enabled": {}, + "tenant_capabilities.authorizer.enabled": {}, + // renamed. + "spanconfig.host_coalesce_adjacent.enabled": {}, + "sql.defaults.experimental_stream_replication.enabled": {}, + "sql.drop_tenant.enabled": {}, + + // removed as of 23.2. + "sql.log.unstructured_entries.enabled": {}, + "sql.auth.createrole_allows_grant_role_membership.enabled": {}, + "changefeed.replan_flow_frequency": {}, + "changefeed.replan_flow_threshold": {}, + "jobs.trace.force_dump_mode": {}, + "timeseries.storage.30m_resolution_ttl": {}, + "server.cpu_profile.enabled": {}, + "changefeed.lagging_ranges_threshold": {}, + "changefeed.lagging_ranges_polling_rate": {}, + "trace.jaeger.agent": {}, + "bulkio.restore.use_simple_import_spans": {}, + "bulkio.restore.remove_regions.enabled": {}, + + // removed as of 24.1 + "storage.mvcc.range_tombstones.enabled": {}, + "changefeed.balance_range_distribution.enable": {}, + "changefeed.mux_rangefeed.enabled": {}, + "kv.rangefeed.catchup_scan_concurrency": {}, + "physical_replication.producer.mux_rangefeeds.enabled": {}, + "kv.rangefeed.use_dedicated_connection_class.enabled": {}, + "sql.trace.session_eventlog.enabled": {}, + "sql.show_ranges_deprecated_behavior.enabled": {}, + "sql.drop_virtual_cluster.enabled": {}, + "cross_cluster_replication.enabled": {}, + "server.controller.default_tenant.check_service.enabled": {}, + + // removed as of 24.2 + "storage.value_blocks.enabled": {}, + "kv.gc.sticky_hint.enabled": {}, + "kv.rangefeed.range_stuck_threshold": {}, + + // removed as of 24.3 + "bulkio.backup.split_keys_on_timestamps": {}, + "sql.create_tenant.default_template": {}, + "kvadmission.low_pri_read_elastic_control.enabled": {}, + + // removed as of 25.1 + "sql.auth.resolve_membership_single_scan.enabled": {}, + "storage.single_delete.crash_on_invariant_violation.enabled": {}, + "storage.single_delete.crash_on_ineffectual.enabled": {}, + "bulkio.backup.elide_common_prefix.enabled": {}, + "kv.bulkio.write_metadata_sst.enabled": {}, + "jobs.execution_errors.max_entries": {}, + "jobs.execution_errors.max_entry_size": {}, + "sql.metrics.statement_details.plan_collection.enabled": {}, + "sql.metrics.statement_details.plan_collection.period": {}, + + // removed as of 25.2 + "kv.snapshot_receiver.excise.enabled": {}, + "kv.mvcc_gc.queue_kv_admission_control.enabled": {}, + "sql.catalog.experimental_use_session_based_leasing": {}, + "bulkio.backup.merge_file_buffer_size": {}, + "changefeed.new_webhook_sink_enabled": {}, + "changefeed.new_webhook_sink.enabled": {}, + "changefeed.new_pubsub_sink_enabled": {}, + "changefeed.new_pubsub_sink.enabled": {}, + "logical_replication.consumer.use_implicit_txns.enabled": {}, +} + +// grandfatheredDefaultSettings is the list of "grandfathered" existing sql.defaults +// cluster settings. In 22.2 and later, new session settings do not need an +// associated sql.defaults cluster setting (see the `vector_search_beam_size` +// setting in vars.go for an example). A session setting can have its default +// changed with ALTER ROLE ... SET, similar to this (the example assumes that +// all roles should use the new default): +// +// ALTER ROLE ALL SET vector_search_beam_size=128; +// +// Caveat: in some cases, we may still add new sql.defaults cluster settings, +// but the new ones *must* be marked as non-public. Undocumented settings are +// excluded from the check that prevents new sql.defaults settings. The +// reason for this is that the rollout automation framework used in +// CockroachCloud works by using cluster settings. If we want to slowly roll out +// a feature that is gated behind a session setting, using a non-public +// sql.defaults cluster setting is the recommended way to do so. +var grandfatheredDefaultSettings = map[InternalKey]struct{}{ + // PLEASE DO NOT ADD NEW SETTINGS TO THIS MAP. THANK YOU. + "sql.defaults.cost_scans_with_default_col_size.enabled": {}, + "sql.defaults.datestyle": {}, + "sql.defaults.datestyle.enabled": {}, + "sql.defaults.deadlock_timeout": {}, + "sql.defaults.default_hash_sharded_index_bucket_count": {}, + "sql.defaults.default_int_size": {}, + "sql.defaults.disallow_full_table_scans.enabled": {}, + "sql.defaults.distsql": {}, + "sql.defaults.experimental_alter_column_type.enabled": {}, + "sql.defaults.experimental_auto_rehoming.enabled": {}, + "sql.defaults.experimental_computed_column_rewrites": {}, + "sql.defaults.experimental_distsql_planning": {}, + "sql.defaults.experimental_enable_unique_without_index_constraints.enabled": {}, + "sql.defaults.experimental_implicit_column_partitioning.enabled": {}, + "sql.defaults.experimental_temporary_tables.enabled": {}, + "sql.defaults.foreign_key_cascades_limit": {}, + "sql.defaults.idle_in_session_timeout": {}, + "sql.defaults.idle_in_transaction_session_timeout": {}, + "sql.defaults.implicit_select_for_update.enabled": {}, + "sql.defaults.insert_fast_path.enabled": {}, + "sql.defaults.intervalstyle": {}, + "sql.defaults.intervalstyle.enabled": {}, + "sql.defaults.large_full_scan_rows": {}, + "sql.defaults.locality_optimized_partitioned_index_scan.enabled": {}, + "sql.defaults.lock_timeout": {}, + "sql.defaults.multiregion_placement_policy.enabled": {}, + "sql.defaults.on_update_rehome_row.enabled": {}, + "sql.defaults.optimizer_use_histograms.enabled": {}, + "sql.defaults.optimizer_use_multicol_stats.enabled": {}, + "sql.defaults.override_alter_primary_region_in_super_region.enabled": {}, + "sql.defaults.override_multi_region_zone_config.enabled": {}, + "sql.defaults.prefer_lookup_joins_for_fks.enabled": {}, + "sql.defaults.primary_region": {}, + "sql.defaults.propagate_input_ordering.enabled": {}, + "sql.defaults.reorder_joins_limit": {}, + "sql.defaults.require_explicit_primary_keys.enabled": {}, + "sql.defaults.results_buffer.size": {}, + "sql.defaults.serial_normalization": {}, + "sql.defaults.serial_sequences_cache_size": {}, + "sql.defaults.statement_timeout": {}, + "sql.defaults.stub_catalog_tables.enabled": {}, + "sql.defaults.super_regions.enabled": {}, + "sql.defaults.transaction_rows_read_err": {}, + "sql.defaults.transaction_rows_read_log": {}, + "sql.defaults.transaction_rows_written_err": {}, + "sql.defaults.transaction_rows_written_log": {}, + "sql.defaults.use_declarative_schema_changer": {}, + "sql.defaults.vectorize": {}, + "sql.defaults.zigzag_join.enabled": {}, +} + +// checkNameFound verifies whether the given string is known as key or name. +func checkNameFound(keyOrName string) { + if _, ok := retiredSettings[InternalKey(keyOrName)]; ok { + panic(fmt.Sprintf("cannot reuse previously defined setting key: %s", InternalKey(keyOrName))) + } + if _, ok := registry[InternalKey(keyOrName)]; ok { + panic(fmt.Sprintf("setting already defined: %s", keyOrName)) + } + if a, ok := aliasRegistry[SettingName(keyOrName)]; ok { + panic(fmt.Sprintf("setting already defined: %s (with key %s)", keyOrName, a.key)) + } +} + +// register adds a setting to the registry. +func register(class Class, key InternalKey, desc string, s internalSetting) { + checkNameFound(string(key)) + if strings.Contains(string(key), "sql.defaults") { + _, grandfathered := grandfatheredDefaultSettings[key] + if !grandfathered && s.Visibility() != Reserved { + panic(fmt.Sprintf( + "new sql.defaults cluster settings: %s is not needed now that `ALTER ROLE ... SET` syntax "+ + "is supported; please remove the new sql.defaults cluster setting or make it non-public", key)) + } + } + + slot := slotIdx(len(registry)) + s.init(class, key, desc, slot) + registry[key] = s + slotTable[slot] = s + if class == SystemVisible { + tenantReadOnlyKeys = append(tenantReadOnlyKeys, key) + } +} + +func registerAlias(key InternalKey, name SettingName, nameStatus NameStatus) { + checkNameFound(string(name)) + aliasRegistry[name] = aliasEntry{key: key, active: nameStatus} +} + +// NumRegisteredSettings returns the number of registered settings. +func NumRegisteredSettings() int { return len(registry) } + +// Keys returns a sorted string array with all the known keys. +func Keys(forSystemTenant bool) (res []InternalKey) { + res = make([]InternalKey, 0, len(registry)) + for k, v := range registry { + if v.isRetired() { + continue + } + if !forSystemTenant && v.Class() == SystemOnly { + continue + } + res = append(res, k) + } + sort.Slice(res, func(i, j int) bool { return res[i] < res[j] }) + return res +} + +// SystemVisibleKeys returns a array with all the known keys that +// have the class SystemVisible. It might not be sorted. +// The caller must refrain from modifying the return value. +func SystemVisibleKeys() []InternalKey { + return tenantReadOnlyKeys +} + +// ConsoleKeys return an array with all cluster settings keys +// used by the UI Console. +// This list should only contain settings that have no sensitive +// information, because it will be returned on `settings` endpoint for +// users without VIEWCLUSTERSETTING or MODIFYCLUSTERSETTING permission, +// but that have VIEWACTIVITY or VIEWACTIVITYREDACTED permissions. +func ConsoleKeys() (res []InternalKey) { + return allConsoleKeys +} + +var allConsoleKeys = []InternalKey{ + "keyvisualizer.enabled", + "keyvisualizer.sample_interval", + "sql.index_recommendation.drop_unused_duration", + "sql.insights.anomaly_detection.latency_threshold", + "sql.insights.high_retry_count.threshold", + "sql.insights.latency_threshold", + "sql.stats.automatic_collection.enabled", + "timeseries.storage.resolution_10s.ttl", + "timeseries.storage.resolution_30m.ttl", + "ui.display_timezone", + "version", +} + +// NameToKey returns the key associated with a setting name. +func NameToKey(name SettingName) (key InternalKey, found bool, nameStatus NameStatus) { + // First check the alias registry. + if alias, ok := aliasRegistry[name]; ok { + return alias.key, true, alias.active + } + // No alias: did they perhaps use the key directly? + maybeKey := InternalKey(name) + if s, ok := registry[maybeKey]; ok { + nameStatus := NameActive + if s.Name() != SettingName(maybeKey) { + // The user is invited to use the new name instead of the key. + nameStatus = NameRetired + } + return maybeKey, true, nameStatus + } + return "", false, NameActive +} + +// LookupForLocalAccess returns a NonMaskedSetting by name. Used when a setting +// is being retrieved for local processing within the cluster and not for +// reporting; sensitive values are accessible. +func LookupForLocalAccess( + name SettingName, forSystemTenant bool, +) (NonMaskedSetting, bool, NameStatus) { + key, ok, nameStatus := NameToKey(name) + if !ok { + return nil, ok, nameStatus + } + s, ok := LookupForLocalAccessByKey(key, forSystemTenant) + return s, ok, nameStatus +} + +// LookupForLocalAccessByKey returns a NonMaskedSetting by key. Used when a +// setting is being retrieved for local processing within the cluster and not +// for reporting; sensitive values are accessible. +func LookupForLocalAccessByKey(key InternalKey, forSystemTenant bool) (NonMaskedSetting, bool) { + s, ok := registry[key] + if !ok { + return nil, false + } + if !forSystemTenant && s.Class() == SystemOnly { + return nil, false + } + return s, true +} + +// LookupForReportingByKey returns a Setting by key. Used when a setting is being +// retrieved for reporting. +// +// For settings that are non-reportable, the returned Setting hides the current +// value (see Setting.String). +func LookupForReportingByKey(key InternalKey, forSystemTenant bool) (Setting, bool) { + s, ok := registry[key] + if !ok { + return nil, false + } + if !forSystemTenant && s.Class() == SystemOnly { + return nil, false + } + if !s.isReportable() { + return &MaskedSetting{setting: s}, true + } + return s, true +} + +// LookupForDisplay returns a Setting by key. Used when a setting is being +// retrieved for display in SHOW commands or crdb_internal tables. +// +// For settings that are sensitive, the returned Setting hides the current +// value (see Setting.String) if canViewSensitive is false. +func LookupForDisplay( + name SettingName, forSystemTenant, canViewSensitive bool, +) (Setting, bool, NameStatus) { + key, ok, nameStatus := NameToKey(name) + if !ok { + return nil, ok, nameStatus + } + s, ok := LookupForDisplayByKey(key, forSystemTenant, canViewSensitive) + return s, ok, nameStatus +} + +// LookupForDisplayByKey returns a Setting by key. Used when a setting is being +// retrieved for display in SHOW commands or crdb_internal tables. +// +// For settings that are sensitive, the returned Setting hides the current +// value (see Setting.String) if canViewSensitive is false. +func LookupForDisplayByKey( + key InternalKey, forSystemTenant, canViewSensitive bool, +) (Setting, bool) { + s, ok := registry[key] + if !ok { + return nil, false + } + if !forSystemTenant && s.Class() == SystemOnly { + return nil, false + } + if s.isSensitive() && !canViewSensitive { + return &MaskedSetting{setting: s}, true + } + return s, true +} + +// ForSystemTenant can be passed to Lookup for code that runs only on the system +// tenant. +const ForSystemTenant = true + +// ForVirtualCluster can be passed to Lookup for code that runs on +// virtual clusters. +const ForVirtualCluster = false + +// ReadableTypes maps our short type identifiers to friendlier names. +var ReadableTypes = map[string]string{ + "s": "string", + "i": "integer", + "f": "float", + "b": "boolean", + "z": "byte size", + "d": "duration", + "e": "enumeration", + // This is named "m" (instead of "v") for backwards compatibility reasons. + "m": "version", + "p": "protobuf", +} + +// RedactedValue returns: +// - a string representation of the value, if the setting is reportable; +// - "" if the setting is not reportable, sensitive, or a string; +// - "" if there is no setting with this name. +func RedactedValue(key InternalKey, values *Values, forSystemTenant bool) string { + if k, ok := registry[key]; ok { + if k.Typ() == "s" || k.isSensitive() || !k.isReportable() { + return "" + } + } + if setting, ok := LookupForReportingByKey(key, forSystemTenant); ok { + return setting.String(values) + } + return "" +} + +// TestingListPrevAppSettings is exported for testing only. +func TestingListPrevAppSettings() map[InternalKey]struct{} { + return systemSettingsWithPreviousApplicationClass +} diff --git a/pkg/settings/setting.go b/pkg/settings/setting.go new file mode 100644 index 0000000..43763e4 --- /dev/null +++ b/pkg/settings/setting.go @@ -0,0 +1,333 @@ +// Copyright 2017 The Cockroach Authors. +// +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. + +package settings + +import ( + "context" + "fmt" +) + +// SettingName represents the user-visible name of a cluster setting. +// The name is suitable for: +// - SHOW/SET CLUSTER SETTING. +// - inclusion in error messages. +// +// For internal storage, use the InternalKey type instead. +type SettingName string + +// InternalKey is the internal (storage) key for a cluster setting. +// The internal key is suitable for use with: +// - direct accesses to system.settings. +// - rangefeed logic associated with system.settings. +// - (in unit tests only) interchangeably with the name for SET CLUSTER SETTING. +// +// For user-visible displays, use the SettingName type instead. +type InternalKey string + +// Setting is the interface exposing the metadata for a cluster setting. +// +// The values for the settings are stored separately in Values. This allows +// having a global (singleton) settings registry while allowing potentially +// multiple "instances" (values) for each setting (e.g. for multiple test +// servers in the same process). +type Setting interface { + // Class returns the scope of the setting in multi-tenant scenarios. + Class() Class + + // InternalKey returns the internal key used to store the setting. + // To display the name of the setting (eg. in errors etc) or the + // SET/SHOW CLUSTER SETTING statements, use the Name() method instead. + // + // The internal key is suitable for use with: + // - direct accesses to system.settings. + // - rangefeed logic associated with system.settings. + // - (in unit tests only) interchangeably with the name for SET CLUSTER SETTING. + InternalKey() InternalKey + + // Name is the user-visible (display) name of the setting. + // The name is suitable for: + // - SHOW/SET CLUSTER SETTING. + // - inclusion in error messages. + Name() SettingName + + // Typ returns the short (1 char) string denoting the type of setting. + Typ() string + + // String returns the string representation of the setting's current value. + // It's used when materializing results for `SHOW CLUSTER SETTINGS` or `SHOW + // CLUSTER SETTING `. + // + // If this object implements a non-reportable setting that was retrieved for + // reporting (see LookupForReportingByKey), String hides the actual value. + String(sv *Values) string + + // DefaultString returns the default value for the setting as a string. This + // is the same as calling String on the setting when it was never set. + DefaultString() string + + // Description contains a helpful text explaining what the specific cluster + // setting is for. + Description() string + + // Visibility returns whether the setting is made publicly visible. Reserved + // settings are still accessible to users, but they don't get listed out when + // retrieving all settings. + Visibility() Visibility + + // IsUnsafe returns whether the setting is unsafe, and thus requires + // a special interlock to set. + IsUnsafe() bool + + // ValueOrigin returns the origin of the current value. + ValueOrigin(ctx context.Context, sv *Values) ValueOrigin +} + +// NonMaskedSetting is the exported interface of non-masked settings. A +// non-masked setting provides access to the current value (even if the setting +// is not reportable). +// +// A non-masked setting must not be used in the context of reporting values (see +// LookupForReportingByKey). +type NonMaskedSetting interface { + Setting + + // Encoded returns the encoded representation of the current value of the + // setting. + Encoded(sv *Values) string + + // EncodedDefault returns the encoded representation of the default value of + // the setting. + EncodedDefault() string + + // DecodeToString returns the string representation of the provided + // encoded value. + // This is analogous to loading the setting from storage and + // then calling String() on it, however the setting is not modified. + // The string representation of the default value can be obtained + // by calling EncodedDefault() and then DecodeToString(). + DecodeToString(encoded string) (repr string, err error) + + // SetOnChange installs a callback to be called when a setting's value + // changes. `fn` should avoid doing long-running or blocking work as it is + // called on the goroutine which handles all settings updates. + SetOnChange(sv *Values, fn func(ctx context.Context)) + + // ErrorHint returns a hint message to be displayed to the user when there's + // an error. + ErrorHint() (bool, string) +} + +// Class describes the scope of a setting under cluster +// virtualization. +// +// Guidelines for choosing a class: +// +// - Make sure to read the descriptions below carefully to +// understand the differences in semantics. +// +// - Rules of thumb: +// +// 1. if an end-user may benefit from modifying the setting +// through a SQL connection to a secondary tenant / virtual +// cluster, AND different virtual clusters should be able to use +// different values, the setting should have class +// ApplicationLevel. +// +// 2. if a setting should only be controlled by SREs in a +// multi-tenant deployment or in an organization that wishes to +// shield DB operations from application development, OR the +// behavior of CockroachDB is not well-defined if multiple tenants +// (virtual clusters) use different values concurrently, the +// setting must *not* use class ApplicationLevel. +// +// 3. if and only if a setting relevant to the KV/storage layer +// and whose value is shared across all virtual clusters is ever +// accessed by code in the application layer (SQL execution or +// HTTP handlers), use SystemVisible. +// +// 4. in other cases, use SystemOnly. +type Class int8 + +const ( + // SystemOnly settings are specific to the KV/storage layer and + // cannot be accessed from application layer code (in particular not + // from SQL layer nor HTTP handlers). + // + // As a rule of thumb, use this class if: + // + // - the setting may be accessed from the shared KV/storage layer; + // + // - AND, the setting should only be controllable by SREs (not + // end-users) in a multi-tenant environment, AND the behavior + // of CockroachDB is not well-defined if different virtual + // clusters were to use different values concurrently. + // + // (If this part of the condition does not hold, consider + // ApplicationLevel instead.) + // + // - AND, its value is never needed in the application layer (i.e. + // it is not read from SQL code, HTTP handlers or other code + // that would run in SQL pods in a multi-tenant environment). + // + // (If this part of the condition does not hold, consider + // SystemVisible instead.) + // + // Note: if a setting is only ever accessed in the SQL code + // after it has ascertained that it was running for the system + // interface; and we do not wish to display this setting in the + // list displayed by `SHOW ALL CLUSTER SETTINGS` in virtual + // clusters, the class SystemOnly is suitable. Hence the emphasis + // on "would run in SQL pods" above. + SystemOnly Class = iota + + // SystemVisible settings are specific to the KV/storage layer and + // are also visible to virtual clusters. + // + // As a rule of thumb, use this class if: + // + // - the setting may be accessed from the shared KV/storage layer; + // + // - AND the setting should only be controllable by operators of + // the storage cluster (e.g. SREs in the case of a multi-tenant + // environment) but having the storage cluster's value be + // observable by virtual clusters is desirable. + // + // (If this part of the condition does not hold, consider + // ApplicationLevel instead.) + // + // - AND, its value is sometimes needed in the application layer + // (i.e. it may be read from SQL code, HTTP handlers or other + // code that could run in SQL pods in a multi-tenant environment). + // + // (If this part of the condition does not hold, consider + // SystemOnly instead.) + // + // One use cases is to enable optimizations in the KV client side of + // virtual cluster RPCs. For example, if the storage layer uses a + // setting to decide the size of a response, making the setting + // visible enables the client in virtual cluster code to + // pre-allocate response buffers to match the size they expect to + // receive. + // + // Another use case is KV/storage feature flags, to enable a UX + // improvement in virtual clusters by avoiding requesting + // storage-level functionality when it is not enabled, such as + // rangefeeds and provide a better error message. + // (Without this extra logic, the error reported by KV/storage + // might be hard to read by end-users.) + // + // As a reminder, the setting values observed by a virtual cluster, + // both for its own application settings and those it observes for + // system-visible settings, can be overridden using ALTER VIRTUAL + // CLUSTER SET CLUSTER SETTING. This can be used during e.g. + // troubleshooting, to allow changing the observed value for a + // virtual cluster without a code change. + // + // A setting that is expected to be overridden in regular operation + // to to control application-level behavior is still an application + // setting, and should use the application class; system-visible is + // for use by settings that control the storage layer but need to be + // visible, rather than for settings that control the application + // layer but are intended to be read-only. This latter case should + // use ApplicationLayer, because it controls application behavior, + // and then rely on an override to prevent modification from within + // the virtual cluster. + SystemVisible + + // ApplicationLevel settings are readable and can optionally be + // modified by virtual clusters. + // + // As a rule of thumb, use this class if: + // + // - the setting is never accessed by the shared KV/storage layer; + // + // - AND, any of the following holds: + // + // - end-users may benefit from modifying the setting + // through a SQL connection to a secondary tenant / virtual + // cluster. + // + // (If this part of the condition does not hold, but the other + // part of the condition below does hold, consider still using + // ApplicationLevel and force an override using ALTER VIRTUAL + // CLUSTER SET CLUSTER SETTING. This makes the + // ApplicationLevel setting effectively read-only from the + // virtual cluster's perspective, because system overrides + // cannot be modified by the virtual cluster.) + // + // - OR, different virtual clusters should be able to + // use different values for the setting. + // + // (If this part of the condition does not hold, consider + // SystemOnly or SystemVisible instead.) + // + // Note that each SQL layer has its own copy of ApplicationLevel + // settings; including the system tenant/interface. However, they + // are neatly partitioned such that a given virtual cluster can + // never observe the value set for another virtual cluster nor that + // set for the system tenant/interface. + // + // As a reminder, the setting values observed by a virtual cluster, + // both for its own application settings and those it observes for + // system-visible settings, can be overridden using ALTER VIRTUAL + // CLUSTER SET CLUSTER SETTING. This can be used during e.g. + // troubleshooting, to allow changing the observed value for a + // virtual cluster without a code change. + ApplicationLevel +) + +// Visibility describes how a user should feel confident that they can customize +// the setting. +// +// See the constant definitions below for details. +type Visibility int8 + +const ( + // Reserved - which is the default - indicates that a setting is + // not documented and the CockroachDB team has not developed + // internal experience about the impact of customizing it to other + // values. + // In short: "Use at your own risk." + Reserved Visibility = iota + // Public indicates that a setting is documented, the range of + // possible values yields predictable results, and the CockroachDB + // team is there to assist if issues occur as a result of the + // customization. + // In short: "Go ahead but be careful." + Public +) + +// ValueOrigin indicates the origin of the current value of a setting, e.g. if +// it is coming from the in-code default or an explicit override. +type ValueOrigin uint32 + +const ( + // OriginDefault indicates the value in use is the default value. + OriginDefault ValueOrigin = iota + // OriginExplicitlySet indicates the value is has been set explicitly. + OriginExplicitlySet + // OriginExternallySet indicates the value has been set externally, such as + // via a host-cluster override for this or all tenant(s). + OriginExternallySet + // OriginOverride indicates the value has been set via a test override. + OriginOverride +) + +func (v ValueOrigin) String() string { + if v > OriginOverride { + return fmt.Sprintf("invalid (%d)", v) + } + return [...]string{"default", "override", "external-override", "test-override"}[v] +} + +// SafeValue implements the redact.SafeValue interface. +func (ValueOrigin) SafeValue() {} + +// SafeValue implements the redact.SafeValue interface. +func (SettingName) SafeValue() {} + +// SafeValue implements the redact.SafeValue interface. +func (InternalKey) SafeValue() {} diff --git a/pkg/settings/string.go b/pkg/settings/string.go new file mode 100644 index 0000000..58ae1be --- /dev/null +++ b/pkg/settings/string.go @@ -0,0 +1,149 @@ +// Copyright 2017 The Cockroach Authors. +// +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. + +package settings + +import ( + "context" + + "github.com/cockroachdb/errors" +) + +// StringSetting is the interface of a setting variable that will be +// updated automatically when the corresponding cluster-wide setting +// of type "string" is updated. +type StringSetting struct { + defaultValue string + validateFn func(*Values, string) error + common +} + +var _ internalSetting = &StringSetting{} + +func (s *StringSetting) String(sv *Values) string { + return s.Get(sv) +} + +// Encoded returns the encoded value of the current value of the setting. +func (s *StringSetting) Encoded(sv *Values) string { + return s.String(sv) +} + +// EncodedDefault returns the encoded value of the default value of the setting. +func (s *StringSetting) EncodedDefault() string { + return s.defaultValue +} + +// DecodeToString decodes and renders an encoded value. +func (s *StringSetting) DecodeToString(encoded string) (string, error) { + return encoded, nil +} + +// Typ returns the short (1 char) string denoting the type of setting. +func (*StringSetting) Typ() string { + return "s" +} + +// Default returns default value for setting. +func (s *StringSetting) Default() string { + return s.defaultValue +} + +// DefaultString returns the default value for the setting as a string. +func (s *StringSetting) DefaultString() string { + return s.defaultValue +} + +// Defeat the linter. +var _ = (*StringSetting).Default + +// Get retrieves the string value in the setting. +func (s *StringSetting) Get(sv *Values) string { + loaded := sv.getGeneric(s.slot) + if loaded == nil { + return "" + } + return loaded.(string) +} + +// Validate that a value conforms with the validation function. +func (s *StringSetting) Validate(sv *Values, v string) error { + if s.validateFn != nil { + if err := s.validateFn(sv, v); err != nil { + return err + } + } + return nil +} + +// Override sets the setting to the given value, assuming +// it passes validation. +func (s *StringSetting) Override(ctx context.Context, sv *Values, v string) { + sv.setValueOrigin(ctx, s.slot, OriginOverride) + _ = s.decodeAndSet(ctx, sv, v) + sv.setDefaultOverride(s.slot, v) +} + +func (s *StringSetting) decodeAndSet(ctx context.Context, sv *Values, v string) error { + if err := s.Validate(sv, v); err != nil { + return err + } + if s.Get(sv) != v { + sv.setGeneric(ctx, s.slot, v) + } + return nil +} + +func (s *StringSetting) decodeAndSetDefaultOverride( + ctx context.Context, sv *Values, v string, +) error { + sv.setDefaultOverride(s.slot, v) + return nil +} + +func (s *StringSetting) setToDefault(ctx context.Context, sv *Values) { + // See if the default value was overridden. + if val := sv.getDefaultOverride(s.slot); val != nil { + // As per the semantics of override, these values don't go through + // validation. + _ = s.decodeAndSet(ctx, sv, val.(string)) + return + } + if err := s.decodeAndSet(ctx, sv, s.defaultValue); err != nil { + panic(err) + } +} + +// RegisterStringSetting defines a new setting with type string. +func RegisterStringSetting( + class Class, key InternalKey, desc string, defaultValue string, opts ...SettingOption, +) *StringSetting { + validateFn := func(sv *Values, val string) error { + for _, opt := range opts { + switch { + case opt.commonOpt != nil: + continue + case opt.validateStringFn != nil: + default: + panic(errors.AssertionFailedf("wrong validator type")) + } + if err := opt.validateStringFn(sv, val); err != nil { + return err + } + } + return nil + } + setting := &StringSetting{ + defaultValue: defaultValue, + validateFn: validateFn, + } + // By default all string settings are considered to perhaps contain + // PII and are thus non-reportable (to exclude them from telemetry + // reports). + setting.setReportable(false) + register(class, key, desc, setting) + setting.apply(opts) + return setting +} diff --git a/pkg/settings/updater.go b/pkg/settings/updater.go new file mode 100644 index 0000000..9a5824a --- /dev/null +++ b/pkg/settings/updater.go @@ -0,0 +1,246 @@ +// Copyright 2017 The Cockroach Authors. +// +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. + +package settings + +import ( + "context" + "strconv" + "time" + + "github.com/cockroachdb/cockroachdb-parser/pkg/util/envutil" + "github.com/cockroachdb/cockroachdb-parser/pkg/util/protoutil" + "github.com/cockroachdb/errors" + "github.com/gogo/protobuf/proto" +) + +var ignoreAllUpdates = envutil.EnvOrDefaultBool("COCKROACH_IGNORE_CLUSTER_SETTINGS", false) + +// IsIgnoringAllUpdates returns true if Updaters returned by NewUpdater will +// discard all updates due to the COCKROACH_IGNORE_CLUSTER_SETTINGS var. +func IsIgnoringAllUpdates() bool { + return ignoreAllUpdates +} + +// EncodeDuration encodes a duration in the format of EncodedValue.Value. +func EncodeDuration(d time.Duration) string { + return d.String() +} + +// EncodeBool encodes a bool in the format of EncodedValue.Value. +func EncodeBool(b bool) string { + return strconv.FormatBool(b) +} + +// EncodeInt encodes an int in the format of EncodedValue.Value. +func EncodeInt(i int64) string { + return strconv.FormatInt(i, 10) +} + +// EncodeFloat encodes a float in the format of EncodedValue.Value. +func EncodeFloat(f float64) string { + return strconv.FormatFloat(f, 'G', -1, 64) +} + +// EncodeProtobuf encodes a protobuf in the format of EncodedValue.Value. +func EncodeProtobuf(p protoutil.Message) string { + data := make([]byte, p.Size()) + if _, err := p.MarshalTo(data); err != nil { + panic(errors.Wrapf(err, "encoding %s: %+v", proto.MessageName(p), p)) + } + return string(data) +} + +type updater struct { + sv *Values + m map[InternalKey]struct{} +} + +// Updater is a helper for updating the in-memory settings. +// +// RefreshSettings passes the serialized representations of all individual +// settings -- e.g. the rows read from the system.settings table. We update the +// wrapped atomic settings values as we go and note which settings were updated, +// then set the rest to default in ResetRemaining(). +type Updater interface { + // Set is used by tests to configure overrides in a generic fashion. + Set(ctx context.Context, key InternalKey, value EncodedValue) error + // SetToDefault resets the setting to its default value. + SetToDefault(ctx context.Context, key InternalKey) error + + // ResetRemaining loads the values from build-time defaults for all + // settings that were not updated by Set() and SetFromStorage(). + ResetRemaining(ctx context.Context) + + // SetFromStorage is called by the settings watcher to update the + // settings from either the rangefeed over system.settings, or + // overrides coming in over the network from the system tenant. + SetFromStorage(ctx context.Context, key InternalKey, value EncodedValue, origin ValueOrigin) error +} + +// A NoopUpdater ignores all updates. +type NoopUpdater struct{} + +// Set implements Updater. It is a no-op. +func (u NoopUpdater) Set(ctx context.Context, key InternalKey, value EncodedValue) error { return nil } + +// ResetRemaining implements Updater. It is a no-op. +func (u NoopUpdater) ResetRemaining(context.Context) {} + +// SetToDefault implements Updater. It is a no-op. +func (u NoopUpdater) SetToDefault(ctx context.Context, key InternalKey) error { return nil } + +// SetFromStorage implements Updater. It is a no-op. +func (u NoopUpdater) SetFromStorage( + ctx context.Context, key InternalKey, value EncodedValue, origin ValueOrigin, +) error { + return nil +} + +// NewUpdater makes an Updater. +func NewUpdater(sv *Values) Updater { + if ignoreAllUpdates { + return NoopUpdater{} + } + return updater{ + sv: sv, + m: make(map[InternalKey]struct{}), + } +} + +// getSetting determines whether the target setting can be set or +// overridden. +func (u updater) getSetting(key InternalKey, value EncodedValue) (internalSetting, error) { + d, ok := registry[key] + if !ok { + if _, ok := retiredSettings[key]; ok { + return nil, nil + } + // Likely a new setting this old node doesn't know about. + return nil, errors.Errorf("unknown setting '%s'", key) + } + return d, nil +} + +func checkType(d internalSetting, value EncodedValue) error { + if expected := d.Typ(); value.Type != expected { + return errors.Errorf("setting '%s' defined as type %s, not %s", d.Name(), expected, value.Type) + } + return nil +} + +// Set attempts update a setting and notes that it was updated. +func (u updater) Set(ctx context.Context, key InternalKey, value EncodedValue) error { + d, err := u.getSetting(key, value) + if err != nil || d == nil { + return err + } + + return u.setInternal(ctx, key, value, d, OriginExplicitlySet) +} + +// setInternal is the shared code between Set() and SetFromStorage(). +// It propagates the given value to the in-RAM store and keeps track +// of the origin of the value. +func (u updater) setInternal( + ctx context.Context, key InternalKey, value EncodedValue, d internalSetting, origin ValueOrigin, +) error { + // Mark the setting as modified, such that + // (updater).ResetRemaining() does not touch it. + u.m[key] = struct{}{} + + if err := checkType(d, value); err != nil { + return err + } + u.sv.setValueOrigin(ctx, d.getSlot(), origin) + return d.decodeAndSet(ctx, u.sv, value.Value) +} + +func (u updater) SetToDefault(ctx context.Context, key InternalKey) error { + d, ok := registry[key] + if !ok { + if _, ok := retiredSettings[key]; ok { + return nil + } + // Likely a new setting this old node doesn't know about. + return errors.Errorf("unknown setting '%s'", key) + } + + u.m[key] = struct{}{} + u.sv.setValueOrigin(ctx, d.getSlot(), OriginDefault) + d.setToDefault(ctx, u.sv) + return nil +} + +// ResetRemaining sets all settings not explicitly set via this +// updater to their default values. +func (u updater) ResetRemaining(ctx context.Context) { + for _, v := range registry { + if u.sv.SpecializedToVirtualCluster() && v.Class() == SystemOnly { + // Don't try to reset system settings on a non-system tenant. + continue + } + if _, setInThisUpdater := u.m[v.InternalKey()]; !setInThisUpdater && + // We need to preserve test overrides. + u.sv.getValueOrigin(ctx, v.getSlot()) != OriginOverride { + u.sv.setValueOrigin(ctx, v.getSlot(), OriginDefault) + v.setToDefault(ctx, u.sv) + } + } +} + +// SetFromStorage loads the stored value into the setting. +func (u updater) SetFromStorage( + ctx context.Context, key InternalKey, value EncodedValue, origin ValueOrigin, +) error { + d, err := u.getSetting(key, value) + if err != nil || d == nil { + return err + } + + if !u.sv.SpecializedToVirtualCluster() /* system tenant */ || + d.Class() == ApplicationLevel { + // The value is being loaded from the current virtual cluster's + // system.settings. Load it as an active value. + return u.setInternal(ctx, key, value, d, origin) + } + + // Here we are looking at a SystemVisible or SystemOnly setting + // from within a virtual cluster. + + if d.Class() == SystemOnly { + // Attempting to load a SystemOnly setting from a virtual + // cluster's system.settings table. + // + // This is always invalid. The caller should have prevented this + // point from being reached, so this is really protection against + // API misuse. + return errors.AssertionFailedf("programming error: cannot set SystemOnly %q", key) + } + + if d.Class() != SystemVisible { + return errors.AssertionFailedf("unhandled class %v", d.Class()) + } + + if err := checkType(d, value); err != nil { + return err + } + + defer func() { + // After the code below sets the default value, we ensure that the + // new default is also copied to the in-RAM store for all settings + // that didn't have an active value in the virtual cluster yet. + if u.sv.getValueOrigin(ctx, d.getSlot()) == OriginDefault { + d.setToDefault(ctx, u.sv) + } + }() + + // We are receiving an alternate default for a SystemVisible + // setting. Here we do not configure the main setting value (via + // setInternal or .set on the setting itself): many tests use + // .Override earlier and we do not want to change the override. + // Instead, we update the default. + return d.decodeAndSetDefaultOverride(ctx, u.sv, value.Value) +} diff --git a/pkg/settings/values.go b/pkg/settings/values.go new file mode 100644 index 0000000..59b681a --- /dev/null +++ b/pkg/settings/values.go @@ -0,0 +1,307 @@ +// Copyright 2021 The Cockroach Authors. +// +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. + +package settings + +import ( + "context" + "sync/atomic" + + "github.com/cockroachdb/cockroachdb-parser/pkg/util/buildutil" + "github.com/cockroachdb/cockroachdb-parser/pkg/util/syncutil" + "github.com/cockroachdb/errors" +) + +// MaxSettings is the maximum number of settings that the system supports. +// Exported for tests. +const MaxSettings = 1023 + +// Values is a container that stores values for all registered settings. +// Each setting is assigned a unique slot (up to MaxSettings). +// Note that slot indices are 1-based (this is to trigger panics if an +// uninitialized slot index is used). +type Values struct { + container valuesContainer + + classCheck classCheck + + defaultOverridesMu struct { + syncutil.Mutex + + // defaultOverrides maintains the set of overridden default values (see + // Override()). + defaultOverrides map[slotIdx]interface{} + } + + changeMu struct { + syncutil.Mutex + // NB: any in place modification to individual slices must also hold the + // lock, e.g. if we ever add RemoveOnChange or something. + onChange [MaxSettings][]func(ctx context.Context) + } + // opaque is an arbitrary object that can be set by a higher layer to make it + // accessible from certain callbacks (like state machine transformers). + opaque interface{} +} + +type classCheck uint32 + +const ( + // classCheckUndefined is used when the settings.Values hasn't been + // specialized yet. + classCheckUndefined classCheck = iota + // classCheckSystemInterface is used when the settings.Values is + // specialized for the system interface and SystemOnly settings can + // be used. + classCheckSystemInterface + // classCheckVirtualCluster is used when the settings.Values is + // specialized for a virtual cluster and SystemOnly settings cannot + // be used. + classCheckVirtualCluster +) + +func (ck *classCheck) get() classCheck { + return classCheck(atomic.LoadUint32((*uint32)(ck))) +} + +func (ck *classCheck) set(nv classCheck) { + atomic.StoreUint32((*uint32)(ck), uint32(nv)) +} + +const numSlots = MaxSettings + 1 + +type valuesContainer struct { + intVals [numSlots]int64 + genericVals [numSlots]atomic.Value + + // If forbidden[slot] is true, that setting is not allowed to be used from the + // current context (i.e. it is a SystemOnly setting and the container is for a + // tenant). Reading or writing such a setting causes panics in test builds. + forbidden [numSlots]bool + + // hasValue contains the origin of the current value of the setting. + hasValue [numSlots]uint32 +} + +func (c *valuesContainer) setGenericVal(slot slotIdx, newVal interface{}) { + if !c.checkForbidden(slot) { + return + } + c.genericVals[slot].Store(newVal) +} + +func (c *valuesContainer) setInt64Val(slot slotIdx, newVal int64) (changed bool) { + if !c.checkForbidden(slot) { + return false + } + return atomic.SwapInt64(&c.intVals[slot], newVal) != newVal +} + +func (c *valuesContainer) getInt64(slot slotIdx) int64 { + c.checkForbidden(slot) + return atomic.LoadInt64(&c.intVals[slot]) +} + +func (c *valuesContainer) getGeneric(slot slotIdx) interface{} { + c.checkForbidden(slot) + return c.genericVals[slot].Load() +} + +// checkForbidden checks if the setting in the given slot is allowed to be used +// from the current context. If not, it panics in test builds and returns false +// in non-test builds. +func (c *valuesContainer) checkForbidden(slot slotIdx) bool { + if c.forbidden[slot] { + if buildutil.CrdbTestBuild { + const msg = `programming error: invalid access to SystemOnly setting %s from a virtual cluster! + +TIP: use class ApplicationLevel for settings that configure just 1 +virtual cluster; SystemOnly for settings that affect only the shared +storage layer; and SystemVisible for settings that affect the storage +layer and also must be visible to all virtual clusters. +` + panic(errors.AssertionFailedf(msg, slotTable[slot].Name())) + } + return false + } + return true +} + +type testOpaqueType struct{} + +// TestOpaque can be passed to Values.Init when we are testing the settings +// infrastructure. +var TestOpaque interface{} = testOpaqueType{} + +// Init must be called before using a Values instance; it initializes all +// variables to their defaults. +// +// The opaque argument can be retrieved later via Opaque(). +func (sv *Values) Init(ctx context.Context, opaque interface{}) { + sv.opaque = opaque + for _, s := range registry { + s.setToDefault(ctx, sv) + } +} + +const alreadySpecializedError = `programming error: setting value container is already specialized! + +TIP: avoid using the same cluster.Settings or settings.Value object across multiple servers. +` + +// SpecializeForSystemInterface marks the values container as +// pertaining to the system interface. +func (sv *Values) SpecializeForSystemInterface() { + if ck := sv.classCheck.get(); ck != classCheckUndefined && ck != classCheckSystemInterface { + panic(errors.AssertionFailedf(alreadySpecializedError)) + } + sv.classCheck.set(classCheckSystemInterface) +} + +// SpecializeForVirtualCluster marks this container as pertaining to +// a virtual cluster, after which use of SystemOnly values is +// disallowed. +func (sv *Values) SpecializeForVirtualCluster() { + if ck := sv.classCheck.get(); ck != classCheckUndefined && ck != classCheckVirtualCluster { + panic(errors.AssertionFailedf(alreadySpecializedError)) + } + sv.classCheck.set(classCheckVirtualCluster) + for slot, setting := range slotTable { + if setting != nil && setting.Class() == SystemOnly { + sv.container.forbidden[slot] = true + } + } +} + +// SpecializedToVirtualCluster returns true if this container is for a +// virtual cluster (i.e. SpecializeToVirtualCluster() was called). +func (sv *Values) SpecializedToVirtualCluster() bool { + return sv.classCheck.get() == classCheckVirtualCluster +} + +// Opaque returns the argument passed to Init. +func (sv *Values) Opaque() interface{} { + return sv.opaque +} + +func (sv *Values) settingChanged(ctx context.Context, slot slotIdx) { + sv.changeMu.Lock() + funcs := sv.changeMu.onChange[slot] + sv.changeMu.Unlock() + for _, fn := range funcs { + fn(ctx) + } +} + +func (sv *Values) setInt64(ctx context.Context, slot slotIdx, newVal int64) { + if sv.container.setInt64Val(slot, newVal) { + sv.settingChanged(ctx, slot) + } +} + +func (sv *Values) setValueOrigin(ctx context.Context, slot slotIdx, origin ValueOrigin) { + atomic.StoreUint32(&sv.container.hasValue[slot], uint32(origin)) +} + +func (sv *Values) getValueOrigin(ctx context.Context, slot slotIdx) ValueOrigin { + return ValueOrigin(atomic.LoadUint32(&sv.container.hasValue[slot])) +} + +// setDefaultOverride overrides the default value for the respective setting to +// newVal. +func (sv *Values) setDefaultOverride(slot slotIdx, newVal interface{}) { + sv.defaultOverridesMu.Lock() + defer sv.defaultOverridesMu.Unlock() + if sv.defaultOverridesMu.defaultOverrides == nil { + sv.defaultOverridesMu.defaultOverrides = make(map[slotIdx]interface{}) + } + sv.defaultOverridesMu.defaultOverrides[slot] = newVal +} + +// getDefaultOverrides checks whether there's a default override for slotIdx-1 +// and returns it (or nil if there is no override). +func (sv *Values) getDefaultOverride(slot slotIdx) interface{} { + sv.defaultOverridesMu.Lock() + defer sv.defaultOverridesMu.Unlock() + return sv.defaultOverridesMu.defaultOverrides[slot] +} + +func (sv *Values) setGeneric(ctx context.Context, slot slotIdx, newVal interface{}) { + sv.container.setGenericVal(slot, newVal) + sv.settingChanged(ctx, slot) +} + +func (sv *Values) getInt64(slot slotIdx) int64 { + return sv.container.getInt64(slot) +} + +func (sv *Values) getGeneric(slot slotIdx) interface{} { + return sv.container.getGeneric(slot) +} + +// setOnChange installs a callback to be called when a setting's value changes. +// `fn` should avoid doing long-running or blocking work as it is called on the +// goroutine which handles all settings updates. +func (sv *Values) setOnChange(slot slotIdx, fn func(ctx context.Context)) { + sv.changeMu.Lock() + sv.changeMu.onChange[slot] = append(sv.changeMu.onChange[slot], fn) + sv.changeMu.Unlock() +} + +// TestingCopyForVirtualCluster makes a copy of the input Values in +// the target Values for use when initializing a server for a virtual +// cluster in tests. This is meant to propagate overrides +// to ApplicationLevel settings. +func (sv *Values) TestingCopyForVirtualCluster(input *Values) { + for slot := slotIdx(0); slot < slotIdx(len(registry)); slot++ { + s := slotTable[slot] + if s.Class() != ApplicationLevel && s.Class() != SystemVisible { + continue + } + // This test-only method is used when creating new virtual clusters which + // initialize their own version and thus do not want an existing version. + if s.Typ() == VersionSettingValueType { + continue + } + + // Copy the value. + sv.container.intVals[slot] = atomic.LoadInt64(&input.container.intVals[slot]) + if v := input.container.genericVals[slot].Load(); v != nil { + sv.container.genericVals[slot].Store(v) + } + + // Copy the default. + input.defaultOverridesMu.Lock() + v, hasVal := input.defaultOverridesMu.defaultOverrides[slot] + input.defaultOverridesMu.Unlock() + if !hasVal { + continue + } + sv.setDefaultOverride(slot, v) + } +} + +// TestingCopyForServer makes a copy of the input Values in the target Values +// for use when initializing a server in a test cluster. This is meant to +// propagate initial values and overrides. +func (sv *Values) TestingCopyForServer(input *Values, newOpaque interface{}) { + sv.opaque = newOpaque + for slot := slotIdx(0); slot < slotIdx(len(registry)); slot++ { + // Copy the value. + sv.container.intVals[slot] = atomic.LoadInt64(&input.container.intVals[slot]) + if v := input.container.genericVals[slot].Load(); v != nil { + sv.container.genericVals[slot].Store(v) + } + + // Copy the default. + input.defaultOverridesMu.Lock() + v, hasVal := input.defaultOverridesMu.defaultOverrides[slot] + input.defaultOverridesMu.Unlock() + if !hasVal { + continue + } + sv.setDefaultOverride(slot, v) + } +} diff --git a/pkg/settings/version.go b/pkg/settings/version.go new file mode 100644 index 0000000..10d3b3d --- /dev/null +++ b/pkg/settings/version.go @@ -0,0 +1,190 @@ +// Copyright 2020 The Cockroach Authors. +// +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. + +package settings + +import ( + "context" + "fmt" +) + +// VersionSetting is the setting type that allows users to control the cluster +// version. It starts off at an initial version and takes into account the +// current version to validate proposed updates. This is (necessarily) tightly +// coupled with the setting implementation in pkg/clusterversion, and it's done +// through the VersionSettingImpl interface. We rely on the implementation to +// decode to and from raw bytes, and to perform the validation itself. The +// VersionSetting itself is then just the tiny shim that lets us hook into the +// rest of the settings machinery (by interfacing with Values, to load and store +// cluster versions). +// +// TODO(irfansharif): If the cluster version is no longer backed by gossip, +// maybe we should stop pretending it's a regular gossip-backed cluster setting. +// We could introduce new syntax here to motivate this shift. +type VersionSetting struct { + impl VersionSettingImpl + common +} + +var _ internalSetting = &VersionSetting{} + +// VersionSettingImpl is the interface bridging pkg/settings and +// pkg/clusterversion. See VersionSetting for additional commentary. +type VersionSettingImpl interface { + // Decode takes in an encoded cluster version and returns it as the native + // type (the clusterVersion proto). Except it does it through the + // ClusterVersionImpl to avoid circular dependencies. + Decode(val []byte) (ClusterVersionImpl, error) + + // Validate checks whether an version update is permitted. It takes in the + // old and the proposed new value (both in encoded form). This is called by + // SET CLUSTER SETTING. + ValidateVersionUpgrade(ctx context.Context, sv *Values, oldV, newV []byte) error + + // ValidateBinaryVersions is a subset of Validate. It only checks that the + // current binary supports the proposed version. This is called when the + // version is being communicated to us by a different node (currently + // through gossip). + // + // TODO(irfansharif): Update this comment when we stop relying on gossip to + // propagate version bumps. + ValidateBinaryVersions(ctx context.Context, sv *Values, newV []byte) error + + // SettingsListDefault returns the value that should be presented by + // `./cockroach gen settings-list` + SettingsListDefault() string +} + +// ClusterVersionImpl is used to stub out the dependency on the ClusterVersion +// type (in pkg/clusterversion). The VersionSetting below is used to set +// ClusterVersion values, but we can't import the type directly due to the +// cyclical dependency structure. +type ClusterVersionImpl interface { + fmt.Stringer + + // Encode encodes the ClusterVersion (using the protobuf encoding). + Encode() []byte +} + +// MakeVersionSetting instantiates a version setting instance. See +// VersionSetting for additional commentary. +func MakeVersionSetting(impl VersionSettingImpl) VersionSetting { + return VersionSetting{impl: impl} +} + +// Validate checks whether an version update is permitted. It takes in the +// old and the proposed new value (both in encoded form). This is called by +// SET CLUSTER SETTING. +func (v *VersionSetting) Validate(ctx context.Context, sv *Values, oldV, newV []byte) error { + return v.impl.ValidateVersionUpgrade(ctx, sv, oldV, newV) +} + +// SettingsListDefault returns the value that should be presented by +// `./cockroach gen settings-list`. +func (v *VersionSetting) SettingsListDefault() string { + return v.impl.SettingsListDefault() +} + +// Typ is part of the Setting interface. +func (*VersionSetting) Typ() string { + // This is named "m" (instead of "v") for backwards compatibility reasons. + return VersionSettingValueType +} + +// VersionSettingValueType is the value type string (m originally for +// "migration") used in the system.settings table. +const VersionSettingValueType = "m" + +// String is part of the Setting interface. +func (v *VersionSetting) String(sv *Values) string { + cv := v.GetInternal(sv) + if cv == nil { + panic("unexpected nil value") + } + return cv.String() +} + +// DefaultString returns the default value for the setting as a string. +func (v *VersionSetting) DefaultString() string { + return encodedDefaultVersion +} + +// Encoded is part of the NonMaskedSetting interface. +func (v *VersionSetting) Encoded(sv *Values) string { + cv := v.GetInternal(sv) + if cv == nil { + panic("unexpected nil value") + } + return string(cv.Encode()) +} + +// EncodedDefault is part of the NonMaskedSetting interface. +func (v *VersionSetting) EncodedDefault() string { + return encodedDefaultVersion +} + +const encodedDefaultVersion = "unsupported" + +// DecodeToString decodes and renders an encoded value. +func (v *VersionSetting) DecodeToString(encoded string) (string, error) { + if encoded == encodedDefaultVersion { + return encodedDefaultVersion, nil + } + cv, err := v.impl.Decode([]byte(encoded)) + if err != nil { + return "", err + } + return cv.String(), nil +} + +// GetInternal returns the setting's current value. +func (v *VersionSetting) GetInternal(sv *Values) ClusterVersionImpl { + val := sv.getGeneric(v.slot) + if val == nil { + return nil + } + return val.(ClusterVersionImpl) +} + +// SetInternal updates the setting's value in the provided Values container. +func (v *VersionSetting) SetInternal(ctx context.Context, sv *Values, newVal ClusterVersionImpl) { + sv.setGeneric(ctx, v.slot, newVal) +} + +// setToDefault is part of the internalSetting interface. This is a no-op for +// VersionSetting. They don't have defaults that they can go back to at any +// time. +func (v *VersionSetting) setToDefault(ctx context.Context, sv *Values) {} + +// decodeAndSet is part of the internalSetting interface. We intentionally avoid +// +// We intentionally avoid updating the setting through this code path. The +// specific setting backed by VersionSetting is the cluster version setting, +// changes to which are propagated through direct RPCs to each node in the +// cluster instead of gossip. This is done using the BumpClusterVersion RPC. +func (v *VersionSetting) decodeAndSet(ctx context.Context, sv *Values, encoded string) error { + return nil +} + +// decodeAndSetDefaultOverride is part of the internalSetting interface. +// +// We intentionally avoid updating the setting through this code path. The +// specific setting backed by VersionSetting is the cluster version setting, +// changes to which are propagated through direct RPCs to each node in the +// cluster instead of gossip. This is done using the BumpClusterVersion RPC. +func (v *VersionSetting) decodeAndSetDefaultOverride( + ctx context.Context, sv *Values, encoded string, +) error { + return nil +} + +// RegisterVersionSetting adds the provided version setting to the global +// registry. +func RegisterVersionSetting( + class Class, key InternalKey, desc string, setting *VersionSetting, opts ...SettingOption, +) { + register(class, key, desc, setting) + setting.apply(opts) +} diff --git a/pkg/sql/colexec/execgen/cmd/execgen/agg_gen_util.go b/pkg/sql/colexec/execgen/cmd/execgen/agg_gen_util.go index aa380d2..d0bb631 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/agg_gen_util.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/agg_gen_util.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main @@ -23,15 +18,63 @@ const ( // of aggregator using an aggregate function. It is replaced with "Hash", // "Ordered", or "Window" before executing the template. aggKindTmplVar = "_AGGKIND" + aggNameTmplVar = "_AGGNAME" hashAggKind = "Hash" orderedAggKind = "Ordered" windowAggKind = "Window" ) -func registerAggGenerator(aggGen generator, filenameSuffix, dep string, genWindowVariant bool) { +func registerAggGenerator( + aggGen generator, filenameSuffix, dep, aggName string, genWindowVariant bool, +) { aggGeneratorAdapter := func(aggKind string) generator { return func(inputFileContents string, wr io.Writer) error { + inputFileContents = strings.ReplaceAll(inputFileContents, "var _ = _ALLOC_CODE", ` +// {{if eq "_AGGKIND" "Ordered"}} + +func init() { + // Sanity check the hard-coded number of overloads. + var numOverloads int + // {{range .}} + // {{range .WidthOverloads}} + numOverloads++ + // {{end}} + // {{end}} + if numOverloads != _AGGNAMENumOverloads { + colexecerror.InternalError(errors.AssertionFailedf( + "_AGGNAMENumOverloads should be updated: expected %d, found %d", numOverloads, _AGGNAMENumOverloads, + )) + } +} + +// _AGGNAMEOverloadOffset returns the offset for this particular type overload +// within contiguous slice of allocators for this aggregate function. +func _AGGNAMEOverloadOffset(t *types.T) int { + var offset int + canonicalTypeFamily := typeconv.TypeFamilyToCanonicalTypeFamily(t.Family()) + // {{range .}} + if canonicalTypeFamily == _CANONICAL_TYPE_FAMILY { + // {{range .WidthOverloads}} + // {{if eq .Width -1}} + return offset + // {{else}} + if t.Width() == {{.Width}} { + return offset + } + offset++ + // {{end}} + // {{end}} + } + offset += {{len .WidthOverloads}} + // {{end}} + colexecerror.InternalError(errors.AssertionFailedf("didn't find overload offset for %s", t.SQLStringForError())) + return 0 +} + +// {{end}} +`) inputFileContents = strings.ReplaceAll(inputFileContents, aggKindTmplVar, aggKind) + inputFileContents = strings.ReplaceAll(inputFileContents, aggNameTmplVar, aggName) return aggGen(inputFileContents, wr) } } diff --git a/pkg/sql/colexec/execgen/cmd/execgen/and_or_projection_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/and_or_projection_gen.go index 3d9cfdc..55ebcce 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/and_or_projection_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/and_or_projection_gen.go @@ -1,12 +1,7 @@ // Copyright 2019 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main diff --git a/pkg/sql/colexec/execgen/cmd/execgen/any_not_null_agg_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/any_not_null_agg_gen.go index 714c971..d97ea92 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/any_not_null_agg_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/any_not_null_agg_gen.go @@ -1,12 +1,7 @@ // Copyright 2018 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main @@ -46,5 +41,7 @@ func genAnyNotNullAgg(inputFileContents string, wr io.Writer) error { func init() { registerAggGenerator( - genAnyNotNullAgg, "any_not_null_agg.eg.go", anyNotNullAggTmpl, false /* genWindowVariant */) + genAnyNotNullAgg, "any_not_null_agg.eg.go", /* filenameSuffix */ + anyNotNullAggTmpl, "anyNotNull" /* aggName */, false, /* genWindowVariant */ + ) } diff --git a/pkg/sql/colexec/execgen/cmd/execgen/avg_agg_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/avg_agg_gen.go index 9220566..fe470a5 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/avg_agg_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/avg_agg_gen.go @@ -1,12 +1,7 @@ // Copyright 2018 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main @@ -107,7 +102,7 @@ const avgAggTmpl = "pkg/sql/colexec/colexecagg/avg_agg_tmpl.go" func genAvgAgg(inputFileContents string, wr io.Writer) error { r := strings.NewReplacer( - "_TYPE_FAMILY", "{{.TypeFamily}}", + "_CANONICAL_TYPE_FAMILY", "{{.TypeFamily}}", "_TYPE_WIDTH", typeWidthReplacement, "_RET_GOTYPESLICE", `{{.RetGoTypeSlice}}`, "_RET_GOTYPE", `{{.RetGoType}}`, @@ -147,9 +142,10 @@ func genAvgAgg(inputFileContents string, wr io.Writer) error { for _, inputTypeFamily := range []types.Family{types.IntFamily, types.DecimalFamily, types.FloatFamily, types.IntervalFamily} { tmplInfo := avgAggTypeTmplInfo{TypeFamily: familyToString(inputTypeFamily)} for _, inputTypeWidth := range supportedWidthsByCanonicalTypeFamily[inputTypeFamily] { - // Note that we don't use execinfrapb.GetAggregateInfo because we don't - // want to bring in a dependency on that package to reduce the burden - // of regenerating execgen code when the protobufs get generated. + // Note that we don't use execinfrapb.GetAggregateOutputType because + // we don't want to bring in a dependency on that package to reduce + // the burden of regenerating execgen code when the protobufs get + // generated. retTypeFamily, retTypeWidth := inputTypeFamily, inputTypeWidth if inputTypeFamily == types.IntFamily { // Average of integers is a decimal. @@ -174,5 +170,8 @@ func genAvgAgg(inputFileContents string, wr io.Writer) error { } func init() { - registerAggGenerator(genAvgAgg, "avg_agg.eg.go", avgAggTmpl, true /* genWindowVariant */) + registerAggGenerator( + genAvgAgg, "avg_agg.eg.go", /* filenameSuffix */ + avgAggTmpl, "avg" /* aggName */, true, /* genWindowVariant */ + ) } diff --git a/pkg/sql/colexec/execgen/cmd/execgen/bool_and_or_agg_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/bool_and_or_agg_gen.go index e5a3790..b12b2e3 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/bool_and_or_agg_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/bool_and_or_agg_gen.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main @@ -96,5 +91,7 @@ func genBooleanAgg(inputFileContents string, wr io.Writer) error { func init() { registerAggGenerator( - genBooleanAgg, "bool_and_or_agg.eg.go", boolAggTmpl, true /* genWindowVariant */) + genBooleanAgg, "bool_and_or_agg.eg.go", /* filenameSuffix */ + boolAggTmpl, "boolAndOr", true, /* genWindowVariant */ + ) } diff --git a/pkg/sql/colexec/execgen/cmd/execgen/cast_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/cast_gen.go index 8384089..afc7f3a 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/cast_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/cast_gen.go @@ -1,12 +1,7 @@ // Copyright 2019 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main diff --git a/pkg/sql/colexec/execgen/cmd/execgen/cast_gen_util.go b/pkg/sql/colexec/execgen/cmd/execgen/cast_gen_util.go index 757d1db..916e911 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/cast_gen_util.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/cast_gen_util.go @@ -1,12 +1,7 @@ // Copyright 2021 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main @@ -271,7 +266,7 @@ func floatToInt(intWidth, floatWidth int32) castFunc { if math.IsNaN(float64(%[2]s)) || %[2]s <= float%[4]d(math.MinInt%[3]d) || %[2]s >= float%[4]d(math.MaxInt%[3]d) { colexecerror.ExpectedError(tree.ErrIntOutOfRange) } - %[1]s = int%[3]d(%[2]s) + %[1]s = int%[3]d(math.RoundToEven(%[2]s)) ` if intWidth == anyWidth { intWidth = 64 @@ -589,7 +584,8 @@ func getStringToTimestampCastFunc(withoutTimezone bool) castFunc { _roundTo := tree.TimeFamilyPrecisionToRoundDuration(%[4]s.Precision()) _now := %[3]s.GetRelativeParseTime() _dateStyle := %[3]s.GetDateStyle() - _t, _, err := pgdate.ParseTimestamp%[5]s(_now, _dateStyle, string(%[2]s)) + _h := %[3]s.GetDateHelper() + _t, _, err := pgdate.ParseTimestamp%[5]s(_now, _dateStyle, string(%[2]s), _h) if err != nil { colexecerror.ExpectedError(err) } diff --git a/pkg/sql/colexec/execgen/cmd/execgen/concat_agg_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/concat_agg_gen.go index 5b9db05..34da925 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/concat_agg_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/concat_agg_gen.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main @@ -34,5 +29,7 @@ func genConcatAgg(inputFileContents string, wr io.Writer) error { func init() { registerAggGenerator( - genConcatAgg, "concat_agg.eg.go", concatAggTmpl, true /* genWindowVariant */) + genConcatAgg, "concat_agg.eg.go", /* filenameSuffix */ + concatAggTmpl, "concat" /* aggName */, true, /* genWindowVariant */ + ) } diff --git a/pkg/sql/colexec/execgen/cmd/execgen/const_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/const_gen.go index e408539..7354575 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/const_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/const_gen.go @@ -1,12 +1,7 @@ // Copyright 2019 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main diff --git a/pkg/sql/colexec/execgen/cmd/execgen/count_agg_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/count_agg_gen.go index c52a67a..155d538 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/count_agg_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/count_agg_gen.go @@ -1,12 +1,7 @@ // Copyright 2019 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main @@ -56,5 +51,8 @@ func genCountAgg(inputFileContents string, wr io.Writer) error { } func init() { - registerAggGenerator(genCountAgg, "count_agg.eg.go", countAggTmpl, true /* genWindowVariant */) + registerAggGenerator( + genCountAgg, "count_agg.eg.go", /* filenameSuffix */ + countAggTmpl, "count" /* aggName */, true, /* genWindowVariant */ + ) } diff --git a/pkg/sql/colexec/execgen/cmd/execgen/crossjoiner_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/crossjoiner_gen.go index 152b609..103b611 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/crossjoiner_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/crossjoiner_gen.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main diff --git a/pkg/sql/colexec/execgen/cmd/execgen/data_manipulation_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/data_manipulation_gen.go index f08a57d..ff167a1 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/data_manipulation_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/data_manipulation_gen.go @@ -1,12 +1,7 @@ // Copyright 2019 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main diff --git a/pkg/sql/colexec/execgen/cmd/execgen/datum_to_vec_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/datum_to_vec_gen.go index a346b25..e121619 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/datum_to_vec_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/datum_to_vec_gen.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main diff --git a/pkg/sql/colexec/execgen/cmd/execgen/default_agg_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/default_agg_gen.go index ac6126b..40cdc9e 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/default_agg_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/default_agg_gen.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main @@ -35,5 +30,7 @@ func genDefaultAgg(inputFileContents string, wr io.Writer) error { func init() { registerAggGenerator( - genDefaultAgg, "default_agg.eg.go", defaultAggTmpl, false /* genWindowVariant */) + genDefaultAgg, "default_agg.eg.go", /* filenameSuffix */ + defaultAggTmpl, "defaultAgg" /* aggName */, false, /* genWindowVariant */ + ) } diff --git a/pkg/sql/colexec/execgen/cmd/execgen/default_cmp_expr_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/default_cmp_expr_gen.go index b7b6c9f..1f488b5 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/default_cmp_expr_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/default_cmp_expr_gen.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main diff --git a/pkg/sql/colexec/execgen/cmd/execgen/default_cmp_proj_ops_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/default_cmp_proj_ops_gen.go index ccc2cb4..f4e3155 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/default_cmp_proj_ops_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/default_cmp_proj_ops_gen.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main @@ -23,13 +18,8 @@ import ( const defaultCmpProjTemplate = ` // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package {{.TargetPkg}} diff --git a/pkg/sql/colexec/execgen/cmd/execgen/default_cmp_sel_ops_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/default_cmp_sel_ops_gen.go index dce1843..96e0b9d 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/default_cmp_sel_ops_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/default_cmp_sel_ops_gen.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main diff --git a/pkg/sql/colexec/execgen/cmd/execgen/distinct_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/distinct_gen.go index 8bbe3b6..c59a08d 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/distinct_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/distinct_gen.go @@ -1,12 +1,7 @@ // Copyright 2018 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main @@ -28,13 +23,8 @@ import ( const distinctTmpl = ` // Copyright 2018 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package %s diff --git a/pkg/sql/colexec/execgen/cmd/execgen/first_last_nth_value_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/first_last_nth_value_gen.go index c0c4b3e..8df525d 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/first_last_nth_value_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/first_last_nth_value_gen.go @@ -1,12 +1,7 @@ // Copyright 2021 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main diff --git a/pkg/sql/colexec/execgen/cmd/execgen/hash_aggregator_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/hash_aggregator_gen.go index 9c466e2..669a42f 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/hash_aggregator_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/hash_aggregator_gen.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main diff --git a/pkg/sql/colexec/execgen/cmd/execgen/hash_utils_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/hash_utils_gen.go index fff2916..84f4d2e 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/hash_utils_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/hash_utils_gen.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main @@ -25,14 +20,18 @@ func genHashUtils(inputFileContents string, wr io.Writer) error { "_TYPE_WIDTH", typeWidthReplacement, "_TYPE", "{{.VecMethod}}", "TemplateType", "{{.VecMethod}}", + // Currently, github.com/dave/dst library used by execgen doesn't + // support the generics well, so we need to put the generic type clause + // manually. + "func rehash(", "func rehash[T uint32 | uint64](", ) s := r.Replace(inputFileContents) assignHash := makeFunctionRegex("_ASSIGN_HASH", 4) s = assignHash.ReplaceAllString(s, makeTemplateFunctionCall("Global.AssignHash", 4)) - rehash := makeFunctionRegex("_REHASH_BODY", 8) - s = rehash.ReplaceAllString(s, `{{template "rehashBody" buildDict "Global" . "HasSel" $6 "HasNulls" $7 "Uint64" $8}}`) + rehash := makeFunctionRegex("_REHASH_BODY", 7) + s = rehash.ReplaceAllString(s, `{{template "rehashBody" buildDict "Global" . "HasSel" $6 "HasNulls" $7}}`) s = replaceManipulationFuncsAmbiguous(".Global", s) diff --git a/pkg/sql/colexec/execgen/cmd/execgen/hashjoiner_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/hashjoiner_gen.go index 4fd6855..cc3b4d1 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/hashjoiner_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/hashjoiner_gen.go @@ -1,12 +1,7 @@ // Copyright 2018 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main diff --git a/pkg/sql/colexec/execgen/cmd/execgen/hashtable_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/hashtable_gen.go index b45f6bb..dfbc892 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/hashtable_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/hashtable_gen.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main diff --git a/pkg/sql/colexec/execgen/cmd/execgen/is_null_ops_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/is_null_ops_gen.go index 15394fd..0cfaafe 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/is_null_ops_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/is_null_ops_gen.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main diff --git a/pkg/sql/colexec/execgen/cmd/execgen/lead_lag_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/lead_lag_gen.go index 911261b..a14ecba 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/lead_lag_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/lead_lag_gen.go @@ -1,12 +1,7 @@ // Copyright 2021 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main diff --git a/pkg/sql/colexec/execgen/cmd/execgen/like_ops_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/like_ops_gen.go index 93dac85..f205881 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/like_ops_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/like_ops_gen.go @@ -1,12 +1,7 @@ // Copyright 2019 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main @@ -31,13 +26,8 @@ import ( const likeTemplate = ` // Copyright 2019 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package colexec%[1]s diff --git a/pkg/sql/colexec/execgen/cmd/execgen/main.go b/pkg/sql/colexec/execgen/cmd/execgen/main.go index 5760876..acf6c2c 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/main.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/main.go @@ -1,12 +1,7 @@ // Copyright 2018 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main @@ -145,7 +140,7 @@ func (g *execgenTool) generate(path string, entry entry) error { return err } // Delete execgen_template build tag. - inputFileBytes = bytes.ReplaceAll(inputFileBytes, []byte("// +build execgen_template"), []byte{}) + inputFileBytes = bytes.ReplaceAll(inputFileBytes, []byte("//go:build execgen_template"), []byte{}) inputFileContents, err = execgen.Generate(string(inputFileBytes)) if err != nil { return err @@ -164,9 +159,6 @@ func (g *execgenTool) generate(path string, entry entry) error { } b := buf.Bytes() - // Delete execgen_template build tag. - b = bytes.ReplaceAll(b, []byte("//go:build execgen_template"), []byte{}) - b = bytes.ReplaceAll(b, []byte("// +build execgen_template"), []byte{}) // Delete empty comments (/* */) that tend to get generated by templating. // As well as empty line comments that are _not_ at the beginning of a line. diff --git a/pkg/sql/colexec/execgen/cmd/execgen/mergejoinbase_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/mergejoinbase_gen.go index db215b5..e259757 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/mergejoinbase_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/mergejoinbase_gen.go @@ -1,12 +1,7 @@ // Copyright 2019 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main diff --git a/pkg/sql/colexec/execgen/cmd/execgen/mergejoiner_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/mergejoiner_gen.go index ae72707..9920745 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/mergejoiner_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/mergejoiner_gen.go @@ -1,12 +1,7 @@ // Copyright 2019 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main diff --git a/pkg/sql/colexec/execgen/cmd/execgen/min_max_agg_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/min_max_agg_gen.go index 1618bad..1697a22 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/min_max_agg_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/min_max_agg_gen.go @@ -1,12 +1,7 @@ // Copyright 2018 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main @@ -65,5 +60,7 @@ func genMinMaxAgg(inputFileContents string, wr io.Writer) error { func init() { registerAggGenerator( - genMinMaxAgg, "min_max_agg.eg.go", minMaxAggTmpl, true /* genWindowVariant */) + genMinMaxAgg, "min_max_agg.eg.go", /* filenameSuffix */ + minMaxAggTmpl, "minMax" /* aggName */, true, /* genWindowVariant */ + ) } diff --git a/pkg/sql/colexec/execgen/cmd/execgen/min_max_removable_agg_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/min_max_removable_agg_gen.go index 2f2f8bc..4f34729 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/min_max_removable_agg_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/min_max_removable_agg_gen.go @@ -1,12 +1,7 @@ // Copyright 2021 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main diff --git a/pkg/sql/colexec/execgen/cmd/execgen/ntile_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/ntile_gen.go index c284986..687046b 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/ntile_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/ntile_gen.go @@ -1,12 +1,7 @@ // Copyright 2021 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main diff --git a/pkg/sql/colexec/execgen/cmd/execgen/ordered_synchronizer_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/ordered_synchronizer_gen.go index b846859..2e17965 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/ordered_synchronizer_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/ordered_synchronizer_gen.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main diff --git a/pkg/sql/colexec/execgen/cmd/execgen/overloads_abbr.go b/pkg/sql/colexec/execgen/cmd/execgen/overloads_abbr.go index 15cf35d..f77618e 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/overloads_abbr.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/overloads_abbr.go @@ -1,12 +1,7 @@ // Copyright 2021 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main diff --git a/pkg/sql/colexec/execgen/cmd/execgen/overloads_base.go b/pkg/sql/colexec/execgen/cmd/execgen/overloads_base.go index 72c8a82..bed2ca1 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/overloads_base.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/overloads_base.go @@ -1,12 +1,7 @@ // Copyright 2018 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main @@ -855,8 +850,8 @@ var supportedWidthsByCanonicalTypeFamily = map[types.Family][]int32{ var numericCanonicalTypeFamilies = []types.Family{types.IntFamily, types.FloatFamily, types.DecimalFamily} -// toVecMethod returns the method name from coldata.Vec interface that can be -// used to get the well-typed underlying memory from a vector. +// toVecMethod returns the method name from coldata.Vec struct that can be used +// to get the well-typed underlying memory from a vector. func toVecMethod(canonicalTypeFamily types.Family, width int32) string { switch canonicalTypeFamily { case types.BoolFamily: diff --git a/pkg/sql/colexec/execgen/cmd/execgen/overloads_bin.go b/pkg/sql/colexec/execgen/cmd/execgen/overloads_bin.go index 561673e..8fe0351 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/overloads_bin.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/overloads_bin.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main @@ -31,7 +26,7 @@ var binaryOpDecMethod = map[treebin.BinaryOperatorSymbol]string{ treebin.Div: "Quo", treebin.FloorDiv: "QuoInteger", treebin.Mod: "Rem", - treebin.Pow: "Pow", + treebin.Pow: "DecimalPow", } var binaryOpFloatMethod = map[treebin.BinaryOperatorSymbol]string{ @@ -119,7 +114,7 @@ func registerBinOpOutputTypes() { for _, binOp := range []treebin.BinaryOperatorSymbol{treebin.Bitand, treebin.Bitor, treebin.Bitxor} { binOpOutputTypes[binOp] = make(map[typePair]*types.T) populateBinOpIntOutputTypeOnIntArgs(binOp) - binOpOutputTypes[binOp][typePair{typeconv.DatumVecCanonicalTypeFamily, anyWidth, typeconv.DatumVecCanonicalTypeFamily, anyWidth}] = types.Any + binOpOutputTypes[binOp][typePair{typeconv.DatumVecCanonicalTypeFamily, anyWidth, typeconv.DatumVecCanonicalTypeFamily, anyWidth}] = types.AnyElement } // Simple arithmetic binary operators. @@ -162,8 +157,8 @@ func registerBinOpOutputTypes() { types.IntervalFamily, // types.Time + types.Interval } { for _, width := range supportedWidthsByCanonicalTypeFamily[compatibleFamily] { - binOpOutputTypes[treebin.Plus][typePair{typeconv.DatumVecCanonicalTypeFamily, anyWidth, compatibleFamily, width}] = types.Any - binOpOutputTypes[treebin.Plus][typePair{compatibleFamily, width, typeconv.DatumVecCanonicalTypeFamily, anyWidth}] = types.Any + binOpOutputTypes[treebin.Plus][typePair{typeconv.DatumVecCanonicalTypeFamily, anyWidth, compatibleFamily, width}] = types.AnyElement + binOpOutputTypes[treebin.Plus][typePair{compatibleFamily, width, typeconv.DatumVecCanonicalTypeFamily, anyWidth}] = types.AnyElement } } for _, compatibleFamily := range []types.Family{ @@ -173,8 +168,8 @@ func registerBinOpOutputTypes() { types.BytesFamily, // types.Jsonb - types.String } { for _, width := range supportedWidthsByCanonicalTypeFamily[compatibleFamily] { - binOpOutputTypes[treebin.Minus][typePair{typeconv.DatumVecCanonicalTypeFamily, anyWidth, compatibleFamily, width}] = types.Any - binOpOutputTypes[treebin.Minus][typePair{compatibleFamily, width, typeconv.DatumVecCanonicalTypeFamily, anyWidth}] = types.Any + binOpOutputTypes[treebin.Minus][typePair{typeconv.DatumVecCanonicalTypeFamily, anyWidth, compatibleFamily, width}] = types.AnyElement + binOpOutputTypes[treebin.Minus][typePair{compatibleFamily, width, typeconv.DatumVecCanonicalTypeFamily, anyWidth}] = types.AnyElement } } @@ -193,14 +188,14 @@ func registerBinOpOutputTypes() { // Other non-arithmetic binary operators. binOpOutputTypes[treebin.Concat] = map[typePair]*types.T{ {types.BytesFamily, anyWidth, types.BytesFamily, anyWidth}: types.Bytes, - {typeconv.DatumVecCanonicalTypeFamily, anyWidth, typeconv.DatumVecCanonicalTypeFamily, anyWidth}: types.Any, + {typeconv.DatumVecCanonicalTypeFamily, anyWidth, typeconv.DatumVecCanonicalTypeFamily, anyWidth}: types.AnyElement, } for _, binOp := range []treebin.BinaryOperatorSymbol{treebin.LShift, treebin.RShift} { binOpOutputTypes[binOp] = make(map[typePair]*types.T) populateBinOpIntOutputTypeOnIntArgs(binOp) for _, intWidth := range supportedWidthsByCanonicalTypeFamily[types.IntFamily] { - binOpOutputTypes[binOp][typePair{typeconv.DatumVecCanonicalTypeFamily, anyWidth, types.IntFamily, intWidth}] = types.Any + binOpOutputTypes[binOp][typePair{typeconv.DatumVecCanonicalTypeFamily, anyWidth, types.IntFamily, intWidth}] = types.AnyElement } } @@ -327,6 +322,7 @@ func (decimalCustomizer) getBinOpAssignFunc() assignFunc { "Target": targetElem, "Left": leftElem, "Right": rightElem, + "IsPow": binOp == treebin.Pow, } buf := strings.Builder{} t := template.Must(template.New("").Parse(` @@ -336,7 +332,11 @@ func (decimalCustomizer) getBinOpAssignFunc() assignFunc { colexecerror.ExpectedError(tree.ErrDivByZero) } {{end}} + {{if .IsPow -}} + err := eval.{{.Op}}(tree.{{.Ctx}}, &{{.Target}}, &{{.Left}}, &{{.Right}}) + {{else -}} _, err := tree.{{.Ctx}}.{{.Op}}(&{{.Target}}, &{{.Left}}, &{{.Right}}) + {{end -}} if err != nil { colexecerror.ExpectedError(err) } @@ -494,7 +494,7 @@ func (c intCustomizer) getBinOpAssignFunc() assignFunc { var leftTmpDec, rightTmpDec apd.Decimal //gcassert:noescape leftTmpDec.SetInt64(int64({{.Left}})) rightTmpDec.SetInt64(int64({{.Right}})) - if _, err := tree.{{.Ctx}}.Pow(&leftTmpDec, &leftTmpDec, &rightTmpDec); err != nil { + if err := eval.DecimalPow(tree.{{.Ctx}}, &leftTmpDec, &leftTmpDec, &rightTmpDec); err != nil { colexecerror.ExpectedError(err) } resultInt, err := leftTmpDec.Int64() @@ -547,6 +547,7 @@ func (c decimalIntCustomizer) getBinOpAssignFunc() assignFunc { "Target": targetElem, "Left": leftElem, "Right": rightElem, + "IsPow": binOp == treebin.Pow, } buf := strings.Builder{} t := template.Must(template.New("").Parse(` @@ -558,7 +559,11 @@ func (c decimalIntCustomizer) getBinOpAssignFunc() assignFunc { {{end}} var tmpDec apd.Decimal //gcassert:noescape tmpDec.SetInt64(int64({{.Right}})) + {{if .IsPow -}} + if err := eval.{{.Op}}(tree.{{.Ctx}}, &{{.Target}}, &{{.Left}}, &tmpDec); err != nil { + {{else -}} if _, err := tree.{{.Ctx}}.{{.Op}}(&{{.Target}}, &{{.Left}}, &tmpDec); err != nil { + {{end -}} colexecerror.ExpectedError(err) } } @@ -581,6 +586,7 @@ func (c intDecimalCustomizer) getBinOpAssignFunc() assignFunc { "Target": targetElem, "Left": leftElem, "Right": rightElem, + "IsPow": binOp == treebin.Pow, } buf := strings.Builder{} t := template.Must(template.New("").Parse(` @@ -592,7 +598,11 @@ func (c intDecimalCustomizer) getBinOpAssignFunc() assignFunc { {{end}} var tmpDec apd.Decimal //gcassert:noescape tmpDec.SetInt64(int64({{.Left}})) + {{if .IsPow -}} + err := eval.{{.Op}}(tree.{{.Ctx}}, &{{.Target}}, &tmpDec, &{{.Right}}) + {{else -}} _, err := tree.{{.Ctx}}.{{.Op}}(&{{.Target}}, &tmpDec, &{{.Right}}) + {{end -}} if err != nil { colexecerror.ExpectedError(err) } diff --git a/pkg/sql/colexec/execgen/cmd/execgen/overloads_cmp.go b/pkg/sql/colexec/execgen/cmd/execgen/overloads_cmp.go index 3038f5c..5d32d1e 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/overloads_cmp.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/overloads_cmp.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main diff --git a/pkg/sql/colexec/execgen/cmd/execgen/overloads_gen_util.go b/pkg/sql/colexec/execgen/cmd/execgen/overloads_gen_util.go index 9ece7e9..ef08021 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/overloads_gen_util.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/overloads_gen_util.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main diff --git a/pkg/sql/colexec/execgen/cmd/execgen/overloads_hash.go b/pkg/sql/colexec/execgen/cmd/execgen/overloads_hash.go index 972239f..524c0b5 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/overloads_hash.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/overloads_hash.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main diff --git a/pkg/sql/colexec/execgen/cmd/execgen/projection_ops_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/projection_ops_gen.go index d9cbc47..7151a25 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/projection_ops_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/projection_ops_gen.go @@ -1,12 +1,7 @@ // Copyright 2018 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main diff --git a/pkg/sql/colexec/execgen/cmd/execgen/range_offset_handler_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/range_offset_handler_gen.go index e2f9808..be34ecd 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/range_offset_handler_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/range_offset_handler_gen.go @@ -1,12 +1,7 @@ // Copyright 2021 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main diff --git a/pkg/sql/colexec/execgen/cmd/execgen/rank_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/rank_gen.go index 5f59144..9a53578 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/rank_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/rank_gen.go @@ -1,12 +1,7 @@ // Copyright 2019 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main diff --git a/pkg/sql/colexec/execgen/cmd/execgen/relative_rank_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/relative_rank_gen.go index 2a67d37..de7e778 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/relative_rank_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/relative_rank_gen.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main diff --git a/pkg/sql/colexec/execgen/cmd/execgen/row_number_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/row_number_gen.go index 3cc0968..bfe52ba 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/row_number_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/row_number_gen.go @@ -1,12 +1,7 @@ // Copyright 2019 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main diff --git a/pkg/sql/colexec/execgen/cmd/execgen/rowtovec_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/rowtovec_gen.go index 2c5c393..e37f5f7 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/rowtovec_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/rowtovec_gen.go @@ -1,12 +1,7 @@ // Copyright 2018 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main diff --git a/pkg/sql/colexec/execgen/cmd/execgen/select_in_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/select_in_gen.go index 8a501c1..878e9b2 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/select_in_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/select_in_gen.go @@ -1,12 +1,7 @@ // Copyright 2019 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main @@ -25,6 +20,7 @@ func genSelectIn(inputFileContents string, wr io.Writer) error { "_CANONICAL_TYPE_FAMILY", "{{.CanonicalTypeFamilyStr}}", "_TYPE_WIDTH", typeWidthReplacement, "_GOTYPESLICE", "{{.GoTypeSliceName}}", + "_GOTYPE_UPCAST_INT", `{{if or (eq .VecMethod "Int16") (eq .VecMethod "Int32")}}int64{{else}}{{.GoType}}{{end}}`, "_GOTYPE", "{{.GoType}}", "_TYPE", "{{.VecMethod}}", "TemplateType", "{{.VecMethod}}", diff --git a/pkg/sql/colexec/execgen/cmd/execgen/selection_ops_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/selection_ops_gen.go index 912085d..88ecf38 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/selection_ops_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/selection_ops_gen.go @@ -1,12 +1,7 @@ // Copyright 2018 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main diff --git a/pkg/sql/colexec/execgen/cmd/execgen/sort_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/sort_gen.go index 4ed1532..7d8b5ff 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/sort_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/sort_gen.go @@ -1,12 +1,7 @@ // Copyright 2018 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main diff --git a/pkg/sql/colexec/execgen/cmd/execgen/sorttopk_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/sorttopk_gen.go index 5826d8b..e44955c 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/sorttopk_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/sorttopk_gen.go @@ -1,12 +1,7 @@ // Copyright 2021 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main diff --git a/pkg/sql/colexec/execgen/cmd/execgen/span_encoder_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/span_encoder_gen.go index 10704b4..50043e7 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/span_encoder_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/span_encoder_gen.go @@ -1,12 +1,7 @@ // Copyright 2021 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main diff --git a/pkg/sql/colexec/execgen/cmd/execgen/substring_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/substring_gen.go index 133a88c..a0d0f88 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/substring_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/substring_gen.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main diff --git a/pkg/sql/colexec/execgen/cmd/execgen/sum_agg_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/sum_agg_gen.go index bfac9e8..d8bcc65 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/sum_agg_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/sum_agg_gen.go @@ -1,12 +1,7 @@ // Copyright 2018 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main @@ -112,7 +107,7 @@ const sumAggTmpl = "pkg/sql/colexec/colexecagg/sum_agg_tmpl.go" func genSumAgg(inputFileContents string, wr io.Writer, isSumInt bool) error { r := strings.NewReplacer( - "_TYPE_FAMILY", "{{.TypeFamily}}", + "_CANONICAL_TYPE_FAMILY", "{{.TypeFamily}}", "_TYPE_WIDTH", typeWidthReplacement, "_SUMKIND", "{{.SumKind}}", "_RET_GOTYPESLICE", `{{.RetGoTypeSlice}}`, @@ -164,9 +159,10 @@ func genSumAgg(inputFileContents string, wr io.Writer, isSumInt bool) error { TypeFamily: familyToString(inputTypeFamily), } for _, inputTypeWidth := range supportedWidthsByCanonicalTypeFamily[inputTypeFamily] { - // Note that we don't use execinfrapb.GetAggregateInfo because we don't - // want to bring in a dependency on that package to reduce the burden - // of regenerating execgen code when the protobufs get generated. + // Note that we don't use execinfrapb.GetAggregateOutputType because + // we don't want to bring in a dependency on that package to reduce + // the burden of regenerating execgen code when the protobufs get + // generated. retTypeFamily, retTypeWidth := inputTypeFamily, inputTypeWidth if inputTypeFamily == types.IntFamily { if isSumInt { @@ -207,9 +203,11 @@ func init() { } } registerAggGenerator( - sumAggGenerator(false /* isSumInt */), "sum_agg.eg.go", - sumAggTmpl, true /* genWindowVariant */) + sumAggGenerator(false /* isSumInt */), "sum_agg.eg.go", /* filenameSuffix */ + sumAggTmpl, "sum" /* aggName */, true, /* genWindowVariant */ + ) registerAggGenerator( - sumAggGenerator(true /* isSumInt */), "sum_int_agg.eg.go", - sumAggTmpl, true /* genWindowVariant */) + sumAggGenerator(true /* isSumInt */), "sum_int_agg.eg.go", /* filenameSuffix */ + sumAggTmpl, "sumInt" /* aggName */, true, /* genWindowVariant */ + ) } diff --git a/pkg/sql/colexec/execgen/cmd/execgen/values_differ_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/values_differ_gen.go index 22ad307..e82102d 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/values_differ_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/values_differ_gen.go @@ -1,12 +1,7 @@ // Copyright 2019 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main diff --git a/pkg/sql/colexec/execgen/cmd/execgen/vec_comparators_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/vec_comparators_gen.go index 694a75e..9326947 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/vec_comparators_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/vec_comparators_gen.go @@ -1,12 +1,7 @@ // Copyright 2019 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main diff --git a/pkg/sql/colexec/execgen/cmd/execgen/vec_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/vec_gen.go index 2d7fbec..4b8eae4 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/vec_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/vec_gen.go @@ -1,12 +1,7 @@ // Copyright 2018 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main diff --git a/pkg/sql/colexec/execgen/cmd/execgen/vec_to_datum_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/vec_to_datum_gen.go index b3b0ff3..d958073 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/vec_to_datum_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/vec_to_datum_gen.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main diff --git a/pkg/sql/colexec/execgen/cmd/execgen/window_aggregator_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/window_aggregator_gen.go index 1e57247..bf9ea00 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/window_aggregator_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/window_aggregator_gen.go @@ -1,12 +1,7 @@ // Copyright 2021 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main diff --git a/pkg/sql/colexec/execgen/cmd/execgen/window_framer_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/window_framer_gen.go index b5db98b..953486a 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/window_framer_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/window_framer_gen.go @@ -1,12 +1,7 @@ // Copyright 2021 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main diff --git a/pkg/sql/colexec/execgen/cmd/execgen/window_peer_grouper_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/window_peer_grouper_gen.go index 863617f..6e0486e 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/window_peer_grouper_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/window_peer_grouper_gen.go @@ -1,12 +1,7 @@ // Copyright 2019 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package main diff --git a/pkg/sql/colexec/execgen/execgen.go b/pkg/sql/colexec/execgen/execgen.go index c744a0a..bf2739f 100644 --- a/pkg/sql/colexec/execgen/execgen.go +++ b/pkg/sql/colexec/execgen/execgen.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package execgen diff --git a/pkg/sql/colexec/execgen/inline.go b/pkg/sql/colexec/execgen/inline.go index 753d97a..c23f29b 100644 --- a/pkg/sql/colexec/execgen/inline.go +++ b/pkg/sql/colexec/execgen/inline.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package execgen diff --git a/pkg/sql/colexec/execgen/placeholders.go b/pkg/sql/colexec/execgen/placeholders.go index 57518b2..7779045 100644 --- a/pkg/sql/colexec/execgen/placeholders.go +++ b/pkg/sql/colexec/execgen/placeholders.go @@ -1,12 +1,7 @@ // Copyright 2019 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package execgen diff --git a/pkg/sql/colexec/execgen/supported_bin_cmp_ops.go b/pkg/sql/colexec/execgen/supported_bin_cmp_ops.go index 0358bd3..6276e8b 100644 --- a/pkg/sql/colexec/execgen/supported_bin_cmp_ops.go +++ b/pkg/sql/colexec/execgen/supported_bin_cmp_ops.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package execgen diff --git a/pkg/sql/colexec/execgen/template.go b/pkg/sql/colexec/execgen/template.go index 4e37be9..cba9137 100644 --- a/pkg/sql/colexec/execgen/template.go +++ b/pkg/sql/colexec/execgen/template.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package execgen diff --git a/pkg/sql/colexec/execgen/util.go b/pkg/sql/colexec/execgen/util.go index 273cef2..12406e0 100644 --- a/pkg/sql/colexec/execgen/util.go +++ b/pkg/sql/colexec/execgen/util.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package execgen diff --git a/pkg/sql/colexecerror/error.go b/pkg/sql/colexecerror/error.go index a003943..0923525 100644 --- a/pkg/sql/colexecerror/error.go +++ b/pkg/sql/colexecerror/error.go @@ -1,28 +1,43 @@ // Copyright 2019 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package colexecerror import ( - "bufio" "context" - "runtime/debug" + "runtime" "strings" "github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode" "github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror" + "github.com/cockroachdb/cockroachdb-parser/pkg/util/buildutil" "github.com/cockroachdb/errors" "github.com/gogo/protobuf/proto" ) -const panicLineSubstring = "runtime/panic.go" +const ( + panicLineSubstring = "runtime/panic.go" + runtimePanicFileSubstring = "runtime" + runtimePanicFunctionSubstring = "runtime." +) + +var testingKnobShouldCatchPanic bool + +// ProductionBehaviorForTests reinstates the release-build behavior for +// CatchVectorizedRuntimeError, which is to catch *all* panics originating from +// within the vectorized execution engine, including runtime panics that are not +// wrapped in InternalError, ExpectedError, or StorageError. (Without calling +// this, in crdb_test builds, CatchVectorizedRuntimeError will only catch panics +// that are wrapped in InternalError, ExpectedError, or StorageError.) +func ProductionBehaviorForTests() func() { + old := testingKnobShouldCatchPanic + testingKnobShouldCatchPanic = true + return func() { + testingKnobShouldCatchPanic = old + } +} // CatchVectorizedRuntimeError executes operation, catches a runtime error if // it is coming from the vectorized engine, and returns it. If an error not @@ -36,25 +51,89 @@ func CatchVectorizedRuntimeError(operation func()) (retErr error) { return } - // Find where the panic came from and only proceed if it is related to the - // vectorized engine. - stackTrace := string(debug.Stack()) - scanner := bufio.NewScanner(strings.NewReader(stackTrace)) - panicLineFound := false - for scanner.Scan() { - if strings.Contains(scanner.Text(), panicLineSubstring) { - panicLineFound = true - break + // First check for error types that should only come from the vectorized + // engine. + if err, ok := panicObj.(error); ok { + // StorageError was caused by something below SQL, and represents an error + // that we'd simply like to propagate along. + var se *StorageError + // notInternalError is an error from the vectorized engine that we'd + // simply like to propagate along. + var nie *notInternalError + // internalError is an error from the vectorized engine that might need to + // be returned to the client with a stacktrace, sentry report, and + // "internal error" designation. + var ie *internalError + passthrough := errors.As(err, &se) || errors.As(err, &nie) + if errors.As(err, &ie) { + // Unwrap so that internalError doesn't show up in sentry reports. + retErr = ie.Unwrap() + // If the internal error doesn't already have an error code, mark it as + // an assertion error so that we generate a sentry report. (We don't do + // this for StorageError, notInternalError, or context.Canceled to avoid + // creating unnecessary sentry reports.) + if !passthrough && !errors.Is(retErr, context.Canceled) { + if code := pgerror.GetPGCode(retErr); code == pgcode.Uncategorized { + retErr = errors.NewAssertionErrorWithWrappedErrf( + retErr, "unexpected error from the vectorized engine", + ) + } + } + return + } + if passthrough { + retErr = err + return } } - if !panicLineFound { - panic(errors.AssertionFailedf("panic line %q not found in the stack trace\n%s", panicLineSubstring, stackTrace)) - } - if !scanner.Scan() { - panic(errors.AssertionFailedf("unexpectedly there is no line below the panic line in the stack trace\n%s", stackTrace)) + + // For other types of errors, we need to check whence the panic originated + // to know what to do. If the panic originated in the vectorized engine, we + // can safely return it as a normal error knowing that any illegal state + // will be cleaned up when the statement finishes. If the panic originated + // lower in the stack, however, we must treat it as unrecoverable because it + // could indicate an illegal state that might persist even after this + // statement finishes. + // + // To check whence the panic originated, we find the frame just before the + // panic frame. + var panicLineFound bool + var panicEmittedFrom string + // Usually, we'll find the offending frame within 3 program counters, + // starting with the caller of this deferred function (2 above the + // runtime.Callers frame). However, we also want to catch panics + // originating in the Go runtime with the runtime frames being returned + // by CallersFrames, so we allow for 5 more program counters for that + // case (e.g. invalid interface conversions use 2 counters). + pc := make([]uintptr, 8) + n := runtime.Callers(2, pc) + if n >= 1 { + frames := runtime.CallersFrames(pc[:n]) + // A fixed number of program counters can expand to any number of frames. + for { + frame, more := frames.Next() + if strings.Contains(frame.File, panicLineSubstring) { + panicLineFound = true + } else if panicLineFound { + if strings.HasPrefix(frame.Function, runtimePanicFunctionSubstring) && + strings.Contains(frame.File, runtimePanicFileSubstring) { + // This frame is from the Go runtime, so we simply + // ignore it to get to the offending one within the + // CRDB. + continue + } + panicEmittedFrom = frame.Function + break + } + if !more { + break + } + } } - panicEmittedFrom := strings.TrimSpace(scanner.Text()) if !shouldCatchPanic(panicEmittedFrom) { + // The panic is from outside the vectorized engine (or we didn't find it + // in the stack). We treat it as unrecoverable because it could indicate + // an illegal state that might persist even after this statement finishes. panic(panicObj) } @@ -66,20 +145,11 @@ func CatchVectorizedRuntimeError(operation func()) (retErr error) { } retErr = err - if _, ok := panicObj.(*StorageError); ok { - // A StorageError was caused by something below SQL, and represents - // an error that we'd simply like to propagate along. - // Do nothing. - return - } - annotateErrorWithoutCode := true - var nie *notInternalError - if errors.Is(err, context.Canceled) || errors.As(err, &nie) { - // We don't want to annotate the context cancellation and - // notInternalError errors in case they don't have a valid PG code - // so that the sentry report is not sent (errors with failed - // assertions get sentry reports). + if errors.Is(err, context.Canceled) { + // We don't want to annotate the context cancellation errors in case they + // don't have a valid PG code so that the sentry report is not sent + // (errors with failed assertions get sentry reports). annotateErrorWithoutCode = false } if code := pgerror.GetPGCode(err); annotateErrorWithoutCode && code == pgcode.Uncategorized { @@ -106,6 +176,9 @@ const ( sqlColPackagesPrefix = "github.com/cockroachdb/cockroachdb-parser/pkg/sql/col" sqlRowPackagesPrefix = "github.com/cockroachdb/cockroachdb-parser/pkg/sql/row" sqlSemPackagesPrefix = "github.com/cockroachdb/cockroachdb-parser/pkg/sql/sem" + // When running BenchmarkCatchVectorizedRuntimeError under bazel, the + // repository prefix is missing. + testSqlColPackagesPrefix = "pkg/sql/col" ) // shouldCatchPanic checks whether the panic that was emitted from @@ -118,6 +191,14 @@ const ( // // panicEmittedFrom must be trimmed to not have any white spaces in the prefix. func shouldCatchPanic(panicEmittedFrom string) bool { + // In crdb_test builds we do not catch runtime panics even if they originate + // from within the vectorized execution engine. These panics probably + // represent bugs in vectorized execution, and we want them to fail loudly in + // tests (but not in production clusters). + if buildutil.CrdbTestBuild && !testingKnobShouldCatchPanic { + return false + } + const panicFromTheCatcherItselfPrefix = "github.com/cockroachdb/cockroachdb-parser/pkg/sql/colexecerror.CatchVectorizedRuntimeError" if strings.HasPrefix(panicEmittedFrom, panicFromTheCatcherItselfPrefix) { // This panic came from the catcher itself, so we will propagate it @@ -135,25 +216,25 @@ func shouldCatchPanic(panicEmittedFrom string) bool { strings.HasPrefix(panicEmittedFrom, execinfraPackagePrefix) || strings.HasPrefix(panicEmittedFrom, sqlColPackagesPrefix) || strings.HasPrefix(panicEmittedFrom, sqlRowPackagesPrefix) || - strings.HasPrefix(panicEmittedFrom, sqlSemPackagesPrefix) + strings.HasPrefix(panicEmittedFrom, sqlSemPackagesPrefix) || + strings.HasPrefix(panicEmittedFrom, testSqlColPackagesPrefix) } // StorageError is an error that was created by a component below the sql // stack, such as the network or storage layers. A StorageError will be bubbled // up all the way past the SQL layer unchanged. type StorageError struct { - error + cause error } -// Cause implements the Causer interface. -func (s *StorageError) Cause() error { - return s.error -} +func (s *StorageError) Error() string { return s.cause.Error() } +func (s *StorageError) Cause() error { return s.cause } +func (s *StorageError) Unwrap() error { return s.cause } // NewStorageError returns a new storage error. This can be used to propagate // an error through the exec subsystem unchanged. func NewStorageError(err error) *StorageError { - return &StorageError{error: err} + return &StorageError{cause: err} } // notInternalError is an error that occurs not because the vectorized engine @@ -183,16 +264,41 @@ func decodeNotInternalError( return newNotInternalError(cause) } +// internalError is an error that occurs because the vectorized engine is in an +// unexpected state. Usually it wraps an assertion error. +type internalError struct { + cause error +} + +func newInternalError(err error) *internalError { + return &internalError{cause: err} +} + +var ( + _ errors.Wrapper = &internalError{} +) + +func (e *internalError) Error() string { return e.cause.Error() } +func (e *internalError) Cause() error { return e.cause } +func (e *internalError) Unwrap() error { return e.Cause() } + +func decodeInternalError( + _ context.Context, cause error, _ string, _ []string, _ proto.Message, +) error { + return newInternalError(cause) +} + func init() { errors.RegisterWrapperDecoder(errors.GetTypeKey((*notInternalError)(nil)), decodeNotInternalError) + errors.RegisterWrapperDecoder(errors.GetTypeKey((*internalError)(nil)), decodeInternalError) } -// InternalError simply panics with the provided object. It will always be -// caught and returned as internal error to the client with the corresponding +// InternalError panics with the error wrapped by internalError. It will always +// be caught and returned as internal error to the client with the corresponding // stack trace. This method should be called to propagate errors that resulted // in the vectorized engine being in an *unexpected* state. func InternalError(err error) { - panic(err) + panic(newInternalError(err)) } // ExpectedError panics with the error that is wrapped by diff --git a/pkg/sql/inverted/expression.go b/pkg/sql/inverted/expression.go index 712c8bb..de562a4 100644 --- a/pkg/sql/inverted/expression.go +++ b/pkg/sql/inverted/expression.go @@ -1,21 +1,17 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package inverted import ( "bytes" "fmt" - "strconv" + "strings" "github.com/cockroachdb/cockroachdb-parser/pkg/keysbase" + "github.com/cockroachdb/cockroachdb-parser/pkg/util/encoding" "github.com/cockroachdb/cockroachdb-parser/pkg/util/treeprinter" "github.com/cockroachdb/errors" "github.com/cockroachdb/redact" @@ -107,7 +103,7 @@ func MakeSingleValSpan(val EncVal) Span { // IsSingleVal returns true iff the span is equivalent to [val, val]. func (s Span) IsSingleVal() bool { - return bytes.Equal(keysbase.PrefixEnd(s.Start), s.End) + return s.Start != nil && bytes.Equal(keysbase.PrefixEnd(s.Start), s.End) } // Equals returns true if this span has the same start and end as the given @@ -158,16 +154,20 @@ func (is Spans) Format(tp treeprinter.Node, label string, redactable bool) { } func formatSpan(span Span, redactable bool) string { - end := span.End spanEndOpenOrClosed := ')' + vals, _ := encoding.PrettyPrintValuesWithTypes(nil, span.Start) + start := strings.Join(vals, "/") + var end string if span.IsSingleVal() { - end = span.Start + end = start spanEndOpenOrClosed = ']' + } else { + vals, _ := encoding.PrettyPrintValuesWithTypes(nil, span.End) + end = strings.Join(vals, "/") } - output := fmt.Sprintf("[%s, %s%c", strconv.Quote(string(span.Start)), - strconv.Quote(string(end)), spanEndOpenOrClosed) + output := fmt.Sprintf("[%s, %s%c", start, end, spanEndOpenOrClosed) if redactable { - output = string(redact.Sprintf("%s", redact.Unsafe(output))) + output = string(redact.Sprintf("%s", encoding.Unsafe(output))) } return output } @@ -309,7 +309,7 @@ type SpanExpression struct { // produce duplicate primary keys. Otherwise, Unique is false. Unique may // be true for certain JSON or Array SpanExpressions, and it holds when // unique SpanExpressions are combined with And. It does not hold when - // these SpanExpressions are combined with Or. + // these non-empty SpanExpressions are combined with Or. // // Once a SpanExpression is built, this field is relevant if the root // SpanExpression has no children (i.e., Operator is None). In this case, @@ -685,14 +685,17 @@ func intersectSpanExpressions(left, right *SpanExpression) *SpanExpression { left.FactoredUnionSpans = subtractSpans(left.FactoredUnionSpans, expr.FactoredUnionSpans) right.FactoredUnionSpans = subtractSpans(right.FactoredUnionSpans, expr.FactoredUnionSpans) } - tryPruneChildren(expr, SetIntersection) + tryPruneChildren(expr) return expr } // Unions two SpanExpressions. func unionSpanExpressions(left, right *SpanExpression) *SpanExpression { expr := &SpanExpression{ - Tight: left.Tight && right.Tight, + Tight: left.Tight && right.Tight, + // Whenever one side is empty, we keep the Unique property from the + // other side. + Unique: (left.Unique && len(right.FactoredUnionSpans) == 0) || (right.Unique && len(left.FactoredUnionSpans) == 0), SpansToRead: unionSpans(left.SpansToRead, right.SpansToRead), FactoredUnionSpans: unionSpans(left.FactoredUnionSpans, right.FactoredUnionSpans), Operator: SetUnion, @@ -701,13 +704,13 @@ func unionSpanExpressions(left, right *SpanExpression) *SpanExpression { } left.FactoredUnionSpans = nil right.FactoredUnionSpans = nil - tryPruneChildren(expr, SetUnion) + tryPruneChildren(expr) return expr } // tryPruneChildren takes an expr with two child *SpanExpression and removes // children when safe to do so. -func tryPruneChildren(expr *SpanExpression, op SetOperator) { +func tryPruneChildren(expr *SpanExpression) { isEmptyExpr := func(e *SpanExpression) bool { return len(e.FactoredUnionSpans) == 0 && e.Left == nil && e.Right == nil } diff --git a/pkg/sql/inverted/span_expression.pb.go b/pkg/sql/inverted/span_expression.pb.go index d8a0090..e4fd4bd 100644 --- a/pkg/sql/inverted/span_expression.pb.go +++ b/pkg/sql/inverted/span_expression.pb.go @@ -426,7 +426,7 @@ func (m *SpanExpressionProto_Node) Size() (n int) { } func sovSpanExpression(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 + return int((uint32(math_bits.Len64(x|1)+6) * 37) >> 8) } func sozSpanExpression(x uint64) (n int) { return sovSpanExpression(uint64((x << 1) ^ uint64((int64(x) >> 63)))) diff --git a/pkg/sql/inverted/span_expression.proto b/pkg/sql/inverted/span_expression.proto index e36aad2..9bf5683 100644 --- a/pkg/sql/inverted/span_expression.proto +++ b/pkg/sql/inverted/span_expression.proto @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. syntax = "proto3"; package cockroach.sql.inverted; diff --git a/pkg/sql/lex/encode.go b/pkg/sql/lex/encode.go index 93117c3..2e3bba8 100644 --- a/pkg/sql/lex/encode.go +++ b/pkg/sql/lex/encode.go @@ -7,13 +7,8 @@ // // Copyright 2015 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. // This code was derived from https://github.com/youtube/vitess. @@ -29,6 +24,7 @@ import ( "github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode" "github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror" + "github.com/cockroachdb/cockroachdb-parser/pkg/util/collatedstring" "github.com/cockroachdb/errors" "golang.org/x/text/language" ) @@ -47,8 +43,12 @@ func NormalizeLocaleName(s string) string { // need to be quoted, and they are considered equivalent to dash characters by // the CLDR standard: http://cldr.unicode.org/. func EncodeLocaleName(buf *bytes.Buffer, s string) { - // If possible, try to normalize the case of the locale name. - if normalized, err := language.Parse(s); err == nil { + // If possible, try to normalize the case of the locale name (only for non-default + // locales). Default locales will always be quoted so they can be parsed correctly. + isDefaultLocale := collatedstring.IsDefaultEquivalentCollation(s) + if isDefaultLocale { + s = fmt.Sprintf("%q", s) + } else if normalized, err := language.Parse(s); err == nil { s = normalized.String() } for i, n := 0, len(s); i < n; i++ { diff --git a/pkg/sql/lex/encode.proto b/pkg/sql/lex/encode.proto index 1402097..de8532d 100644 --- a/pkg/sql/lex/encode.proto +++ b/pkg/sql/lex/encode.proto @@ -1,12 +1,7 @@ // Copyright 2022 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. syntax = "proto3"; package cockroach.sql.sessiondatapb; diff --git a/pkg/sql/lexbase/allkeywords/main.go b/pkg/sql/lexbase/allkeywords/main.go index 0f54dca..927bda8 100644 --- a/pkg/sql/lexbase/allkeywords/main.go +++ b/pkg/sql/lexbase/allkeywords/main.go @@ -1,12 +1,7 @@ // Copyright 2019 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. // all-keywords generates sql/lexbase/keywords.go from sql.y. // diff --git a/pkg/sql/lexbase/encode.go b/pkg/sql/lexbase/encode.go index 7056a8c..47b9a37 100644 --- a/pkg/sql/lexbase/encode.go +++ b/pkg/sql/lexbase/encode.go @@ -7,13 +7,8 @@ // // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. // This code was derived from https://github.com/youtube/vitess. @@ -47,9 +42,18 @@ const ( // without wrapping quotes. EncBareIdentifiers + // EncBareReservedKeywords indicates that reserved keywords will be rendered + // without wrapping quotes. + EncBareReservedKeywords + // EncFirstFreeFlagBit needs to remain unused; it is used as base // bit offset for tree.FmtFlags. EncFirstFreeFlagBit + + // EncAlwaysQuoted makes sure the string is always wrapped with quotes. + // This is used only to construct a statement against Oracle source, + // as Oracle is case insensitive if object name is not quoted. + EncAlwaysQuoted ) // EncodeRestrictedSQLIdent writes the identifier in s to buf. The @@ -57,7 +61,7 @@ const ( // contains special characters, or the identifier is a reserved SQL // keyword. func EncodeRestrictedSQLIdent(buf *bytes.Buffer, s string, flags EncodeFlags) { - if flags.HasFlags(EncBareIdentifiers) || (!isReservedKeyword(s) && IsBareIdentifier(s)) { + if !flags.HasFlags(EncAlwaysQuoted) && (flags.HasFlags(EncBareIdentifiers) || (!isReservedKeyword(s) && IsBareIdentifier(s))) { buf.WriteString(s) return } @@ -68,7 +72,7 @@ func EncodeRestrictedSQLIdent(buf *bytes.Buffer, s string, flags EncodeFlags) { // The identifier is only quoted if the flags don't tell otherwise and // the identifier contains special characters. func EncodeUnrestrictedSQLIdent(buf *bytes.Buffer, s string, flags EncodeFlags) { - if flags.HasFlags(EncBareIdentifiers) || IsBareIdentifier(s) { + if !flags.HasFlags(EncAlwaysQuoted) && (flags.HasFlags(EncBareIdentifiers) || IsBareIdentifier(s)) { buf.WriteString(s) return } @@ -108,7 +112,12 @@ func EncodeEscapedSQLIdent(buf *bytes.Buffer, s string) { buf.WriteByte('"') } -var mustQuoteMap = map[byte]bool{ +const ( + minPrintableChar = 0x20 // ' ' + maxPrintableChar = 0x7E // '~' +) + +var mustQuoteMap = [maxPrintableChar + 1]bool{ ' ': true, ',': true, '{': true, @@ -146,7 +155,7 @@ func EncodeSQLStringWithFlags(buf *bytes.Buffer, in string, flags EncodeFlags) { continue } ch := byte(r) - if r >= 0x20 && r < 0x7F { + if r >= minPrintableChar && r <= maxPrintableChar { if mustQuoteMap[ch] { // We have to quote this string - ignore bareStrings setting bareStrings = false @@ -161,6 +170,7 @@ func EncodeSQLStringWithFlags(buf *bytes.Buffer, in string, flags EncodeFlags) { escapedString = true } buf.WriteString(in[start:i]) + ln := utf8.RuneLen(r) if ln < 0 { start = i + 1 diff --git a/pkg/sql/lexbase/experimental_keywords.go b/pkg/sql/lexbase/experimental_keywords.go index 3f43f50..6c6a227 100644 --- a/pkg/sql/lexbase/experimental_keywords.go +++ b/pkg/sql/lexbase/experimental_keywords.go @@ -1,12 +1,7 @@ // Copyright 2019 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package lexbase diff --git a/pkg/sql/lexbase/keywords.go b/pkg/sql/lexbase/keywords.go index 8c93523..fd6a768 100644 --- a/pkg/sql/lexbase/keywords.go +++ b/pkg/sql/lexbase/keywords.go @@ -31,6 +31,7 @@ var KeywordsCategories = map[string]string{ "authorization": "T", "automatic": "U", "availability": "U", +"avoid_full_scan": "U", "backup": "U", "backups": "U", "backward": "U", @@ -38,6 +39,7 @@ var KeywordsCategories = map[string]string{ "before": "U", "begin": "U", "between": "C", +"bidirectional": "U", "bigint": "C", "binary": "U", "bit": "C", @@ -47,6 +49,7 @@ var KeywordsCategories = map[string]string{ "bucket_count": "U", "bundle": "U", "by": "U", +"bypassrls": "U", "cache": "U", "call": "U", "called": "U", @@ -116,9 +119,7 @@ var KeywordsCategories = map[string]string{ "databases": "U", "day": "U", "deallocate": "U", -"debug_dump_metadata_sst": "U", "debug_ids": "U", -"debug_pause_on": "U", "dec": "C", "decimal": "C", "declare": "U", @@ -134,13 +135,16 @@ var KeywordsCategories = map[string]string{ "destination": "U", "detached": "U", "details": "U", +"disable": "U", "discard": "U", "distinct": "R", "do": "R", "domain": "U", "double": "U", "drop": "U", +"each": "U", "else": "R", +"enable": "U", "encoding": "U", "encrypted": "U", "encryption_info_dir": "U", @@ -180,6 +184,7 @@ var KeywordsCategories = map[string]string{ "for": "R", "force": "U", "force_index": "U", +"force_inverted_index": "U", "force_not_null": "U", "force_null": "U", "force_quote": "U", @@ -225,6 +230,7 @@ var KeywordsCategories = map[string]string{ "ignore_foreign_keys": "U", "ilike": "T", "immediate": "U", +"immediately": "U", "immutable": "U", "import": "U", "in": "R", @@ -248,6 +254,7 @@ var KeywordsCategories = map[string]string{ "input": "U", "insensitive": "U", "insert": "U", +"instead": "U", "int": "C", "integer": "C", "intersect": "R", @@ -295,6 +302,8 @@ var KeywordsCategories = map[string]string{ "localtime": "R", "localtimestamp": "R", "locked": "U", +"logical": "U", +"logically": "U", "login": "U", "lookup": "U", "low": "U", @@ -305,6 +314,7 @@ var KeywordsCategories = map[string]string{ "method": "U", "minute": "U", "minvalue": "U", +"mode": "U", "modifyclustersetting": "U", "modifysqlclustersetting": "U", "month": "U", @@ -325,16 +335,19 @@ var KeywordsCategories = map[string]string{ "nan": "U", "natural": "T", "never": "U", +"new": "U", "new_db_name": "U", "new_kms": "U", "next": "U", "no": "U", +"nobypassrls": "U", "nocancelquery": "U", "nocontrolchangefeed": "U", "nocontroljob": "U", "nocreatedb": "U", "nocreatelogin": "U", "nocreaterole": "U", +"node": "U", "nologin": "U", "nomodifyclustersetting": "U", "none": "T", @@ -361,6 +374,7 @@ var KeywordsCategories = map[string]string{ "off": "U", "offset": "R", "oids": "U", +"old": "U", "old_kms": "U", "on": "R", "only": "R", @@ -387,6 +401,8 @@ var KeywordsCategories = map[string]string{ "password": "U", "pause": "U", "paused": "U", +"per": "U", +"permissive": "U", "physical": "U", "placement": "U", "placing": "R", @@ -396,6 +412,8 @@ var KeywordsCategories = map[string]string{ "pointm": "U", "pointz": "U", "pointzm": "U", +"policies": "U", +"policy": "U", "polygon": "C", "polygonm": "U", "polygonz": "U", @@ -404,6 +422,7 @@ var KeywordsCategories = map[string]string{ "preceding": "U", "precision": "C", "prepare": "U", +"prepared": "U", "preserve": "U", "primary": "R", "prior": "U", @@ -427,6 +446,7 @@ var KeywordsCategories = map[string]string{ "redact": "U", "ref": "U", "references": "R", +"referencing": "U", "refresh": "U", "region": "U", "regional": "U", @@ -439,12 +459,14 @@ var KeywordsCategories = map[string]string{ "rename": "U", "repeatable": "U", "replace": "U", +"replicated": "U", "replication": "U", "reset": "U", "restart": "U", "restore": "U", "restrict": "U", "restricted": "U", +"restrictive": "U", "resume": "U", "retention": "U", "retry": "U", @@ -507,12 +529,14 @@ var KeywordsCategories = map[string]string{ "smallint": "C", "snapshot": "U", "some": "R", +"source": "U", "split": "U", "sql": "U", "sqllogin": "U", "stable": "U", "start": "U", "state": "U", +"statement": "U", "statements": "U", "statistics": "U", "status": "U", @@ -523,9 +547,11 @@ var KeywordsCategories = map[string]string{ "store": "U", "stored": "U", "storing": "U", +"straight": "U", "stream": "U", "strict": "U", "string": "C", +"subject": "U", "subscription": "U", "substring": "C", "super": "U", @@ -563,6 +589,7 @@ var KeywordsCategories = map[string]string{ "transform": "U", "treat": "C", "trigger": "U", +"triggers": "U", "trim": "C", "true": "R", "truncate": "U", @@ -571,6 +598,7 @@ var KeywordsCategories = map[string]string{ "types": "U", "unbounded": "U", "uncommitted": "U", +"unidirectional": "U", "union": "R", "unique": "R", "unknown": "U", @@ -593,8 +621,10 @@ var KeywordsCategories = map[string]string{ "values": "C", "varbit": "C", "varchar": "C", +"variables": "U", "variadic": "R", "varying": "U", +"vector": "C", "verify_backup_table_data": "U", "view": "U", "viewactivity": "U", @@ -652,6 +682,7 @@ var KeywordNames = []string{ "authorization", "automatic", "availability", +"avoid_full_scan", "backup", "backups", "backward", @@ -659,6 +690,7 @@ var KeywordNames = []string{ "before", "begin", "between", +"bidirectional", "bigint", "binary", "bit", @@ -668,6 +700,7 @@ var KeywordNames = []string{ "bucket_count", "bundle", "by", +"bypassrls", "cache", "call", "called", @@ -737,9 +770,7 @@ var KeywordNames = []string{ "databases", "day", "deallocate", -"debug_dump_metadata_sst", "debug_ids", -"debug_pause_on", "dec", "decimal", "declare", @@ -755,13 +786,16 @@ var KeywordNames = []string{ "destination", "detached", "details", +"disable", "discard", "distinct", "do", "domain", "double", "drop", +"each", "else", +"enable", "encoding", "encrypted", "encryption_info_dir", @@ -801,6 +835,7 @@ var KeywordNames = []string{ "for", "force", "force_index", +"force_inverted_index", "force_not_null", "force_null", "force_quote", @@ -846,6 +881,7 @@ var KeywordNames = []string{ "ignore_foreign_keys", "ilike", "immediate", +"immediately", "immutable", "import", "in", @@ -869,6 +905,7 @@ var KeywordNames = []string{ "input", "insensitive", "insert", +"instead", "int", "integer", "intersect", @@ -916,6 +953,8 @@ var KeywordNames = []string{ "localtime", "localtimestamp", "locked", +"logical", +"logically", "login", "lookup", "low", @@ -926,6 +965,7 @@ var KeywordNames = []string{ "method", "minute", "minvalue", +"mode", "modifyclustersetting", "modifysqlclustersetting", "month", @@ -946,16 +986,19 @@ var KeywordNames = []string{ "nan", "natural", "never", +"new", "new_db_name", "new_kms", "next", "no", +"nobypassrls", "nocancelquery", "nocontrolchangefeed", "nocontroljob", "nocreatedb", "nocreatelogin", "nocreaterole", +"node", "nologin", "nomodifyclustersetting", "none", @@ -982,6 +1025,7 @@ var KeywordNames = []string{ "off", "offset", "oids", +"old", "old_kms", "on", "only", @@ -1008,6 +1052,8 @@ var KeywordNames = []string{ "password", "pause", "paused", +"per", +"permissive", "physical", "placement", "placing", @@ -1017,6 +1063,8 @@ var KeywordNames = []string{ "pointm", "pointz", "pointzm", +"policies", +"policy", "polygon", "polygonm", "polygonz", @@ -1025,6 +1073,7 @@ var KeywordNames = []string{ "preceding", "precision", "prepare", +"prepared", "preserve", "primary", "prior", @@ -1048,6 +1097,7 @@ var KeywordNames = []string{ "redact", "ref", "references", +"referencing", "refresh", "region", "regional", @@ -1060,12 +1110,14 @@ var KeywordNames = []string{ "rename", "repeatable", "replace", +"replicated", "replication", "reset", "restart", "restore", "restrict", "restricted", +"restrictive", "resume", "retention", "retry", @@ -1128,12 +1180,14 @@ var KeywordNames = []string{ "smallint", "snapshot", "some", +"source", "split", "sql", "sqllogin", "stable", "start", "state", +"statement", "statements", "statistics", "status", @@ -1144,9 +1198,11 @@ var KeywordNames = []string{ "store", "stored", "storing", +"straight", "stream", "strict", "string", +"subject", "subscription", "substring", "super", @@ -1184,6 +1240,7 @@ var KeywordNames = []string{ "transform", "treat", "trigger", +"triggers", "trim", "true", "truncate", @@ -1192,6 +1249,7 @@ var KeywordNames = []string{ "types", "unbounded", "uncommitted", +"unidirectional", "union", "unique", "unknown", @@ -1214,8 +1272,10 @@ var KeywordNames = []string{ "values", "varbit", "varchar", +"variables", "variadic", "varying", +"vector", "verify_backup_table_data", "view", "viewactivity", @@ -1278,6 +1338,7 @@ func GetKeywordID(k string) int32 { case "authorization": return AUTHORIZATION case "automatic": return AUTOMATIC case "availability": return AVAILABILITY + case "avoid_full_scan": return AVOID_FULL_SCAN case "backup": return BACKUP case "backups": return BACKUPS case "backward": return BACKWARD @@ -1285,6 +1346,7 @@ func GetKeywordID(k string) int32 { case "before": return BEFORE case "begin": return BEGIN case "between": return BETWEEN + case "bidirectional": return BIDIRECTIONAL case "bigint": return BIGINT case "binary": return BINARY case "bit": return BIT @@ -1294,6 +1356,7 @@ func GetKeywordID(k string) int32 { case "bucket_count": return BUCKET_COUNT case "bundle": return BUNDLE case "by": return BY + case "bypassrls": return BYPASSRLS case "cache": return CACHE case "call": return CALL case "called": return CALLED @@ -1363,9 +1426,7 @@ func GetKeywordID(k string) int32 { case "databases": return DATABASES case "day": return DAY case "deallocate": return DEALLOCATE - case "debug_dump_metadata_sst": return DEBUG_DUMP_METADATA_SST case "debug_ids": return DEBUG_IDS - case "debug_pause_on": return DEBUG_PAUSE_ON case "dec": return DEC case "decimal": return DECIMAL case "declare": return DECLARE @@ -1381,13 +1442,16 @@ func GetKeywordID(k string) int32 { case "destination": return DESTINATION case "detached": return DETACHED case "details": return DETAILS + case "disable": return DISABLE case "discard": return DISCARD case "distinct": return DISTINCT case "do": return DO case "domain": return DOMAIN case "double": return DOUBLE case "drop": return DROP + case "each": return EACH case "else": return ELSE + case "enable": return ENABLE case "encoding": return ENCODING case "encrypted": return ENCRYPTED case "encryption_info_dir": return ENCRYPTION_INFO_DIR @@ -1427,6 +1491,7 @@ func GetKeywordID(k string) int32 { case "for": return FOR case "force": return FORCE case "force_index": return FORCE_INDEX + case "force_inverted_index": return FORCE_INVERTED_INDEX case "force_not_null": return FORCE_NOT_NULL case "force_null": return FORCE_NULL case "force_quote": return FORCE_QUOTE @@ -1472,6 +1537,7 @@ func GetKeywordID(k string) int32 { case "ignore_foreign_keys": return IGNORE_FOREIGN_KEYS case "ilike": return ILIKE case "immediate": return IMMEDIATE + case "immediately": return IMMEDIATELY case "immutable": return IMMUTABLE case "import": return IMPORT case "in": return IN @@ -1495,6 +1561,7 @@ func GetKeywordID(k string) int32 { case "input": return INPUT case "insensitive": return INSENSITIVE case "insert": return INSERT + case "instead": return INSTEAD case "int": return INT case "integer": return INTEGER case "intersect": return INTERSECT @@ -1542,6 +1609,8 @@ func GetKeywordID(k string) int32 { case "localtime": return LOCALTIME case "localtimestamp": return LOCALTIMESTAMP case "locked": return LOCKED + case "logical": return LOGICAL + case "logically": return LOGICALLY case "login": return LOGIN case "lookup": return LOOKUP case "low": return LOW @@ -1552,6 +1621,7 @@ func GetKeywordID(k string) int32 { case "method": return METHOD case "minute": return MINUTE case "minvalue": return MINVALUE + case "mode": return MODE case "modifyclustersetting": return MODIFYCLUSTERSETTING case "modifysqlclustersetting": return MODIFYSQLCLUSTERSETTING case "month": return MONTH @@ -1572,16 +1642,19 @@ func GetKeywordID(k string) int32 { case "nan": return NAN case "natural": return NATURAL case "never": return NEVER + case "new": return NEW case "new_db_name": return NEW_DB_NAME case "new_kms": return NEW_KMS case "next": return NEXT case "no": return NO + case "nobypassrls": return NOBYPASSRLS case "nocancelquery": return NOCANCELQUERY case "nocontrolchangefeed": return NOCONTROLCHANGEFEED case "nocontroljob": return NOCONTROLJOB case "nocreatedb": return NOCREATEDB case "nocreatelogin": return NOCREATELOGIN case "nocreaterole": return NOCREATEROLE + case "node": return NODE case "nologin": return NOLOGIN case "nomodifyclustersetting": return NOMODIFYCLUSTERSETTING case "none": return NONE @@ -1608,6 +1681,7 @@ func GetKeywordID(k string) int32 { case "off": return OFF case "offset": return OFFSET case "oids": return OIDS + case "old": return OLD case "old_kms": return OLD_KMS case "on": return ON case "only": return ONLY @@ -1634,6 +1708,8 @@ func GetKeywordID(k string) int32 { case "password": return PASSWORD case "pause": return PAUSE case "paused": return PAUSED + case "per": return PER + case "permissive": return PERMISSIVE case "physical": return PHYSICAL case "placement": return PLACEMENT case "placing": return PLACING @@ -1643,6 +1719,8 @@ func GetKeywordID(k string) int32 { case "pointm": return POINTM case "pointz": return POINTZ case "pointzm": return POINTZM + case "policies": return POLICIES + case "policy": return POLICY case "polygon": return POLYGON case "polygonm": return POLYGONM case "polygonz": return POLYGONZ @@ -1651,6 +1729,7 @@ func GetKeywordID(k string) int32 { case "preceding": return PRECEDING case "precision": return PRECISION case "prepare": return PREPARE + case "prepared": return PREPARED case "preserve": return PRESERVE case "primary": return PRIMARY case "prior": return PRIOR @@ -1674,6 +1753,7 @@ func GetKeywordID(k string) int32 { case "redact": return REDACT case "ref": return REF case "references": return REFERENCES + case "referencing": return REFERENCING case "refresh": return REFRESH case "region": return REGION case "regional": return REGIONAL @@ -1686,12 +1766,14 @@ func GetKeywordID(k string) int32 { case "rename": return RENAME case "repeatable": return REPEATABLE case "replace": return REPLACE + case "replicated": return REPLICATED case "replication": return REPLICATION case "reset": return RESET case "restart": return RESTART case "restore": return RESTORE case "restrict": return RESTRICT case "restricted": return RESTRICTED + case "restrictive": return RESTRICTIVE case "resume": return RESUME case "retention": return RETENTION case "retry": return RETRY @@ -1754,12 +1836,14 @@ func GetKeywordID(k string) int32 { case "smallint": return SMALLINT case "snapshot": return SNAPSHOT case "some": return SOME + case "source": return SOURCE case "split": return SPLIT case "sql": return SQL case "sqllogin": return SQLLOGIN case "stable": return STABLE case "start": return START case "state": return STATE + case "statement": return STATEMENT case "statements": return STATEMENTS case "statistics": return STATISTICS case "status": return STATUS @@ -1770,9 +1854,11 @@ func GetKeywordID(k string) int32 { case "store": return STORE case "stored": return STORED case "storing": return STORING + case "straight": return STRAIGHT case "stream": return STREAM case "strict": return STRICT case "string": return STRING + case "subject": return SUBJECT case "subscription": return SUBSCRIPTION case "substring": return SUBSTRING case "super": return SUPER @@ -1810,6 +1896,7 @@ func GetKeywordID(k string) int32 { case "transform": return TRANSFORM case "treat": return TREAT case "trigger": return TRIGGER + case "triggers": return TRIGGERS case "trim": return TRIM case "true": return TRUE case "truncate": return TRUNCATE @@ -1818,6 +1905,7 @@ func GetKeywordID(k string) int32 { case "types": return TYPES case "unbounded": return UNBOUNDED case "uncommitted": return UNCOMMITTED + case "unidirectional": return UNIDIRECTIONAL case "union": return UNION case "unique": return UNIQUE case "unknown": return UNKNOWN @@ -1840,8 +1928,10 @@ func GetKeywordID(k string) int32 { case "values": return VALUES case "varbit": return VARBIT case "varchar": return VARCHAR + case "variables": return VARIABLES case "variadic": return VARIADIC case "varying": return VARYING + case "vector": return VECTOR case "verify_backup_table_data": return VERIFY_BACKUP_TABLE_DATA case "view": return VIEW case "viewactivity": return VIEWACTIVITY diff --git a/pkg/sql/lexbase/normalize.go b/pkg/sql/lexbase/normalize.go index 197b2bc..de59ff2 100644 --- a/pkg/sql/lexbase/normalize.go +++ b/pkg/sql/lexbase/normalize.go @@ -1,12 +1,7 @@ // Copyright 2017 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package lexbase diff --git a/pkg/sql/lexbase/predicates.go b/pkg/sql/lexbase/predicates.go index f166b28..5cbd442 100644 --- a/pkg/sql/lexbase/predicates.go +++ b/pkg/sql/lexbase/predicates.go @@ -1,12 +1,7 @@ // Copyright 2017 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. package lexbase diff --git a/pkg/sql/lexbase/reserved_keywords.go b/pkg/sql/lexbase/reserved_keywords.go index 6779ff7..eb4fb70 100644 --- a/pkg/sql/lexbase/reserved_keywords.go +++ b/pkg/sql/lexbase/reserved_keywords.go @@ -155,6 +155,7 @@ var reservedKeywords = map[string]struct{}{ "varbit": {}, "varchar": {}, "variadic": {}, +"vector": {}, "virtual": {}, "when": {}, "where": {}, diff --git a/pkg/sql/lexbase/sql-gen.sh b/pkg/sql/lexbase/sql-gen.sh index b242ab6..d753916 100755 --- a/pkg/sql/lexbase/sql-gen.sh +++ b/pkg/sql/lexbase/sql-gen.sh @@ -1,8 +1,14 @@ #!/usr/bin/env bash -# This is used through bazel when generating sql.go and plpgsql.go. -# Look at BUILD.bazel in pkg/sql/parser or pkg/plpgsql/parser for -# usage. +# Copyright 2022 The Cockroach Authors. +# +# Use of this software is governed by the CockroachDB Software License +# included in the /LICENSE file. + + +# This is used through bazel when generating sql.go, plpgsql.go, and jsonpath.go. +# Look at BUILD.bazel in pkg/sql/parser, pkg/sql/plpgsql/parser, or +# pkg/util/jsonpath/parser for usage. set -euo pipefail @@ -17,7 +23,7 @@ GENYACC=$LANG-gen.y awk '{print $0")>_\\1 /* <\\2> */_"}' > types_regex.tmp sed -E -f types_regex.tmp < $1 | \ - if [ $LANG != plpgsql ] && [ $LANG != pgrepl ]; then \ + if [ $LANG != plpgsql ] && [ $LANG != pgrepl ] && [ $LANG != jsonpath ]; then \ awk -f $3 | \ sed -Ee 's,//.*$$,,g;s,/[*]([^*]|[*][^/])*[*]/, ,g;s/ +$$//g' > $GENYACC else diff --git a/pkg/sql/lexbase/tokens.go b/pkg/sql/lexbase/tokens.go index 872c988..6c01167 100644 --- a/pkg/sql/lexbase/tokens.go +++ b/pkg/sql/lexbase/tokens.go @@ -50,643 +50,676 @@ const ATTRIBUTE = 57389 const AUTHORIZATION = 57390 const AUTOMATIC = 57391 const AVAILABILITY = 57392 -const BACKUP = 57393 -const BACKUPS = 57394 -const BACKWARD = 57395 -const BATCH = 57396 -const BEFORE = 57397 -const BEGIN = 57398 -const BETWEEN = 57399 -const BIGINT = 57400 -const BIGSERIAL = 57401 -const BINARY = 57402 -const BIT = 57403 -const BUCKET_COUNT = 57404 -const BOOLEAN = 57405 -const BOTH = 57406 -const BOX2D = 57407 -const BUNDLE = 57408 -const BY = 57409 -const CACHE = 57410 -const CALL = 57411 -const CALLED = 57412 -const CANCEL = 57413 -const CANCELQUERY = 57414 -const CAPABILITIES = 57415 -const CAPABILITY = 57416 -const CASCADE = 57417 -const CASE = 57418 -const CAST = 57419 -const CBRT = 57420 -const CHANGEFEED = 57421 -const CHAR = 57422 -const CHARACTER = 57423 -const CHARACTERISTICS = 57424 -const CHECK = 57425 -const CHECK_FILES = 57426 -const CLOSE = 57427 -const CLUSTER = 57428 -const CLUSTERS = 57429 -const COALESCE = 57430 -const COLLATE = 57431 -const COLLATION = 57432 -const COLUMN = 57433 -const COLUMNS = 57434 -const COMMENT = 57435 -const COMMENTS = 57436 -const COMMIT = 57437 -const COMMITTED = 57438 -const COMPACT = 57439 -const COMPLETE = 57440 -const COMPLETIONS = 57441 -const CONCAT = 57442 -const CONCURRENTLY = 57443 -const CONFIGURATION = 57444 -const CONFIGURATIONS = 57445 -const CONFIGURE = 57446 -const CONFLICT = 57447 -const CONNECTION = 57448 -const CONNECTIONS = 57449 -const CONSTRAINT = 57450 -const CONSTRAINTS = 57451 -const CONTAINS = 57452 -const CONTROLCHANGEFEED = 57453 -const CONTROLJOB = 57454 -const CONVERSION = 57455 -const CONVERT = 57456 -const COPY = 57457 -const COST = 57458 -const COVERING = 57459 -const CREATE = 57460 -const CREATEDB = 57461 -const CREATELOGIN = 57462 -const CREATEROLE = 57463 -const CROSS = 57464 -const CSV = 57465 -const CUBE = 57466 -const CURRENT = 57467 -const CURRENT_CATALOG = 57468 -const CURRENT_DATE = 57469 -const CURRENT_SCHEMA = 57470 -const CURRENT_ROLE = 57471 -const CURRENT_TIME = 57472 -const CURRENT_TIMESTAMP = 57473 -const CURRENT_USER = 57474 -const CURSOR = 57475 -const CYCLE = 57476 -const DATA = 57477 -const DATABASE = 57478 -const DATABASES = 57479 -const DATE = 57480 -const DAY = 57481 -const DEBUG_IDS = 57482 -const DEBUG_PAUSE_ON = 57483 -const DEC = 57484 -const DEBUG_DUMP_METADATA_SST = 57485 -const DECIMAL = 57486 -const DEFAULT = 57487 -const DEFAULTS = 57488 -const DEFINER = 57489 -const DEALLOCATE = 57490 -const DECLARE = 57491 -const DEFERRABLE = 57492 -const DEFERRED = 57493 -const DELETE = 57494 -const DELIMITER = 57495 -const DEPENDS = 57496 -const DESC = 57497 -const DESTINATION = 57498 -const DETACHED = 57499 -const DETAILS = 57500 -const DISCARD = 57501 -const DISTINCT = 57502 -const DO = 57503 -const DOMAIN = 57504 -const DOUBLE = 57505 -const DROP = 57506 -const ELSE = 57507 -const ENCODING = 57508 -const ENCRYPTED = 57509 -const ENCRYPTION_INFO_DIR = 57510 -const ENCRYPTION_PASSPHRASE = 57511 -const END = 57512 -const ENUM = 57513 -const ENUMS = 57514 -const ESCAPE = 57515 -const EXCEPT = 57516 -const EXCLUDE = 57517 -const EXCLUDING = 57518 -const EXISTS = 57519 -const EXECUTE = 57520 -const EXECUTION = 57521 -const EXPERIMENTAL = 57522 -const EXPERIMENTAL_FINGERPRINTS = 57523 -const EXPERIMENTAL_REPLICA = 57524 -const EXPERIMENTAL_AUDIT = 57525 -const EXPERIMENTAL_RELOCATE = 57526 -const EXPIRATION = 57527 -const EXPLAIN = 57528 -const EXPORT = 57529 -const EXTENSION = 57530 -const EXTERNAL = 57531 -const EXTRACT = 57532 -const EXTRACT_DURATION = 57533 -const EXTREMES = 57534 -const FAILURE = 57535 -const FALSE = 57536 -const FAMILY = 57537 -const FETCH = 57538 -const FETCHVAL = 57539 -const FETCHTEXT = 57540 -const FETCHVAL_PATH = 57541 -const FETCHTEXT_PATH = 57542 -const FILES = 57543 -const FILTER = 57544 -const FIRST = 57545 -const FLOAT = 57546 -const FLOAT4 = 57547 -const FLOAT8 = 57548 -const FLOORDIV = 57549 -const FOLLOWING = 57550 -const FOR = 57551 -const FORCE = 57552 -const FORCE_INDEX = 57553 -const FORCE_NOT_NULL = 57554 -const FORCE_NULL = 57555 -const FORCE_QUOTE = 57556 -const FORCE_ZIGZAG = 57557 -const FOREIGN = 57558 -const FORMAT = 57559 -const FORWARD = 57560 -const FREEZE = 57561 -const FROM = 57562 -const FULL = 57563 -const FUNCTION = 57564 -const FUNCTIONS = 57565 -const GENERATED = 57566 -const GEOGRAPHY = 57567 -const GEOMETRY = 57568 -const GEOMETRYM = 57569 -const GEOMETRYZ = 57570 -const GEOMETRYZM = 57571 -const GEOMETRYCOLLECTION = 57572 -const GEOMETRYCOLLECTIONM = 57573 -const GEOMETRYCOLLECTIONZ = 57574 -const GEOMETRYCOLLECTIONZM = 57575 -const GLOBAL = 57576 -const GOAL = 57577 -const GRANT = 57578 -const GRANTEE = 57579 -const GRANTS = 57580 -const GREATEST = 57581 -const GROUP = 57582 -const GROUPING = 57583 -const GROUPS = 57584 -const HAVING = 57585 -const HASH = 57586 -const HEADER = 57587 -const HIGH = 57588 -const HISTOGRAM = 57589 -const HOLD = 57590 -const HOUR = 57591 -const IDENTITY = 57592 -const IF = 57593 -const IFERROR = 57594 -const IFNULL = 57595 -const IGNORE_FOREIGN_KEYS = 57596 -const ILIKE = 57597 -const IMMEDIATE = 57598 -const IMMUTABLE = 57599 -const IMPORT = 57600 -const IN = 57601 -const INCLUDE = 57602 -const INCLUDING = 57603 -const INCLUDE_ALL_SECONDARY_TENANTS = 57604 -const INCLUDE_ALL_VIRTUAL_CLUSTERS = 57605 -const INCREMENT = 57606 -const INCREMENTAL = 57607 -const INCREMENTAL_LOCATION = 57608 -const INET = 57609 -const INET_CONTAINED_BY_OR_EQUALS = 57610 -const INET_CONTAINS_OR_EQUALS = 57611 -const INDEX = 57612 -const INDEXES = 57613 -const INHERITS = 57614 -const INJECT = 57615 -const INITIALLY = 57616 -const INDEX_BEFORE_PAREN = 57617 -const INDEX_BEFORE_NAME_THEN_PAREN = 57618 -const INDEX_AFTER_ORDER_BY_BEFORE_AT = 57619 -const INNER = 57620 -const INOUT = 57621 -const INPUT = 57622 -const INSENSITIVE = 57623 -const INSERT = 57624 -const INT = 57625 -const INTEGER = 57626 -const INTERSECT = 57627 -const INTERVAL = 57628 -const INTO = 57629 -const INTO_DB = 57630 -const INVERTED = 57631 -const INVOKER = 57632 -const IS = 57633 -const ISERROR = 57634 -const ISNULL = 57635 -const ISOLATION = 57636 -const JOB = 57637 -const JOBS = 57638 -const JOIN = 57639 -const JSON = 57640 -const JSONB = 57641 -const JSON_SOME_EXISTS = 57642 -const JSON_ALL_EXISTS = 57643 -const KEY = 57644 -const KEYS = 57645 -const KMS = 57646 -const KV = 57647 -const LABEL = 57648 -const LANGUAGE = 57649 -const LAST = 57650 -const LATERAL = 57651 -const LATEST = 57652 -const LC_CTYPE = 57653 -const LC_COLLATE = 57654 -const LEADING = 57655 -const LEASE = 57656 -const LEAST = 57657 -const LEAKPROOF = 57658 -const LEFT = 57659 -const LESS = 57660 -const LEVEL = 57661 -const LIKE = 57662 -const LIMIT = 57663 -const LINESTRING = 57664 -const LINESTRINGM = 57665 -const LINESTRINGZ = 57666 -const LINESTRINGZM = 57667 -const LIST = 57668 -const LOCAL = 57669 -const LOCALITY = 57670 -const LOCALTIME = 57671 -const LOCALTIMESTAMP = 57672 -const LOCKED = 57673 -const LOGIN = 57674 -const LOOKUP = 57675 -const LOW = 57676 -const LSHIFT = 57677 -const MATCH = 57678 -const MATERIALIZED = 57679 -const MERGE = 57680 -const MINVALUE = 57681 -const MAXVALUE = 57682 -const METHOD = 57683 -const MINUTE = 57684 -const MODIFYCLUSTERSETTING = 57685 -const MODIFYSQLCLUSTERSETTING = 57686 -const MONTH = 57687 -const MOVE = 57688 -const MULTILINESTRING = 57689 -const MULTILINESTRINGM = 57690 -const MULTILINESTRINGZ = 57691 -const MULTILINESTRINGZM = 57692 -const MULTIPOINT = 57693 -const MULTIPOINTM = 57694 -const MULTIPOINTZ = 57695 -const MULTIPOINTZM = 57696 -const MULTIPOLYGON = 57697 -const MULTIPOLYGONM = 57698 -const MULTIPOLYGONZ = 57699 -const MULTIPOLYGONZM = 57700 -const NAN = 57701 -const NAME = 57702 -const NAMES = 57703 -const NATURAL = 57704 -const NEVER = 57705 -const NEW_DB_NAME = 57706 -const NEW_KMS = 57707 -const NEXT = 57708 -const NO = 57709 -const NOCANCELQUERY = 57710 -const NOCONTROLCHANGEFEED = 57711 -const NOCONTROLJOB = 57712 -const NOCREATEDB = 57713 -const NOCREATELOGIN = 57714 -const NOCREATEROLE = 57715 -const NOLOGIN = 57716 -const NOMODIFYCLUSTERSETTING = 57717 -const NOREPLICATION = 57718 -const NOSQLLOGIN = 57719 -const NO_INDEX_JOIN = 57720 -const NO_ZIGZAG_JOIN = 57721 -const NO_FULL_SCAN = 57722 -const NONE = 57723 -const NONVOTERS = 57724 -const NORMAL = 57725 -const NOT = 57726 -const NOTHING = 57727 -const NOTHING_AFTER_RETURNING = 57728 -const NOTNULL = 57729 -const NOVIEWACTIVITY = 57730 -const NOVIEWACTIVITYREDACTED = 57731 -const NOVIEWCLUSTERSETTING = 57732 -const NOWAIT = 57733 -const NULL = 57734 -const NULLIF = 57735 -const NULLS = 57736 -const NUMERIC = 57737 -const OF = 57738 -const OFF = 57739 -const OFFSET = 57740 -const OID = 57741 -const OIDS = 57742 -const OIDVECTOR = 57743 -const OLD_KMS = 57744 -const ON = 57745 -const ONLY = 57746 -const OPT = 57747 -const OPTION = 57748 -const OPTIONS = 57749 -const OR = 57750 -const ORDER = 57751 -const ORDINALITY = 57752 -const OTHERS = 57753 -const OUT = 57754 -const OUTER = 57755 -const OVER = 57756 -const OVERLAPS = 57757 -const OVERLAY = 57758 -const OWNED = 57759 -const OWNER = 57760 -const OPERATOR = 57761 -const PARALLEL = 57762 -const PARENT = 57763 -const PARTIAL = 57764 -const PARTITION = 57765 -const PARTITIONS = 57766 -const PASSWORD = 57767 -const PAUSE = 57768 -const PAUSED = 57769 -const PHYSICAL = 57770 -const PLACEMENT = 57771 -const PLACING = 57772 -const PLAN = 57773 -const PLANS = 57774 -const POINT = 57775 -const POINTM = 57776 -const POINTZ = 57777 -const POINTZM = 57778 -const POLYGON = 57779 -const POLYGONM = 57780 -const POLYGONZ = 57781 -const POLYGONZM = 57782 -const POSITION = 57783 -const PRECEDING = 57784 -const PRECISION = 57785 -const PREPARE = 57786 -const PRESERVE = 57787 -const PRIMARY = 57788 -const PRIOR = 57789 -const PRIORITY = 57790 -const PRIVILEGES = 57791 -const PROCEDURAL = 57792 -const PROCEDURE = 57793 -const PROCEDURES = 57794 -const PUBLIC = 57795 -const PUBLICATION = 57796 -const QUERIES = 57797 -const QUERY = 57798 -const QUOTE = 57799 -const RANGE = 57800 -const RANGES = 57801 -const READ = 57802 -const REAL = 57803 -const REASON = 57804 -const REASSIGN = 57805 -const RECURSIVE = 57806 -const RECURRING = 57807 -const REDACT = 57808 -const REF = 57809 -const REFERENCES = 57810 -const REFRESH = 57811 -const REGCLASS = 57812 -const REGION = 57813 -const REGIONAL = 57814 -const REGIONS = 57815 -const REGNAMESPACE = 57816 -const REGPROC = 57817 -const REGPROCEDURE = 57818 -const REGROLE = 57819 -const REGTYPE = 57820 -const REINDEX = 57821 -const RELATIVE = 57822 -const RELOCATE = 57823 -const REMOVE_PATH = 57824 -const REMOVE_REGIONS = 57825 -const RENAME = 57826 -const REPEATABLE = 57827 -const REPLACE = 57828 -const REPLICATION = 57829 -const RELEASE = 57830 -const RESET = 57831 -const RESTART = 57832 -const RESTORE = 57833 -const RESTRICT = 57834 -const RESTRICTED = 57835 -const RESUME = 57836 -const RETENTION = 57837 -const RETURNING = 57838 -const RETURN = 57839 -const RETURNS = 57840 -const RETRY = 57841 -const REVISION_HISTORY = 57842 -const REVOKE = 57843 -const RIGHT = 57844 -const ROLE = 57845 -const ROLES = 57846 -const ROLLBACK = 57847 -const ROLLUP = 57848 -const ROUTINES = 57849 -const ROW = 57850 -const ROWS = 57851 -const RSHIFT = 57852 -const RULE = 57853 -const RUNNING = 57854 -const SAVEPOINT = 57855 -const SCANS = 57856 -const SCATTER = 57857 -const SCHEDULE = 57858 -const SCHEDULES = 57859 -const SCROLL = 57860 -const SCHEMA = 57861 -const SCHEMA_ONLY = 57862 -const SCHEMAS = 57863 -const SCRUB = 57864 -const SEARCH = 57865 -const SECOND = 57866 -const SECONDARY = 57867 -const SECURITY = 57868 -const SELECT = 57869 -const SEQUENCE = 57870 -const SEQUENCES = 57871 -const SERIALIZABLE = 57872 -const SERVER = 57873 -const SERVICE = 57874 -const SESSION = 57875 -const SESSIONS = 57876 -const SESSION_USER = 57877 -const SET = 57878 -const SETOF = 57879 -const SETS = 57880 -const SETTING = 57881 -const SETTINGS = 57882 -const SHARE = 57883 -const SHARED = 57884 -const SHOW = 57885 -const SIMILAR = 57886 -const SIMPLE = 57887 -const SIZE = 57888 -const SKIP = 57889 -const SKIP_LOCALITIES_CHECK = 57890 -const SKIP_MISSING_FOREIGN_KEYS = 57891 -const SKIP_MISSING_SEQUENCES = 57892 -const SKIP_MISSING_SEQUENCE_OWNERS = 57893 -const SKIP_MISSING_VIEWS = 57894 -const SKIP_MISSING_UDFS = 57895 -const SMALLINT = 57896 -const SMALLSERIAL = 57897 -const SNAPSHOT = 57898 -const SOME = 57899 -const SPLIT = 57900 -const SQL = 57901 -const SQLLOGIN = 57902 -const STABLE = 57903 -const START = 57904 -const STATE = 57905 -const STATISTICS = 57906 -const STATUS = 57907 -const STDIN = 57908 -const STDOUT = 57909 -const STOP = 57910 -const STREAM = 57911 -const STRICT = 57912 -const STRING = 57913 -const STORAGE = 57914 -const STORE = 57915 -const STORED = 57916 -const STORING = 57917 -const SUBSTRING = 57918 -const SUPER = 57919 -const SUPPORT = 57920 -const SURVIVE = 57921 -const SURVIVAL = 57922 -const SYMMETRIC = 57923 -const SYNTAX = 57924 -const SYSTEM = 57925 -const SQRT = 57926 -const SUBSCRIPTION = 57927 -const STATEMENTS = 57928 -const TABLE = 57929 -const TABLES = 57930 -const TABLESPACE = 57931 -const TEMP = 57932 -const TEMPLATE = 57933 -const TEMPORARY = 57934 -const TENANT = 57935 -const TENANT_NAME = 57936 -const TENANTS = 57937 -const TESTING_RELOCATE = 57938 -const TEXT = 57939 -const THEN = 57940 -const TIES = 57941 -const TIME = 57942 -const TIMETZ = 57943 -const TIMESTAMP = 57944 -const TIMESTAMPTZ = 57945 -const TO = 57946 -const THROTTLING = 57947 -const TRAILING = 57948 -const TRACE = 57949 -const TRANSACTION = 57950 -const TRANSACTIONS = 57951 -const TRANSFER = 57952 -const TRANSFORM = 57953 -const TREAT = 57954 -const TRIGGER = 57955 -const TRIM = 57956 -const TRUE = 57957 -const TRUNCATE = 57958 -const TRUSTED = 57959 -const TYPE = 57960 -const TYPES = 57961 -const TRACING = 57962 -const UNBOUNDED = 57963 -const UNCOMMITTED = 57964 -const UNION = 57965 -const UNIQUE = 57966 -const UNKNOWN = 57967 -const UNLISTEN = 57968 -const UNLOGGED = 57969 -const UNSAFE_RESTORE_INCOMPATIBLE_VERSION = 57970 -const UNSPLIT = 57971 -const UPDATE = 57972 -const UPDATES_CLUSTER_MONITORING_METRICS = 57973 -const UPSERT = 57974 -const UNSET = 57975 -const UNTIL = 57976 -const USE = 57977 -const USER = 57978 -const USERS = 57979 -const USING = 57980 -const UUID = 57981 -const VALID = 57982 -const VALIDATE = 57983 -const VALUE = 57984 -const VALUES = 57985 -const VARBIT = 57986 -const VARCHAR = 57987 -const VARIADIC = 57988 -const VERIFY_BACKUP_TABLE_DATA = 57989 -const VIEW = 57990 -const VARYING = 57991 -const VIEWACTIVITY = 57992 -const VIEWACTIVITYREDACTED = 57993 -const VIEWDEBUG = 57994 -const VIEWCLUSTERMETADATA = 57995 -const VIEWCLUSTERSETTING = 57996 -const VIRTUAL = 57997 -const VISIBLE = 57998 -const INVISIBLE = 57999 -const VISIBILITY = 58000 -const VOLATILE = 58001 -const VOTERS = 58002 -const VIRTUAL_CLUSTER_NAME = 58003 -const VIRTUAL_CLUSTER = 58004 -const WHEN = 58005 -const WHERE = 58006 -const WINDOW = 58007 -const WITH = 58008 -const WITHIN = 58009 -const WITHOUT = 58010 -const WORK = 58011 -const WRITE = 58012 -const YEAR = 58013 -const ZONE = 58014 -const NOT_LA = 58015 -const NULLS_LA = 58016 -const WITH_LA = 58017 -const AS_LA = 58018 -const GENERATED_ALWAYS = 58019 -const GENERATED_BY_DEFAULT = 58020 -const RESET_ALL = 58021 -const ROLE_ALL = 58022 -const USER_ALL = 58023 -const ON_LA = 58024 -const TENANT_ALL = 58025 -const CLUSTER_ALL = 58026 -const SET_TRACING = 58027 -const CONTAINED_BY = 58028 -const POSTFIXOP = 58029 -const INTERVAL_SIMPLE = 58030 -const UMINUS = 58031 -const HELPTOKEN = 58032 +const AVOID_FULL_SCAN = 57393 +const BACKUP = 57394 +const BACKUPS = 57395 +const BACKWARD = 57396 +const BATCH = 57397 +const BEFORE = 57398 +const BEGIN = 57399 +const BETWEEN = 57400 +const BIDIRECTIONAL = 57401 +const BIGINT = 57402 +const BIGSERIAL = 57403 +const BINARY = 57404 +const BIT = 57405 +const BUCKET_COUNT = 57406 +const BOOLEAN = 57407 +const BOTH = 57408 +const BOX2D = 57409 +const BUNDLE = 57410 +const BY = 57411 +const BYPASSRLS = 57412 +const CACHE = 57413 +const CALL = 57414 +const CALLED = 57415 +const CANCEL = 57416 +const CANCELQUERY = 57417 +const CAPABILITIES = 57418 +const CAPABILITY = 57419 +const CASCADE = 57420 +const CASE = 57421 +const CAST = 57422 +const CBRT = 57423 +const CHANGEFEED = 57424 +const CHAR = 57425 +const CHARACTER = 57426 +const CHARACTERISTICS = 57427 +const CHECK = 57428 +const CHECK_FILES = 57429 +const CLOSE = 57430 +const CLUSTER = 57431 +const CLUSTERS = 57432 +const COALESCE = 57433 +const COLLATE = 57434 +const COLLATION = 57435 +const COLUMN = 57436 +const COLUMNS = 57437 +const COMMENT = 57438 +const COMMENTS = 57439 +const COMMIT = 57440 +const COMMITTED = 57441 +const COMPACT = 57442 +const COMPLETE = 57443 +const COMPLETIONS = 57444 +const CONCAT = 57445 +const CONCURRENTLY = 57446 +const CONFIGURATION = 57447 +const CONFIGURATIONS = 57448 +const CONFIGURE = 57449 +const CONFLICT = 57450 +const CONNECTION = 57451 +const CONNECTIONS = 57452 +const CONSTRAINT = 57453 +const CONSTRAINTS = 57454 +const CONTAINS = 57455 +const CONTROLCHANGEFEED = 57456 +const CONTROLJOB = 57457 +const CONVERSION = 57458 +const CONVERT = 57459 +const COPY = 57460 +const COS_DISTANCE = 57461 +const COST = 57462 +const COVERING = 57463 +const CREATE = 57464 +const CREATEDB = 57465 +const CREATELOGIN = 57466 +const CREATEROLE = 57467 +const CROSS = 57468 +const CSV = 57469 +const CUBE = 57470 +const CURRENT = 57471 +const CURRENT_CATALOG = 57472 +const CURRENT_DATE = 57473 +const CURRENT_SCHEMA = 57474 +const CURRENT_ROLE = 57475 +const CURRENT_TIME = 57476 +const CURRENT_TIMESTAMP = 57477 +const CURRENT_USER = 57478 +const CURSOR = 57479 +const CYCLE = 57480 +const DATA = 57481 +const DATABASE = 57482 +const DATABASES = 57483 +const DATE = 57484 +const DAY = 57485 +const DEBUG_IDS = 57486 +const DEC = 57487 +const DECIMAL = 57488 +const DEFAULT = 57489 +const DEFAULTS = 57490 +const DEFINER = 57491 +const DEALLOCATE = 57492 +const DECLARE = 57493 +const DEFERRABLE = 57494 +const DEFERRED = 57495 +const DELETE = 57496 +const DELIMITER = 57497 +const DEPENDS = 57498 +const DESC = 57499 +const DESTINATION = 57500 +const DETACHED = 57501 +const DETAILS = 57502 +const DISABLE = 57503 +const DISCARD = 57504 +const DISTANCE = 57505 +const DISTINCT = 57506 +const DO = 57507 +const DOMAIN = 57508 +const DOUBLE = 57509 +const DROP = 57510 +const EACH = 57511 +const ELSE = 57512 +const ENABLE = 57513 +const ENCODING = 57514 +const ENCRYPTED = 57515 +const ENCRYPTION_INFO_DIR = 57516 +const ENCRYPTION_PASSPHRASE = 57517 +const END = 57518 +const ENUM = 57519 +const ENUMS = 57520 +const ESCAPE = 57521 +const EXCEPT = 57522 +const EXCLUDE = 57523 +const EXCLUDING = 57524 +const EXISTS = 57525 +const EXECUTE = 57526 +const EXECUTION = 57527 +const EXPERIMENTAL = 57528 +const EXPERIMENTAL_FINGERPRINTS = 57529 +const EXPERIMENTAL_REPLICA = 57530 +const EXPERIMENTAL_AUDIT = 57531 +const EXPERIMENTAL_RELOCATE = 57532 +const EXPIRATION = 57533 +const EXPLAIN = 57534 +const EXPORT = 57535 +const EXTENSION = 57536 +const EXTERNAL = 57537 +const EXTRACT = 57538 +const EXTRACT_DURATION = 57539 +const EXTREMES = 57540 +const FAILURE = 57541 +const FALSE = 57542 +const FAMILY = 57543 +const FETCH = 57544 +const FETCHVAL = 57545 +const FETCHTEXT = 57546 +const FETCHVAL_PATH = 57547 +const FETCHTEXT_PATH = 57548 +const FILES = 57549 +const FILTER = 57550 +const FIRST = 57551 +const FLOAT = 57552 +const FLOAT4 = 57553 +const FLOAT8 = 57554 +const FLOORDIV = 57555 +const FOLLOWING = 57556 +const FOR = 57557 +const FORCE = 57558 +const FORCE_INDEX = 57559 +const FORCE_INVERTED_INDEX = 57560 +const FORCE_NOT_NULL = 57561 +const FORCE_NULL = 57562 +const FORCE_QUOTE = 57563 +const FORCE_ZIGZAG = 57564 +const FOREIGN = 57565 +const FORMAT = 57566 +const FORWARD = 57567 +const FREEZE = 57568 +const FROM = 57569 +const FULL = 57570 +const FUNCTION = 57571 +const FUNCTIONS = 57572 +const GENERATED = 57573 +const GEOGRAPHY = 57574 +const GEOMETRY = 57575 +const GEOMETRYM = 57576 +const GEOMETRYZ = 57577 +const GEOMETRYZM = 57578 +const GEOMETRYCOLLECTION = 57579 +const GEOMETRYCOLLECTIONM = 57580 +const GEOMETRYCOLLECTIONZ = 57581 +const GEOMETRYCOLLECTIONZM = 57582 +const GLOBAL = 57583 +const GOAL = 57584 +const GRANT = 57585 +const GRANTEE = 57586 +const GRANTS = 57587 +const GREATEST = 57588 +const GROUP = 57589 +const GROUPING = 57590 +const GROUPS = 57591 +const HAVING = 57592 +const HASH = 57593 +const HEADER = 57594 +const HIGH = 57595 +const HISTOGRAM = 57596 +const HOLD = 57597 +const HOUR = 57598 +const IDENTITY = 57599 +const IF = 57600 +const IFERROR = 57601 +const IFNULL = 57602 +const IGNORE_FOREIGN_KEYS = 57603 +const ILIKE = 57604 +const IMMEDIATE = 57605 +const IMMEDIATELY = 57606 +const IMMUTABLE = 57607 +const IMPORT = 57608 +const IN = 57609 +const INCLUDE = 57610 +const INCLUDING = 57611 +const INCLUDE_ALL_SECONDARY_TENANTS = 57612 +const INCLUDE_ALL_VIRTUAL_CLUSTERS = 57613 +const INCREMENT = 57614 +const INCREMENTAL = 57615 +const INCREMENTAL_LOCATION = 57616 +const INET = 57617 +const INET_CONTAINED_BY_OR_EQUALS = 57618 +const INET_CONTAINS_OR_EQUALS = 57619 +const INDEX = 57620 +const INDEXES = 57621 +const INHERITS = 57622 +const INJECT = 57623 +const INITIALLY = 57624 +const INDEX_BEFORE_PAREN = 57625 +const INDEX_BEFORE_NAME_THEN_PAREN = 57626 +const INDEX_AFTER_ORDER_BY_BEFORE_AT = 57627 +const INNER = 57628 +const INOUT = 57629 +const INPUT = 57630 +const INSENSITIVE = 57631 +const INSERT = 57632 +const INSTEAD = 57633 +const INT = 57634 +const INTEGER = 57635 +const INTERSECT = 57636 +const INTERVAL = 57637 +const INTO = 57638 +const INTO_DB = 57639 +const INVERTED = 57640 +const INVOKER = 57641 +const IS = 57642 +const ISERROR = 57643 +const ISNULL = 57644 +const ISOLATION = 57645 +const JOB = 57646 +const JOBS = 57647 +const JOIN = 57648 +const JSON = 57649 +const JSONB = 57650 +const JSON_SOME_EXISTS = 57651 +const JSON_ALL_EXISTS = 57652 +const KEY = 57653 +const KEYS = 57654 +const KMS = 57655 +const KV = 57656 +const LABEL = 57657 +const LANGUAGE = 57658 +const LAST = 57659 +const LATERAL = 57660 +const LATEST = 57661 +const LC_CTYPE = 57662 +const LC_COLLATE = 57663 +const LEADING = 57664 +const LEASE = 57665 +const LEAST = 57666 +const LEAKPROOF = 57667 +const LEFT = 57668 +const LESS = 57669 +const LEVEL = 57670 +const LIKE = 57671 +const LIMIT = 57672 +const LINESTRING = 57673 +const LINESTRINGM = 57674 +const LINESTRINGZ = 57675 +const LINESTRINGZM = 57676 +const LIST = 57677 +const LOCAL = 57678 +const LOCALITY = 57679 +const LOCALTIME = 57680 +const LOCALTIMESTAMP = 57681 +const LOCKED = 57682 +const LOGICAL = 57683 +const LOGICALLY = 57684 +const LOGIN = 57685 +const LOOKUP = 57686 +const LOW = 57687 +const LSHIFT = 57688 +const MATCH = 57689 +const MATERIALIZED = 57690 +const MERGE = 57691 +const MINVALUE = 57692 +const MAXVALUE = 57693 +const METHOD = 57694 +const MINUTE = 57695 +const MODIFYCLUSTERSETTING = 57696 +const MODIFYSQLCLUSTERSETTING = 57697 +const MODE = 57698 +const MONTH = 57699 +const MOVE = 57700 +const MULTILINESTRING = 57701 +const MULTILINESTRINGM = 57702 +const MULTILINESTRINGZ = 57703 +const MULTILINESTRINGZM = 57704 +const MULTIPOINT = 57705 +const MULTIPOINTM = 57706 +const MULTIPOINTZ = 57707 +const MULTIPOINTZM = 57708 +const MULTIPOLYGON = 57709 +const MULTIPOLYGONM = 57710 +const MULTIPOLYGONZ = 57711 +const MULTIPOLYGONZM = 57712 +const NAN = 57713 +const NAME = 57714 +const NAMES = 57715 +const NATURAL = 57716 +const NEG_INNER_PRODUCT = 57717 +const NEVER = 57718 +const NEW = 57719 +const NEW_DB_NAME = 57720 +const NEW_KMS = 57721 +const NEXT = 57722 +const NO = 57723 +const NOBYPASSRLS = 57724 +const NOCANCELQUERY = 57725 +const NOCONTROLCHANGEFEED = 57726 +const NOCONTROLJOB = 57727 +const NOCREATEDB = 57728 +const NOCREATELOGIN = 57729 +const NOCREATEROLE = 57730 +const NODE = 57731 +const NOLOGIN = 57732 +const NOMODIFYCLUSTERSETTING = 57733 +const NOREPLICATION = 57734 +const NOSQLLOGIN = 57735 +const NO_INDEX_JOIN = 57736 +const NO_ZIGZAG_JOIN = 57737 +const NO_FULL_SCAN = 57738 +const NONE = 57739 +const NONVOTERS = 57740 +const NORMAL = 57741 +const NOT = 57742 +const NOTHING = 57743 +const NOTHING_AFTER_RETURNING = 57744 +const NOTNULL = 57745 +const NOVIEWACTIVITY = 57746 +const NOVIEWACTIVITYREDACTED = 57747 +const NOVIEWCLUSTERSETTING = 57748 +const NOWAIT = 57749 +const NULL = 57750 +const NULLIF = 57751 +const NULLS = 57752 +const NUMERIC = 57753 +const OF = 57754 +const OFF = 57755 +const OFFSET = 57756 +const OID = 57757 +const OIDS = 57758 +const OIDVECTOR = 57759 +const OLD = 57760 +const OLD_KMS = 57761 +const ON = 57762 +const ONLY = 57763 +const OPT = 57764 +const OPTION = 57765 +const OPTIONS = 57766 +const OR = 57767 +const ORDER = 57768 +const ORDINALITY = 57769 +const OTHERS = 57770 +const OUT = 57771 +const OUTER = 57772 +const OVER = 57773 +const OVERLAPS = 57774 +const OVERLAY = 57775 +const OWNED = 57776 +const OWNER = 57777 +const OPERATOR = 57778 +const PARALLEL = 57779 +const PARENT = 57780 +const PARTIAL = 57781 +const PARTITION = 57782 +const PARTITIONS = 57783 +const PASSWORD = 57784 +const PAUSE = 57785 +const PAUSED = 57786 +const PER = 57787 +const PERMISSIVE = 57788 +const PHYSICAL = 57789 +const PLACEMENT = 57790 +const PLACING = 57791 +const PLAN = 57792 +const PLANS = 57793 +const POINT = 57794 +const POINTM = 57795 +const POINTZ = 57796 +const POINTZM = 57797 +const POLICIES = 57798 +const POLICY = 57799 +const POLYGON = 57800 +const POLYGONM = 57801 +const POLYGONZ = 57802 +const POLYGONZM = 57803 +const POSITION = 57804 +const PRECEDING = 57805 +const PRECISION = 57806 +const PREPARE = 57807 +const PREPARED = 57808 +const PRESERVE = 57809 +const PRIMARY = 57810 +const PRIOR = 57811 +const PRIORITY = 57812 +const PRIVILEGES = 57813 +const PROCEDURAL = 57814 +const PROCEDURE = 57815 +const PROCEDURES = 57816 +const PUBLIC = 57817 +const PUBLICATION = 57818 +const QUERIES = 57819 +const QUERY = 57820 +const QUOTE = 57821 +const RANGE = 57822 +const RANGES = 57823 +const READ = 57824 +const REAL = 57825 +const REASON = 57826 +const REASSIGN = 57827 +const RECURSIVE = 57828 +const RECURRING = 57829 +const REDACT = 57830 +const REF = 57831 +const REFERENCES = 57832 +const REFERENCING = 57833 +const REFRESH = 57834 +const REGCLASS = 57835 +const REGION = 57836 +const REGIONAL = 57837 +const REGIONS = 57838 +const REGNAMESPACE = 57839 +const REGPROC = 57840 +const REGPROCEDURE = 57841 +const REGROLE = 57842 +const REGTYPE = 57843 +const REINDEX = 57844 +const RELATIVE = 57845 +const RELOCATE = 57846 +const REMOVE_PATH = 57847 +const REMOVE_REGIONS = 57848 +const RENAME = 57849 +const REPEATABLE = 57850 +const REPLACE = 57851 +const REPLICATED = 57852 +const REPLICATION = 57853 +const RELEASE = 57854 +const RESET = 57855 +const RESTART = 57856 +const RESTORE = 57857 +const RESTRICT = 57858 +const RESTRICTED = 57859 +const RESTRICTIVE = 57860 +const RESUME = 57861 +const RETENTION = 57862 +const RETURNING = 57863 +const RETURN = 57864 +const RETURNS = 57865 +const RETRY = 57866 +const REVISION_HISTORY = 57867 +const REVOKE = 57868 +const RIGHT = 57869 +const ROLE = 57870 +const ROLES = 57871 +const ROLLBACK = 57872 +const ROLLUP = 57873 +const ROUTINES = 57874 +const ROW = 57875 +const ROWS = 57876 +const RSHIFT = 57877 +const RULE = 57878 +const RUNNING = 57879 +const SAVEPOINT = 57880 +const SCANS = 57881 +const SCATTER = 57882 +const SCHEDULE = 57883 +const SCHEDULES = 57884 +const SCROLL = 57885 +const SCHEMA = 57886 +const SCHEMA_ONLY = 57887 +const SCHEMAS = 57888 +const SCRUB = 57889 +const SEARCH = 57890 +const SECOND = 57891 +const SECONDARY = 57892 +const SECURITY = 57893 +const SELECT = 57894 +const SEQUENCE = 57895 +const SEQUENCES = 57896 +const SERIALIZABLE = 57897 +const SERVER = 57898 +const SERVICE = 57899 +const SESSION = 57900 +const SESSIONS = 57901 +const SESSION_USER = 57902 +const SET = 57903 +const SETOF = 57904 +const SETS = 57905 +const SETTING = 57906 +const SETTINGS = 57907 +const SHARE = 57908 +const SHARED = 57909 +const SHOW = 57910 +const SIMILAR = 57911 +const SIMPLE = 57912 +const SIZE = 57913 +const SKIP = 57914 +const SKIP_LOCALITIES_CHECK = 57915 +const SKIP_MISSING_FOREIGN_KEYS = 57916 +const SKIP_MISSING_SEQUENCES = 57917 +const SKIP_MISSING_SEQUENCE_OWNERS = 57918 +const SKIP_MISSING_VIEWS = 57919 +const SKIP_MISSING_UDFS = 57920 +const SMALLINT = 57921 +const SMALLSERIAL = 57922 +const SNAPSHOT = 57923 +const SOME = 57924 +const SOURCE = 57925 +const SPLIT = 57926 +const SQL = 57927 +const SQLLOGIN = 57928 +const STABLE = 57929 +const START = 57930 +const STATE = 57931 +const STATEMENT = 57932 +const STATISTICS = 57933 +const STATUS = 57934 +const STDIN = 57935 +const STDOUT = 57936 +const STOP = 57937 +const STRAIGHT = 57938 +const STREAM = 57939 +const STRICT = 57940 +const STRING = 57941 +const STORAGE = 57942 +const STORE = 57943 +const STORED = 57944 +const STORING = 57945 +const SUBJECT = 57946 +const SUBSTRING = 57947 +const SUPER = 57948 +const SUPPORT = 57949 +const SURVIVE = 57950 +const SURVIVAL = 57951 +const SYMMETRIC = 57952 +const SYNTAX = 57953 +const SYSTEM = 57954 +const SQRT = 57955 +const SUBSCRIPTION = 57956 +const STATEMENTS = 57957 +const TABLE = 57958 +const TABLES = 57959 +const TABLESPACE = 57960 +const TEMP = 57961 +const TEMPLATE = 57962 +const TEMPORARY = 57963 +const TENANT = 57964 +const TENANT_NAME = 57965 +const TENANTS = 57966 +const TESTING_RELOCATE = 57967 +const TEXT = 57968 +const THEN = 57969 +const TIES = 57970 +const TIME = 57971 +const TIMETZ = 57972 +const TIMESTAMP = 57973 +const TIMESTAMPTZ = 57974 +const TO = 57975 +const THROTTLING = 57976 +const TRAILING = 57977 +const TRACE = 57978 +const TRANSACTION = 57979 +const TRANSACTIONS = 57980 +const TRANSFER = 57981 +const TRANSFORM = 57982 +const TREAT = 57983 +const TRIGGER = 57984 +const TRIGGERS = 57985 +const TRIM = 57986 +const TRUE = 57987 +const TRUNCATE = 57988 +const TRUSTED = 57989 +const TYPE = 57990 +const TYPES = 57991 +const TRACING = 57992 +const UNBOUNDED = 57993 +const UNCOMMITTED = 57994 +const UNIDIRECTIONAL = 57995 +const UNION = 57996 +const UNIQUE = 57997 +const UNKNOWN = 57998 +const UNLISTEN = 57999 +const UNLOGGED = 58000 +const UNSAFE_RESTORE_INCOMPATIBLE_VERSION = 58001 +const UNSPLIT = 58002 +const UPDATE = 58003 +const UPDATES_CLUSTER_MONITORING_METRICS = 58004 +const UPSERT = 58005 +const UNSET = 58006 +const UNTIL = 58007 +const USE = 58008 +const USER = 58009 +const USERS = 58010 +const USING = 58011 +const UUID = 58012 +const VALID = 58013 +const VALIDATE = 58014 +const VALUE = 58015 +const VALUES = 58016 +const VARBIT = 58017 +const VARCHAR = 58018 +const VARIADIC = 58019 +const VECTOR = 58020 +const VERIFY_BACKUP_TABLE_DATA = 58021 +const VIEW = 58022 +const VARIABLES = 58023 +const VARYING = 58024 +const VIEWACTIVITY = 58025 +const VIEWACTIVITYREDACTED = 58026 +const VIEWDEBUG = 58027 +const VIEWCLUSTERMETADATA = 58028 +const VIEWCLUSTERSETTING = 58029 +const VIRTUAL = 58030 +const VISIBLE = 58031 +const INVISIBLE = 58032 +const VISIBILITY = 58033 +const VOLATILE = 58034 +const VOTERS = 58035 +const VIRTUAL_CLUSTER_NAME = 58036 +const VIRTUAL_CLUSTER = 58037 +const WHEN = 58038 +const WHERE = 58039 +const WINDOW = 58040 +const WITH = 58041 +const WITHIN = 58042 +const WITHOUT = 58043 +const WORK = 58044 +const WRITE = 58045 +const YEAR = 58046 +const ZONE = 58047 +const NOT_LA = 58048 +const NULLS_LA = 58049 +const WITH_LA = 58050 +const AS_LA = 58051 +const GENERATED_ALWAYS = 58052 +const GENERATED_BY_DEFAULT = 58053 +const RESET_ALL = 58054 +const ROLE_ALL = 58055 +const USER_ALL = 58056 +const ON_LA = 58057 +const TENANT_ALL = 58058 +const CLUSTER_ALL = 58059 +const SET_TRACING = 58060 +const CONTAINED_BY = 58061 +const POSTFIXOP = 58062 +const INTERVAL_SIMPLE = 58063 +const UMINUS = 58064 +const HELPTOKEN = 58065 diff --git a/pkg/sql/oidext/oidext.go b/pkg/sql/oidext/oidext.go index ac7da45..b629a94 100644 --- a/pkg/sql/oidext/oidext.go +++ b/pkg/sql/oidext/oidext.go @@ -1,12 +1,7 @@ // Copyright 2020 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. // Package oidext contains oids that are not in `github.com/lib/pq/oid` // as they are not shipped by default with postgres. @@ -34,6 +29,15 @@ const ( T__geography = oid.Oid(90003) T_box2d = oid.Oid(90004) T__box2d = oid.Oid(90005) + T_pgvector = oid.Oid(90006) + T__pgvector = oid.Oid(90007) +) + +// OIDs in this block are not extensions of postgres, but are not supported in +// github.com/lib/pq/oid. See postgres/src/include/catalog/pg_type.dat for oids. +const ( + T_jsonpath = oid.Oid(4072) + T__jsonpath = oid.Oid(4073) ) // ExtensionTypeName returns a mapping from extension oids @@ -45,6 +49,10 @@ var ExtensionTypeName = map[oid.Oid]string{ T__geography: "_GEOGRAPHY", T_box2d: "BOX2D", T__box2d: "_BOX2D", + T_pgvector: "VECTOR", + T__pgvector: "_VECTOR", + T_jsonpath: "JSONPATH", + T__jsonpath: "_JSONPATH", } // TypeName checks the name for a given type by first looking up oid.TypeName diff --git a/pkg/sql/parser/help.go b/pkg/sql/parser/help.go index 8a0cf32..d6b1b33 100644 --- a/pkg/sql/parser/help.go +++ b/pkg/sql/parser/help.go @@ -1,12 +1,7 @@ // Copyright 2017 The Cockroach Authors. // -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. +// Use of this software is governed by the CockroachDB Software License +// included in the /LICENSE file. // Package parser contains exposes a SQL parser for cockroach. package parser diff --git a/pkg/sql/parser/help_gen_test.sh b/pkg/sql/parser/help_gen_test.sh index 702efbc..2a58fac 100755 --- a/pkg/sql/parser/help_gen_test.sh +++ b/pkg/sql/parser/help_gen_test.sh @@ -1,5 +1,11 @@ #!/usr/bin/env bash +# Copyright 2017 The Cockroach Authors. +# +# Use of this software is governed by the CockroachDB Software License +# included in the /LICENSE file. + + # Trigger this script by running `make generate PKG=./pkg/sql/parser` from the # repository root to ensure your PATH includes vendored binaries. diff --git a/pkg/sql/parser/help_messages.go b/pkg/sql/parser/help_messages.go index 43366f7..d0d1436 100644 --- a/pkg/sql/parser/help_messages.go +++ b/pkg/sql/parser/help_messages.go @@ -4,20 +4,20 @@ package parser var helpMessages = map[string]HelpMessageBody{ - //line sql.y: 1817 + //line sql.y: 1925 `ALTER`: { - //line sql.y: 1818 + //line sql.y: 1926 Category: hGroup, - //line sql.y: 1819 + //line sql.y: 1927 Text: `ALTER TABLE, ALTER INDEX, ALTER VIEW, ALTER SEQUENCE, ALTER DATABASE, ALTER USER, ALTER ROLE, ALTER DEFAULT PRIVILEGES `, }, - //line sql.y: 1844 + //line sql.y: 1954 `ALTER TABLE`: { ShortDescription: `change the definition of a table`, - //line sql.y: 1845 + //line sql.y: 1955 Category: hDDL, - //line sql.y: 1846 + //line sql.y: 1956 Text: ` ALTER TABLE [IF EXISTS] [, ...] @@ -30,6 +30,10 @@ Commands: ALTER TABLE ... ALTER [COLUMN] {SET ON UPDATE | DROP ON UPDATE} ALTER TABLE ... ALTER [COLUMN] DROP NOT NULL ALTER TABLE ... ALTER [COLUMN] DROP STORED + ALTER TABLE ... ALTER [COLUMN] ADD GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( opt_sequence_option_list ) ] + ALTER TABLE ... ALTER [COLUMN] SET GENERATED { ALWAYS | BY DEFAULT } + ALTER TABLE ... ALTER [COLUMN] + ALTER TABLE ... ALTER [COLUMN] DROP IDENTITY [ IF EXISTS ] ALTER TABLE ... ALTER [COLUMN] [SET DATA] TYPE [COLLATE ] ALTER TABLE ... ALTER PRIMARY KEY USING COLUMNS ( ) ALTER TABLE ... RENAME TO @@ -48,6 +52,7 @@ Commands: ALTER TABLE ... CONFIGURE ZONE ALTER TABLE ... SET SCHEMA ALTER TABLE ... SET LOCALITY [REGIONAL BY [TABLE IN | ROW] | GLOBAL] + ALTER TABLE ... {ENABLE | DISABLE | FORCE | NO FORCE} ROW LEVEL SECURITY Column qualifiers: [CONSTRAINT ] {NULL | NOT NULL | UNIQUE | PRIMARY KEY | CHECK () | DEFAULT } @@ -62,16 +67,16 @@ Zone configurations: { TO | = } `, - //line sql.y: 1889 + //line sql.y: 2004 SeeAlso: `WEBDOCS/alter-table.html `, }, - //line sql.y: 1905 + //line sql.y: 2020 `ALTER PARTITION`: { ShortDescription: `apply zone configurations to a partition`, - //line sql.y: 1906 + //line sql.y: 2021 Category: hDDL, - //line sql.y: 1907 + //line sql.y: 2022 Text: ` ALTER PARTITION @@ -92,30 +97,30 @@ Zone configurations: { TO | = } `, - //line sql.y: 1926 - SeeAlso: `WEBDOCS/configure-zone.html + //line sql.y: 2041 + SeeAlso: `WEBDOCS/alter-partition.html `, }, - //line sql.y: 1931 + //line sql.y: 2046 `ALTER VIEW`: { ShortDescription: `change the definition of a view`, - //line sql.y: 1932 + //line sql.y: 2047 Category: hDDL, - //line sql.y: 1933 + //line sql.y: 2048 Text: ` ALTER [MATERIALIZED] VIEW [IF EXISTS] RENAME TO ALTER [MATERIALIZED] VIEW [IF EXISTS] SET SCHEMA `, - //line sql.y: 1936 + //line sql.y: 2051 SeeAlso: `WEBDOCS/alter-view.html `, }, - //line sql.y: 1945 + //line sql.y: 2060 `ALTER SEQUENCE`: { ShortDescription: `change the definition of a sequence`, - //line sql.y: 1946 + //line sql.y: 2061 Category: hDDL, - //line sql.y: 1947 + //line sql.y: 2062 Text: ` ALTER SEQUENCE [IF EXISTS] [AS ] @@ -129,12 +134,12 @@ ALTER SEQUENCE [IF EXISTS] RENAME TO ALTER SEQUENCE [IF EXISTS] SET SCHEMA `, }, - //line sql.y: 1976 + //line sql.y: 2091 `ALTER DATABASE`: { ShortDescription: `change the definition of a database`, - //line sql.y: 1977 + //line sql.y: 2092 Category: hDDL, - //line sql.y: 1978 + //line sql.y: 2093 Text: ` ALTER DATABASE RENAME TO ALTER DATABASE CONFIGURE ZONE @@ -149,16 +154,16 @@ ALTER DATABASE SET var { TO | = } { value | DEFAULT } ALTER DATABASE RESET { var | ALL } ALTER DATABASE ALTER LOCALITY { GLOBAL | REGIONAL [IN ] } CONFIGURE ZONE `, - //line sql.y: 1991 + //line sql.y: 2106 SeeAlso: `WEBDOCS/alter-database.html `, }, - //line sql.y: 2010 + //line sql.y: 2125 `ALTER FUNCTION`: { ShortDescription: `change the definition of a function`, - //line sql.y: 2011 + //line sql.y: 2126 Category: hDDL, - //line sql.y: 2012 + //line sql.y: 2127 Text: ` ALTER FUNCTION name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] action [ ... ] [ RESTRICT ] @@ -174,17 +179,18 @@ where action is one of: CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT IMMUTABLE | STABLE | VOLATILE [ NOT ] LEAKPROOF + [ EXTERNAL ] SECURITY { INVOKER | DEFINER } `, - //line sql.y: 2027 + //line sql.y: 2143 SeeAlso: `WEBDOCS/alter-function.html `, }, - //line sql.y: 2036 + //line sql.y: 2152 `ALTER PROCEDURE`: { ShortDescription: `change the definition of a procedure`, - //line sql.y: 2037 + //line sql.y: 2153 Category: hDDL, - //line sql.y: 2038 + //line sql.y: 2154 Text: ` ALTER PROCEDURE name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] RENAME TO new_name @@ -194,16 +200,16 @@ ALTER PROCEDURE name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] SET SCHEMA new_schema `, - //line sql.y: 2046 + //line sql.y: 2162 SeeAlso: `WEBDOCS/alter-procedure.html `, }, - //line sql.y: 2240 + //line sql.y: 2356 `ALTER RANGE`: { ShortDescription: `change the parameters of a range`, - //line sql.y: 2241 + //line sql.y: 2357 Category: hDDL, - //line sql.y: 2242 + //line sql.y: 2358 Text: ` ALTER RANGE @@ -221,16 +227,16 @@ Zone configurations: { TO | = } `, - //line sql.y: 2258 + //line sql.y: 2374 SeeAlso: `ALTER TABLE `, }, - //line sql.y: 2264 + //line sql.y: 2380 `ALTER INDEX`: { ShortDescription: `change the definition of an index`, - //line sql.y: 2265 + //line sql.y: 2381 Category: hDDL, - //line sql.y: 2266 + //line sql.y: 2382 Text: ` ALTER INDEX [IF EXISTS] @@ -250,16 +256,16 @@ Zone configurations: { TO | = } `, - //line sql.y: 2284 + //line sql.y: 2400 SeeAlso: `WEBDOCS/alter-index.html `, }, - //line sql.y: 2986 + //line sql.y: 3187 `ALTER TYPE`: { ShortDescription: `change the definition of a type.`, - //line sql.y: 2987 + //line sql.y: 3188 Category: hDDL, - //line sql.y: 2988 + //line sql.y: 3189 Text: `ALTER TYPE Commands: @@ -277,26 +283,26 @@ Attribute action: ALTER ATTRIBUTE [ SET DATA ] TYPE [ COLLATE ] [ CASCADE | RESTRICT ] `, - //line sql.y: 3004 + //line sql.y: 3205 SeeAlso: `WEBDOCS/alter-type.html `, }, - //line sql.y: 3153 + //line sql.y: 3354 `REFRESH`: { ShortDescription: `recalculate a materialized view`, - //line sql.y: 3154 + //line sql.y: 3355 Category: hMisc, - //line sql.y: 3155 + //line sql.y: 3356 Text: ` -REFRESH MATERIALIZED VIEW [CONCURRENTLY] view_name [WITH [NO] DATA] +REFRESH MATERIALIZED VIEW [CONCURRENTLY] view_name [AS OF SYSTEM TIME >] [WITH [NO] DATA] `, }, - //line sql.y: 3182 + //line sql.y: 3384 `BACKUP`: { ShortDescription: `back up data to external storage`, - //line sql.y: 3183 + //line sql.y: 3385 Category: hCCL, - //line sql.y: 3184 + //line sql.y: 3386 Text: ` Create a full backup @@ -333,16 +339,16 @@ Options: include_all_virtual_clusters: enable backups of all virtual clusters during a cluster backup `, - //line sql.y: 3219 + //line sql.y: 3421 SeeAlso: `RESTORE, WEBDOCS/backup.html `, }, - //line sql.y: 3365 + //line sql.y: 3559 `CREATE SCHEDULE FOR BACKUP`: { ShortDescription: `backup data periodically`, - //line sql.y: 3366 + //line sql.y: 3560 Category: hCCL, - //line sql.y: 3367 + //line sql.y: 3561 Text: ` CREATE SCHEDULE [IF NOT EXISTS] [] @@ -414,16 +420,16 @@ FULL BACKUP : objects. `, - //line sql.y: 3437 + //line sql.y: 3631 SeeAlso: `BACKUP `, }, - //line sql.y: 3455 + //line sql.y: 3649 `ALTER BACKUP SCHEDULE`: { ShortDescription: `alter an existing backup schedule`, - //line sql.y: 3456 + //line sql.y: 3650 Category: hCCL, - //line sql.y: 3457 + //line sql.y: 3651 Text: ` ALTER BACKUP SCHEDULE [, ...] @@ -437,16 +443,16 @@ Commands: See CREATE SCHEDULE FOR BACKUP for detailed option descriptions. `, - //line sql.y: 3469 + //line sql.y: 3663 SeeAlso: `CREATE SCHEDULE FOR BACKUP `, }, - //line sql.y: 3609 + //line sql.y: 3811 `CREATE EXTERNAL CONNECTION`: { ShortDescription: `create a new external connection`, - //line sql.y: 3610 + //line sql.y: 3812 Category: hMisc, - //line sql.y: 3611 + //line sql.y: 3813 Text: ` CREATE EXTERNAL CONNECTION [IF NOT EXISTS] AS @@ -457,12 +463,25 @@ Endpoint: Endpoint of the resource that the external connection represents. `, }, - //line sql.y: 3629 + //line sql.y: 3831 + `CHECK EXTERNAL CONNECTION`: { + ShortDescription: `check the status of an external connection`, + //line sql.y: 3832 + Category: hMisc, + //line sql.y: 3833 + Text: ` +CREATE EXTERNAL CONNECTION [WITH ] + +Uri: + Uri for the external connection. +`, + }, + //line sql.y: 3889 `DROP EXTERNAL CONNECTION`: { ShortDescription: `drop an existing external connection`, - //line sql.y: 3630 + //line sql.y: 3890 Category: hMisc, - //line sql.y: 3631 + //line sql.y: 3891 Text: ` DROP EXTERNAL CONNECTION @@ -470,12 +489,12 @@ Name: Unique name for this external connection. `, }, - //line sql.y: 3645 + //line sql.y: 3905 `RESTORE`: { ShortDescription: `restore data from external storage`, - //line sql.y: 3646 + //line sql.y: 3906 Category: hCCL, - //line sql.y: 3647 + //line sql.y: 3907 Text: ` RESTORE FROM [ AS OF SYSTEM TIME ] @@ -503,20 +522,19 @@ Options: kms="[kms_provider]://[kms_host]/[master_key_identifier]?[parameters]" : decrypt backups using KMS detached: execute restore job asynchronously, without waiting for its completion skip_localities_check: ignore difference of zone configuration between restore cluster and backup cluster - debug_pause_on: describes the events that the job should pause itself on for debugging purposes. new_db_name: renames the restored database. only applies to database restores include_all_virtual_clusters: enable backups of all virtual clusters during a cluster backup `, - //line sql.y: 3677 + //line sql.y: 3936 SeeAlso: `BACKUP, WEBDOCS/restore.html `, }, - //line sql.y: 3905 + //line sql.y: 4134 `IMPORT`: { ShortDescription: `load data from file in a distributed manner`, - //line sql.y: 3906 + //line sql.y: 4135 Category: hCCL, - //line sql.y: 3907 + //line sql.y: 4136 Text: ` -- Import both schema and table data: IMPORT [ TABLE FROM ] @@ -536,16 +554,16 @@ Use CREATE TABLE followed by IMPORT INTO to create and import into a table from external files that only have table data. `, - //line sql.y: 3925 + //line sql.y: 4154 SeeAlso: `CREATE TABLE, WEBDOCS/import-into.html `, }, - //line sql.y: 3959 + //line sql.y: 4188 `EXPORT`: { ShortDescription: `export data to file in a distributed manner`, - //line sql.y: 3960 + //line sql.y: 4189 Category: hCCL, - //line sql.y: 3961 + //line sql.y: 4190 Text: ` EXPORT INTO [WITH