feat: migrate ClickHouse adapter to utopia-php/query 0.3.x builder#4
feat: migrate ClickHouse adapter to utopia-php/query 0.3.x builder#4lohanidamodar wants to merge 1 commit into
Conversation
Greptile SummaryThis PR migrates
Confidence Score: 4/5Safe to merge once the two open interval-related threads from the prior review round are resolved or explicitly deferred with a tracking issue. The builder migration is mechanically thorough and all call sites correctly call applyFilters after parseQueries. The two issues from earlier rounds — getTimeSeries rejecting intervals that find() accepts, and getTimeSeriesFromTable using a narrower function map than findAggregatedFromTable — remain open with no fix yet landed and affect callers using sub-hourly intervals. src/Usage/Adapter/ClickHouse.php — the INTERVAL_FUNCTIONS constant and getTimeSeriesFromTable carry the open interval-consistency issues from the prior review round. Important Files Changed
Reviews (6): Last reviewed commit: "feat!: migrate ClickHouse adapter to uto..." | Re-trigger Greptile |
| @@ -172,49 +166,24 @@ public function setTimeout(int $milliseconds): self | |||
| return $this; | |||
| } | |||
|
|
|||
| /** | |||
| * Enable or disable query logging for debugging. | |||
| * | |||
| * @param bool $enable Whether to enable query logging | |||
| * @return self | |||
| */ | |||
| public function enableQueryLogging(bool $enable = true): self | |||
| { | |||
There was a problem hiding this comment.
Let's keep the docs on public methods
There was a problem hiding this comment.
Restored docblocks on the public setter / lifecycle methods that lost them during the migration rewrite (__construct, setTimeout, enableQueryLogging, setCompression, setKeepAlive, setMaxRetries, setRetryDelay, setAsyncInserts, clearQueryLog, getName, healthCheck, setNamespace, setDatabase, setSecure, plus the namespace/tenant/sharedTables getters). Done in 0e0bbd6.
| 'integer' => $table->addColumn($id, ColumnType::BigInteger), | ||
| 'float' => $table->addColumn($id, ColumnType::Float), | ||
| 'boolean' => $table->addColumn($id, ColumnType::Boolean), | ||
| 'datetime' => $table->datetime($id, 3), |
There was a problem hiding this comment.
There should be shorthand methods we can use for integer, float and boolean too
There was a problem hiding this comment.
Swapped the addColumn(..., ColumnType::BigInteger|Float|Boolean) calls in the match block to the dedicated bigInteger() / float() / boolean() shorthand, plus the value BigInteger column in createDailyTable(). ColumnType import is no longer needed. SQL snapshot tests still green. Done in c2a261e.
Bump utopia-php/query from 0.1.* to 0.3.* and compile the ClickHouse adapter's SQL through the shared builder and schema layer instead of hand-assembled strings: - Reads (find, count, sum, totals, time series, daily, hybrid daily+raw union) build through the ClickHouse query builder with typed named bindings; every schema column is pinned to its ClickHouse parameter type so placeholder types never fall back to PHP value inference. - CREATE TABLE for the events/gauges/daily tables and the daily materialized view go through the schema layer. Column shapes the typed API cannot express (DateTime64 timezone argument, LowCardinality(Nullable(...)), hyphenated skip-index names) are emitted as raw definitions so deployed DDL is byte-for-byte unchanged. Projections, ALTER-based dim backfills and the MV body stay raw SQL, which the schema layer cannot express yet. - INSERT envelopes compile via insertFormat(); the JSONEachRow body assembly and transport are unchanged. - Query 0.3 API: getMethod() returns the Method enum, so all string TYPE_* comparisons are gone. UsageQuery keeps its groupByInterval() and groupBy() factories, now mapped to Method::GroupByTimeBucket and Method::GroupBy; groupBy() also accepts an array of columns to stay signature-compatible with the base class. - contains()/containsAny()/notContains() filters are rewritten to IN / NOT IN before reaching the builder to keep set-membership semantics (the builder compiles Contains as substring LIKE).
4530574 to
8fc13b3
Compare
Summary
Migrates the ClickHouse adapter to
utopia-php/query0.3.x (stable pin0.3.*, currently resolving to the tagged0.3.2release — no dev-branch pins). Every table CREATE, materialized view, INSERT envelope, SELECT and DELETE now compiles throughSchema\ClickHouse/Builder\ClickHouse; the adapter keeps only its HTTP transport, routing logic, and the few DDL shapes the library cannot express yet.Rebased on current
main, so the migration now covers everything that landed since the PR was opened: per-call tenant scoping, the daily-MV routing planner (raw/daily/hybrid), per-dim projections, dim-column backfills, theresourceTyperename, theipdimension, and the PSR-18 client transport.What changed
Schema (DDL via
Schema\ClickHouse)createTable()emits the events/gauges tables throughTable\ClickHouse: typed columns withcodec(),Engine::MergeTree,partitionBy,orderBy,settings.createDailyTable()usesEngine::SummingMergeTree;createDailyMaterializedView()goes throughSchema\ClickHouse::createMaterializedView(the MV body remains a hand SELECT — subquery-aggregation MV bodies do not round-trip through the builder yet).rawColumn()so the deployed DDL stays byte-for-byte identical:DateTime64(3, 'UTC')(timezone argument),LowCardinality(Nullable(String))(the typed API emits the invalidNullable(LowCardinality(...))nesting), and the hyphenated skip-index names (index-path), which the typed index API rejects.ADD PROJECTION),MODIFY SETTING, and theADD COLUMN IF NOT EXISTSdim backfills stay raw SQL — no schema-layer support yet.Reads (SELECT via
Builder\ClickHouse)useNamedBindings()+withParamTypes(); all schema columns are pinned to their ClickHouse parameter types (DateTime64(3, 'UTC'),Int64,String) so placeholders never fall back to PHP value inference.find/findFromTable,findAggregatedFromTable(interval buckets + dim group-bys),count(including the boundedLIMIT maxsubquery),sumand the routed daily/hybrid paths,findDaily,sumDaily,sumDailyBatch,getTotal*,getTimeSeries.SUM(...) FROM (... UNION ALL ...), prefixing one side's named bindings to avoid placeholder collisions.whereRawfragment with its own named bindings (upstream builder helper deferred).contains()/containsAny()/notContains()filters are rewritten toIN/NOT INbefore reaching the builder to keep set-membership semantics (the builder compilesContainsas substringLIKE).Writes
addBatch()compiles theINSERT INTO t (...) FORMAT JSONEachRowenvelope viainsertFormat(); JSONEachRow body assembly and the non-retrying POST transport are unchanged.Deletes
purge()/purgeDaily()emit lightweightDELETE FROMthrough the builder.Query 0.3 API surface
Query::getMethod()returns theMethodenum, so all stringTYPE_*comparisons are gone (ClickHouse and Database adapters).UsageQuery::TYPE_GROUP_BY_INTERVAL/TYPE_GROUP_BYstring constants are removed.UsageQuery::groupByInterval()andUsageQuery::groupBy()remain and now map toMethod::GroupByTimeBucket/Method::GroupBy;groupBy()also accepts an array of columns to stay signature-compatible with the 0.3 base class.Test plan
composer lintcleancomposer check(PHPStan level max) cleanSHOW CREATE TABLEschema assertions (codecs, LowCardinality,DateTime64(3, 'UTC'),index-*skip indexes), routing/dim-routing/projection tests, cursor pagination, and purge propagationStill deferred upstream (follow-up PRs)
whereRaw)LowCardinality(Nullable(...))column type and timezone argument forDateTime64MODIFY SETTING/ADD COLUMN IF NOT EXISTSin the schema layer