Summary
The ttl(...) hint behaves differently depending on whether it is placed on a CREATE TABLE definition or on an IMPORT statement that imports that table. On CREATE TABLE it works; on IMPORT it is silently ignored — no error, no warning, no effect on the compiled plan. This makes it easy to write a script that looks correct but produces no retention.
Observed with datasqrl/cmd:0.10.5.
Expected
One of the following, consistently:
- The
ttl hint on IMPORT is honored (propagated to the imported table's engine config), or
- The compiler emits a warning/error that
ttl (and other definition-level hints) are not valid on an IMPORT statement.
Today it does neither — the hint is accepted by the parser and then dropped.
Actual
ttl on IMPORT produces no retention.ms in kafka.json (topic config stays {}), and ttl: 0 everywhere in postgres.json / flink-compiled-plan.json. Moving the identical hint onto the CREATE TABLE definition produces the expected retention.ms.
Trivial reproduction
mytable/MyEvents.sqrl — the table definition:
/*+ no_query, engine(kafka) */
CREATE TABLE MyEvents (
`id` STRING NOT NULL METADATA FROM 'uuid',
`payload` STRING,
`timestamp` TIMESTAMP_LTZ(3) NOT NULL METADATA FROM 'timestamp',
WATERMARK FOR `timestamp` AS `timestamp` - INTERVAL '0.001' SECOND
);
main.sqrl — case A, hint on the IMPORT (ignored):
/*+ no_query, ttl(14 days) */
IMPORT mytable.MyEvents.*;
Compile → kafka.json:
{ "topicName": "MyEvents", "config": {} } // <-- ttl dropped, no retention.ms
main.sqrl — case B, hint moved onto the CREATE TABLE (works):
/*+ no_query, engine(kafka), ttl(14 days) */
CREATE TABLE MyEvents ( ... );
-- main.sqrl
IMPORT mytable.MyEvents.*;
Compile → kafka.json:
{ "topicName": "MyEvents", "config": { "retention.ms": "1209600000" } } // <-- 14 days
Impact
A user reasonably expects to set per-import retention from the consuming script (the table definition may be a shared/imported package they don't own). Because the hint is silently dropped, topics silently fall back to whatever engine-level default retention is configured (e.g. a global kafka.retention), which can be effectively "keep forever" — a real cost/correctness footgun with no diagnostic.
Related observation (separate, lower priority)
While investigating, no_query and insert(batch) placed on an IMPORT of a kafka source table also had no effect (stripping them yielded a byte-identical plan). If definition-level hints are generally not meant to apply on IMPORT, a single validation pass that rejects/warns on unsupported hints-on-import would cover all of these cases.
Summary
The
ttl(...)hint behaves differently depending on whether it is placed on aCREATE TABLEdefinition or on anIMPORTstatement that imports that table. OnCREATE TABLEit works; onIMPORTit is silently ignored — no error, no warning, no effect on the compiled plan. This makes it easy to write a script that looks correct but produces no retention.Observed with
datasqrl/cmd:0.10.5.Expected
One of the following, consistently:
ttlhint onIMPORTis honored (propagated to the imported table's engine config), orttl(and other definition-level hints) are not valid on anIMPORTstatement.Today it does neither — the hint is accepted by the parser and then dropped.
Actual
ttlonIMPORTproduces noretention.msinkafka.json(topic config stays{}), andttl: 0everywhere inpostgres.json/flink-compiled-plan.json. Moving the identical hint onto theCREATE TABLEdefinition produces the expectedretention.ms.Trivial reproduction
mytable/MyEvents.sqrl— the table definition:main.sqrl— case A, hint on the IMPORT (ignored):Compile →
kafka.json:{ "topicName": "MyEvents", "config": {} } // <-- ttl dropped, no retention.msmain.sqrl— case B, hint moved onto the CREATE TABLE (works):Compile →
kafka.json:{ "topicName": "MyEvents", "config": { "retention.ms": "1209600000" } } // <-- 14 daysImpact
A user reasonably expects to set per-import retention from the consuming script (the table definition may be a shared/imported package they don't own). Because the hint is silently dropped, topics silently fall back to whatever engine-level default retention is configured (e.g. a global
kafka.retention), which can be effectively "keep forever" — a real cost/correctness footgun with no diagnostic.Related observation (separate, lower priority)
While investigating,
no_queryandinsert(batch)placed on anIMPORTof a kafka source table also had no effect (stripping them yielded a byte-identical plan). If definition-level hints are generally not meant to apply onIMPORT, a single validation pass that rejects/warns on unsupported hints-on-import would cover all of these cases.