CREATE EXTERNAL TABLE … ENGINE = SQL|ESQL¶
Map a MatrixOne external table to a foreign SQL database (
ENGINE = SQL) or an Elasticsearch ES|QL source (ENGINE = ESQL) whose rows are produced by a query text supplied at scan time. The table is read-only, and the source query is carried by the hidden__mo_querycolumn or thequerytable option.
Description¶
CREATE EXTERNAL TABLE ... ENGINE = SQL and CREATE EXTERNAL TABLE ... ENGINE = ESQL map a MatrixOne external table to a foreign data source that answers a query at scan time. ENGINE = SQL speaks to a SQL database through a {"driver": "...", "dsn": "..."} config (MySQL and PostgreSQL drivers are supported). ENGINE = ESQL speaks to an Elasticsearch cluster through an ES|QL config.
The table is read-only: SELECT is supported, and writes are rejected. CREATE EXTERNAL TABLE validates the engine options and the config JSON shape but does not dial the source; the connection is opened lazily on the first scan.
Syntax¶
CREATE EXTERNAL TABLE [IF NOT EXISTS] [db.]table_name (
column1 type1,
column2 type2,
...
) ENGINE = {SQL | ESQL} [WITH ("option" = 'value' [, "option" = 'value'] ...)];
Arguments¶
Option |
Engine |
Required |
Description |
|---|---|---|---|
|
SQL, ESQL |
No |
Connection JSON. For SQL: `{“driver”:”mysql |
|
SQL, ESQL |
No |
Default query text used when a |
|
SQL |
No |
|
Usage Notes¶
Read-only: writes into an
ENGINE = SQL|ESQLexternal table are rejected.INSERT ... SELECT FROMsuch a table is the intended ETL path.Secret redaction:
SHOW CREATE TABLEalways rendersconfigas'config' = '<redacted>', because the JSON carries credentials. Recreate tables withconfigre-supplied, or use the session variable instead of an inline config.Connection sharing: an external table and a
sql_tvf/esql_tvfwith the same config in the same session share one cached connection.No DDL-time connectivity check:
CREATE EXTERNAL TABLEvalidates only the option set and the config JSON shape. A bad driver or a wrong-typed option is rejected atCREATEtime.
Examples¶
The following example creates a read-only SQL external table, inspects its redacted DDL, and demonstrates that unknown options are rejected at CREATE time. It needs no live source connection:
DROP DATABASE IF EXISTS foreign_ext_demo;
CREATE DATABASE foreign_ext_demo;
USE foreign_ext_demo;
CREATE EXTERNAL TABLE orders (
id BIGINT,
name VARCHAR(64),
amount DECIMAL(12,2),
created DATETIME
) ENGINE = SQL WITH ('config' = '{"driver":"mysql","dsn":"dump:111@tcp(127.0.0.1:6001)/foreign_ext_demo"}');
SHOW CREATE TABLE orders;
-- Expected-Success: false
CREATE EXTERNAL TABLE badopt (id INT) ENGINE = SQL WITH ('compress' = 'true');
DROP DATABASE foreign_ext_demo;
The next examples read from the table and require a reachable source, so they are syntax templates rather than a paste-and-run script:
-- the query text is supplied on the hidden column
SELECT id, name, amount FROM orders
WHERE __mo_query = 'select id, name, amount, created from src order by id';
-- a default query from the 'query' table option
SELECT id, name FROM with_default;
-- IN produces one scan per query text; the projection shows which query produced each row
SELECT id, __mo_query FROM orders
WHERE __mo_query IN (
'select id, name, amount, created from src where id = 1',
'select id, name, amount, created from src where id = 3')
ORDER BY id;
-- pushdown = 'true' lets the source apply a predicate MatrixOne can render
SELECT id FROM pushed WHERE __mo_query = 'select id, name, amount, created from src' AND id > 2;