Published

⭐⭐⭐ F·1 · CONSULTAR SIN COPIAR — la federación, por la cara

Connect any source, model it as an ontology, transform it, and operationalize it, analytics, automation and machine learning, under one governed, self-hostable roof. --- Most teams stitch the...

⭐⭐⭐ F·1 · CONSULTAR SIN COPIAR — la federación, por la cara

Estado: 🏁 f1-gate-federacion.ts VERDE en vivo contra un PostgreSQL real.
Regla de la casa: cada hecho lleva el comando que lo demuestra.

SELECT * FROM pg_ventas.public.ventas WHERE anio = 2025

SELECT v.cliente, c.segmento
  FROM pg_ventas.public.ventas v
  JOIN main.default.clientes c ON c.id = v.cliente_id

1 · Por qué esto es federación GOBERNADA y un FOREIGN CATALOG no

Un catálogo federado de verdad es un catálogo que el motor ve directamente. Spark habla con la cara (spark.sql.catalog.carbon.uri), así que un catálogo así quedaría fuera del punto de aplicación: la federación no se debilitaría, desaparecería.

Una vista TEMPORAL no es un catálogo: la crea la puerta después de autorizar, vive en la sesión del inquilino y muere con ella. No queda nada persistente con lo que esquivarnos — y aun así el motor lee del origen sin intermediarios.

⭐⭐ Y la primitiva ya existía: la construyó C·5 para copiar. Resultó ser la misma pieza para consultar, para el metadata-only (LIKE) y para las vistas — en los cuatro casos lo que hace falta es que el motor pueda leer del origen bajo una autorización nuestra; lo único que cambia es qué se hace después. ⇒ vive en lib/governance/jdbc-vista.ts, una sola vez: dos copias serían dos sitios donde olvidar connectionProvider o fetchsize.


2 · ⛔⛔ El rewriting, y la cicatriz que hereda

M2c ya pagó esto: sustituir un nombre de tabla reescribía también dentro de los literalesSELECT 'ventas' FROM ventas devolvía la coordenada física en el literal. No fallaba: MENTÍA, y se descubrió en producción.

⇒ Aquí las referencias se localizan sobre el texto ENMASCARADO (maskNoise neutraliza literales y comentarios conservando las posiciones) y se reemplazan por RANGO, de atrás hacia delante. No hay ninguna búsqueda de texto, que es exactamente lo que hace imposible aquel fallo.

⭐ Los tests que valen son los negativos (refs-cualificadas.test.ts, 13): un literal, un comentario, una columna cualificada y una comilla escapada no se tocan.

⚠️ Y no sirve scanTableRefs: colapsa al último segmento (pg.public.ventasventas) porque corre después de rewriteDottedFromRefs. La federación necesita justo lo contrario — el PRIMER segmento, que es el que puede ser una conexión.


3 · La desambiguación, por TERCERA vez

SELECT * FROM main.default.ventas es una consulta legítima del warehouse con la misma forma exacta. ⇒ se mira si el primer segmento es una conexión declarada; si no lo es, noEsFederado y el flujo sigue.

⭐ Es la tercera vez (C·4, C·5, F·1) y ya no es casualidad: en una puerta que habla el mismo dialecto que el motor, la desambiguación nunca puede ser sintáctica.


4 · ⭐⭐⭐ Lo que el gate mide, y cuál decide

sondaresultado
sin CONNECTION_USE no lee, y el motivo lo da el plano de permisos
una consulta del warehouse no se secuestra
⭐ una coordenada dentro de un literal no la convierte en federada
lee del origen✅ 5 filas
⭐⭐⭐ ZERO-COPY · no nació ni un dataset✅ 152 → 152
el WHERE se resuelve en el ORIGEN✅ 84 de 250
⭐⭐ JOIN mixto: origen externo × Warehouse
el secreto no aparece ni en el resultado ni en el ledger

⭐⭐⭐ La que decide es la ④. Que devuelva filas sólo prueba que hay un tubo; si tras un SELECT federado apareciera un dataset, esto sería una copia con otro nombre — y peor, una que el usuario no pidió.

⚠️ Y la ⑥ es la que separa «puedo leer de fuera» de «puedo cruzar lo de fuera con lo mío», que es el caso por el que alguien paga.


5 · ⭐⭐ Lo que hubo que abrir en la puerta, y por qué no abre un agujero

Una consulta puramente federada no tiene ninguna tabla del Warehouse, y la puerta la rechazaba con «No se identificó ninguna tabla del Warehouse». Eso dejaba la federación a medias de la peor manera: el JOIN mixto funcionaba (hay una tabla que identificar) y el SELECT a secas no.

soloFederado, hermano de soloMetadata — que ya admitía las consultas de information_schema por el mismo motivo estructural.

Y no abre un agujero de tenencia, que es lo que esa guarda protege: el token del motor sigue siendo el del principal, las vistas viven en la sesión de su inquilino, y la conexión de la que salen ya pasó por CONNECTION_USE. Lo que la guarda impide es que el motor conteste con las tablas de todos los inquilinos; aquí no hay ninguna tabla del motor que contestar.


6 · ⏭️ Lo que NO está

  • Escribir en el origen. Sólo se federan lecturas (SELECT/WITH), y no por descuido: escribir en el sistema de otro es una decisión que no está tomada.
  • Orígenes que no sean PostgreSQL. El mecanismo es el mismo; cada tipo es un adaptador que hay que escribir, y la lista se queda corta a propósito.
  • Una VISTA persistente sobre el origen. Hoy la relación vive en la sesión. Una vista guardada exigiría decidir cuándo se re-autoriza — y ésa es la pregunta interesante.