switch (field->real_type())
{ case MYSQL_TYPE_TINY: return is_unsigned ? duckdb::LogicalType::UTINYINT
: duckdb::LogicalType::TINYINT; case MYSQL_TYPE_SHORT: return is_unsigned ? duckdb::LogicalType::USMALLINT
: duckdb::LogicalType::SMALLINT; case MYSQL_TYPE_INT24: case MYSQL_TYPE_LONG: return is_unsigned ? duckdb::LogicalType::UINTEGER
: duckdb::LogicalType::INTEGER; case MYSQL_TYPE_LONGLONG: return is_unsigned ? duckdb::LogicalType::UBIGINT
: duckdb::LogicalType::BIGINT; case MYSQL_TYPE_FLOAT: return duckdb::LogicalType::FLOAT; case MYSQL_TYPE_DOUBLE: return duckdb::LogicalType::DOUBLE; case MYSQL_TYPE_DECIMAL: case MYSQL_TYPE_NEWDECIMAL: { auto *df= static_cast<const Field_new_decimal *>(field);
uint prec= df->precision > 38 ? 38 : df->precision; return duckdb::LogicalType::DECIMAL(prec, df->dec);
} case MYSQL_TYPE_DATE: case MYSQL_TYPE_NEWDATE: return duckdb::LogicalType::DATE; case MYSQL_TYPE_TIME: case MYSQL_TYPE_TIME2: return duckdb::LogicalType::TIME; case MYSQL_TYPE_DATETIME: case MYSQL_TYPE_DATETIME2: return duckdb::LogicalType::TIMESTAMP; case MYSQL_TYPE_TIMESTAMP: case MYSQL_TYPE_TIMESTAMP2: return duckdb::LogicalType::TIMESTAMP_TZ; case MYSQL_TYPE_YEAR: return duckdb::LogicalType::INTEGER; case MYSQL_TYPE_BIT: case MYSQL_TYPE_GEOMETRY: return duckdb::LogicalType::BLOB; case MYSQL_TYPE_BLOB: case MYSQL_TYPE_TINY_BLOB: case MYSQL_TYPE_MEDIUM_BLOB: case MYSQL_TYPE_LONG_BLOB: return field->has_charset() ? duckdb::LogicalType::VARCHAR
: duckdb::LogicalType::BLOB; case MYSQL_TYPE_STRING: case MYSQL_TYPE_VARCHAR: case MYSQL_TYPE_VAR_STRING: case MYSQL_TYPE_SET: case MYSQL_TYPE_ENUM: if (is_uuid_field(field)) return duckdb::LogicalType::UUID; return duckdb::LogicalType::VARCHAR; default: return duckdb::LogicalType::VARCHAR;
}
}
static duckdb::Value field_to_duckdb_value(Field *field)
{ if (field->is_null()) return duckdb::Value();
switch (field->real_type())
{ case MYSQL_TYPE_TINY: case MYSQL_TYPE_SHORT: case MYSQL_TYPE_INT24: case MYSQL_TYPE_LONG: case MYSQL_TYPE_LONGLONG: case MYSQL_TYPE_YEAR: { if (field->is_unsigned()) return duckdb::Value::UBIGINT(field->val_uint()); return duckdb::Value::BIGINT(field->val_int());
} case MYSQL_TYPE_FLOAT: { float v;
v= static_cast<float>(field->val_real()); return duckdb::Value::FLOAT(v);
} case MYSQL_TYPE_DOUBLE: return duckdb::Value::DOUBLE(field->val_real()); case MYSQL_TYPE_DECIMAL: case MYSQL_TYPE_NEWDECIMAL: {
String buf;
field->val_str(&buf); return duckdb::Value(std::string(buf.ptr(), buf.length()));
} case MYSQL_TYPE_DATE: case MYSQL_TYPE_NEWDATE: case MYSQL_TYPE_TIME: case MYSQL_TYPE_TIME2: case MYSQL_TYPE_DATETIME: case MYSQL_TYPE_DATETIME2: case MYSQL_TYPE_TIMESTAMP: case MYSQL_TYPE_TIMESTAMP2: {
String buf;
field->val_str(&buf); return duckdb::Value(std::string(buf.ptr(), buf.length()));
} case MYSQL_TYPE_BIT: case MYSQL_TYPE_GEOMETRY: {
String buf;
field->val_str(&buf); return duckdb::Value::BLOB(std::string(buf.ptr(), buf.length()));
} case MYSQL_TYPE_BLOB: case MYSQL_TYPE_TINY_BLOB: case MYSQL_TYPE_MEDIUM_BLOB: case MYSQL_TYPE_LONG_BLOB: {
String buf;
field->val_str(&buf); if (field->has_charset()) return duckdb::Value(std::string(buf.ptr(), buf.length())); return duckdb::Value::BLOB(std::string(buf.ptr(), buf.length()));
} default: {
String buf;
field->val_str(&buf); if (is_uuid_field(field)) return duckdb::Value::UUID(std::string(buf.ptr(), buf.length())); return duckdb::Value(std::string(buf.ptr(), buf.length()));
}
}
}
TABLE *tbl= find_external_table(key); if (!tbl) throw duckdb::BinderException("_mdb_scan: table '%s' not found in " "external table registry",
key.c_str());
for (Field **f= tbl->field; *f; f++)
{
names.push_back((*f)->field_name.str);
return_types.push_back(field_to_logical_type(*f));
}
/* ---- Lazy fiber initialization on first call ---- */ if (!state.scan_started)
{ const std::string &where_sql= state.where_sql; /* RYOW mode reads via the direct handler scan below (parent trx);
otherwise use a fiber running a synthetic SELECT for pushdown. */ if (!state.direct)
{
duckdb::vector<duckdb::LogicalType> col_types;
uint nfields= tbl->s->fields; for (auto col_idx : state.column_ids)
{ if (col_idx >= nfields)
col_types.push_back(duckdb::LogicalType::BIGINT); else
col_types.push_back(field_to_logical_type(tbl->field[col_idx]));
}
duckdb::CreateTableFunctionInfo info(std::move(mdb_scan)); auto &catalog= duckdb::Catalog::GetSystemCatalog(db); auto transaction= duckdb::CatalogTransaction::GetSystemTransaction(db);
catalog.CreateFunction(transaction, info);
/* RYOW variant: reads via the parent transaction's handler, so it cannot honorpushed-downfilters.Disablefilter_pushdownsoDuckDBkeepsthe
Filter operator above the scan and applies predicates itself. */
duckdb::TableFunction mdb_scan_direct( "_mdb_scan_direct", {duckdb::LogicalType::VARCHAR}, mdb_scan_function,
mdb_scan_bind, mdb_scan_init_global);
mdb_scan_direct.projection_pushdown= true;
mdb_scan_direct.filter_pushdown= false;
duckdb::CreateTableFunctionInfo info_direct(std::move(mdb_scan_direct));
catalog.CreateFunction(transaction, info_direct);
auto &config= duckdb::DBConfig::GetConfig(db);
config.replacement_scans.emplace_back(mariadb_replacement_scan);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.