```sql
CREATE TABLE test_tbl
(   `ip` String, `ipv6` IPv6 MATERIALIZED toIPv6(ip) )
ENGINE = Memory;

insert into test_tbl(ip) values ( 'fe80::9801:43ff:fe1f:7690'), ('1.1.1.1'), (''), ('::ffff:1.1.1.1' );

 DB::Exception: Invalid IPv6 value: while executing 'FUNCTION _CAST(toIPv6(ip) :: 2, 'IPv6' :: 1)


set cast_ipv4_ipv6_default_on_conversion_error=1;
insert into test_tbl(ip) values ( 'fe80::9801:43ff:fe1f:7690'), ('1.1.1.1'), (''), ('::ffff:1.1.1.1' );
 
 DB::Exception: Invalid IPv6 value: while executing 'FUNCTION _CAST(toIPv6(ip)
```

`toIPv6OrDefault` does not help in this case.

```sql
CREATE TABLE test_tbl
(   `ip` String, `ipv6` IPv6 MATERIALIZED toIPv6OrDefault(ip) )
ENGINE = Memory;

insert into test_tbl(ip) values ( 'fe80::9801:43ff:fe1f:7690'), ('1.1.1.1'), (''), ('::ffff:1.1.1.1' );
  DB::Exception: Invalid IPv6 value: while executing 'FUNCTION _CAST(toIPv6OrD

insert into test_tbl(ip) values ( 'fe80::9801:43ff:fe1f:7690'), ('1.1.1.1'), (''), ('::ffff:1.1.1.1' ), ('garbudge');
  DB::Exception: Invalid IPv6 value: while executing 'FUNCTION
```

WA:

```sql
CREATE TABLE test_tbl
(   `ip` String, `ipv6` IPv6 MATERIALIZED if(ip='', '::', ip) )
ENGINE = Memory;

insert into test_tbl(ip) values ( 'fe80::9801:43ff:fe1f:7690'), ('1.1.1.1'), (''), ('::ffff:1.1.1.1' );

select ip, ipv6 from test_tbl;
┌─ip────────────────────────┬─ipv6──────────────────────┐
│ fe80::9801:43ff:fe1f:7690 │ fe80::9801:43ff:fe1f:7690 │
│ 1.1.1.1                   │ ::ffff:1.1.1.1            │
│                           │ ::                        │
│ ::ffff:1.1.1.1            │ ::ffff:1.1.1.1            │
└───────────────────────────┴───────────────────────────┘
```
M(Int64, max_partitions_to_read, -1, "Limit the max number of partitions that can be accessed in one query. <= 0 means unlimited.", 0) \
    M(Bool, check_query_single_value_result, true, "Return check query result as single 1/0 value", 0) \
    M(Bool, allow_drop_detached, false, "Allow ALTER TABLE ... DROP DETACHED PART[ITION] ... queries", 0) \
    \
    M(UInt64, postgresql_connection_pool_size, 16, "Connection pool size for PostgreSQL table engine and database engine.", 0) \
    M(UInt64, postgresql_connection_pool_wait_timeout, 5000, "Connection pool push/pop timeout on empty pool for PostgreSQL table engine and database engine. By default it will block on empty pool.", 0) \
    M(UInt64, glob_expansion_max_elements, 1000, "Maximum number of allowed addresses (For external storages, table functions, etc).", 0) \
    M(UInt64, odbc_bridge_connection_pool_size, 16, "Connection pool size for each connection settings string in ODBC bridge.", 0) \
    \
    M(Seconds, distributed_replica_error_half_life, DBMS_CONNECTION_POOL_WITH_FAILOVER_DEFAULT_DECREASE_ERROR_PERIOD, "Time period reduces replica error counter by 2 times.", 0) \
    M(UInt64, distributed_replica_error_cap, DBMS_CONNECTION_POOL_WITH_FAILOVER_MAX_ERROR_COUNT, "Max number of errors per replica, prevents piling up an incredible amount of errors if replica was offline for some time and allows it to be reconsidered in a shorter amount of time.", 0) \
    M(UInt64, distributed_replica_max_ignored_errors, 0, "Number of errors that will be ignored while choosing replicas", 0) \
    \
    M(Bool, allow_experimental_live_view, false, "Enable LIVE VIEW. Not mature enough.", 0) \
    M(Seconds, live_view_heartbeat_interval, 15, "The heartbeat interval in seconds to indicate live query is alive.", 0) \
    M(UInt64, max_live_view_insert_blocks_before_refresh, 64, "Limit maximum number of inserted blocks after which mergeable blocks are dropped and query is re-executed.", 0) \
    M(Bool, allow_experimental_window_view, false, "Enable WINDOW VIEW. Not mature enough.", 0) \
    M(Seconds, window_view_clean_interval, DEFAULT_WINDOW_VIEW_CLEAN_INTERVAL_SEC, "The clean interval of window view in seconds to free outdated data.", 0) \
    M(Seconds, window_view_heartbeat_interval, DEFAULT_WINDOW_VIEW_HEARTBEAT_INTERVAL_SEC, "The heartbeat interval in seconds to indicate watch query is alive.", 0) \
    M(UInt64, min_free_disk_space_for_temporary_data, 0, "The minimum disk space to keep while writing temporary data used in external sorting and aggregation.", 0) \
    \
    M(DefaultDatabaseEngine, default_database_engine, DefaultDatabaseEngine::Atomic, "Default database engine.", 0) \
    M(DefaultTableEngine, default_table_engine, DefaultTableEngine::None, "Default table engine used when ENGINE is not set in CREATE statement.",0) \
    M(Bool, show_table_uuid_in_table_create_query_if_not_nil, false, "For tables in databases with Engine=Atomic show UUID of the table in its CREATE query.", 0) \
    M(Bool, database_atomic_wait_for_drop_and_detach_synchronously, false, "When executing DROP or DETACH TABLE in Atomic database, wait for table data to be finally dropped or detached.", 0) \
    M(Bool, enable_scalar_subquery_optimization, true, "If it is set to true, prevent scalar subqueries from (de)serializing large scalar values and possibly avoid running the same subquery more than once.", 0) \
    M(Bool, optimize_trivial_count_query, true, "Process trivial 'SELECT count() FROM table' query from metadata.", 0) \
    M(Bool, optimize_respect_aliases, true, "If it is set to true, it will respect aliases in WHERE/GROUP BY/ORDER BY, that will help with partition pruning/secondary indexes/optimize_aggregation_in_order/optimize_read_in_order/optimize_trivial_count", 0) \
    M(UInt64, mutations_sync, 0, "Wait for synchronous execution of ALTER TABLE UPDATE/DELETE queries (mutations). 0 - execute asynchronously. 1 - wait current server. 2 - wait all replicas if they exist.", 0) \
    M(Bool, optimize_move_functions_out_of_any, false, "Move functions out of aggregate functions 'any', 'anyLast'.", 0) \